Git使用指南

Git是最著名的版本控制软件,基于Git的Github更是无数程序员/宅男的圣地。对于初学编程的朋友,掌握Git的使用是有必要的。我最近在学习Python,顺便学习了Git的使用,本文目的是给自己作一个总结,如能帮助到别人,那更好了。

以下命令在PowerShell下使用,在一个文件夹下调用PowerShell的方法:按住Shift,并鼠标右键,将会出现打开PowerShell选项。

0. 创建文件夹

创建一个test文件夹,使用mdmkdir:

mkdir test

创建空文件

type nul>>test.txt

创建带内容的文件:

echo "你的内容">>test.txt

理解Git工作原理:

image-20200215202252569

参考:https://rogerdudler.github.io/git-guide/index.zh.html

1. 创建一个库

使用cd进入一个文件夹,比如进入test,cd test,之后建一个仓库:

git init

建立裸仓库:

git init --bare

🚨工作仓库与裸仓库区别:

  • 裸仓库不包含源文件(目录下不会显示),但仍然可以clone,类似于中心仓库。
  • 工作仓库包含源文件
  • 在其他地方,如Clone工作仓库后,将无法提交修改

2. 修改文件,并添加到缓存区(跟踪文件):

git add *

关于git add 命令

跟踪一个或多个文件:

git add <file_1> <file_2>

跟踪所有,但不包括删除的文件,并根据.gitignore做过滤

git add .

跟踪所有,但不包括删除的文件,并忽略.gitignore把任何文件都加入

git add *

跟踪所有更改,包括删除文件

git add -A

列出跟踪文件列表:

git ls-files

关于 .gitignore

在项目目录下创建 .gitignore 文件,可以设置不跟踪的文件或文件夹,格式如下

*.o # 不跟踪扩展名为 o 的文件
tmp/    # 不跟踪 tmp/ 目录下的文件

跟踪文件的其他操作:

# 查看状态
git status
# 查看提交记录
git log
# 删除文件跟踪状态
git rm file.txt

3. 提交修改到head

提交简短描述:

git commit -m "你的描述"
# 只改变的某些文件内容,可以用以下:
git commit -am "你的描述"
# 以上相当于
git add .
git commit -m "你的描述"
# 注意若添加了新文件,不能用-am

提交详细描述:

git commit

输入后会自动打开文本编辑器编辑内容。

4. 链接远端仓库

在Push之前,先确保链接远端仓库

Clone远端仓库

执行如下命令以创建一个本地仓库的克隆版本:

git clone /path/to/repository

如果是远端服务器上的仓库,命令会是这个样子:

git clone username@host:/path/to/repository
git clone https://path/to/repository

clone GitHub可使用HTTPS和SSH方式

https方式:

git clone https://github.com/path/to/repository

ssh方式:

git clone [email protected]:/path/to/repository

本地仓库链接到远端仓库

https方式:

git remote add origin https://github.com/path/to/repository

ssh方式:

git remote add origin [email protected]:path/to/repository

删除远端仓库链接

删除远程连接
git remote rm origin
添加远程连接
git remote add origin <url>

5.Push到远端仓库

git push -u origin master
或者
git push origin master

要确保能push到远端仓库比如GitHub,需要保证本地与GitHub有SSH Key对应。

添加SSH Key的方法:

https://help.github.com/cn/github/authenticating-to-github/connecting-to-github-with-ssh

生成新 SSH 密钥

  1. 打开 Git Bash。
  2. 粘贴下面的文本(替换为您的 GitHub 电子邮件地址)。

    $ ssh-keygen -t rsa -b 4096 -C "[email protected]"

这将创建以所提供的电子邮件地址为标签的新 SSH 密钥。

> Generating public/private rsa key pair.
  1. 提示您“Enter a file in which to save the key(输入要保存密钥的文件)”时,按 Enter 键。 这将接受默认文件位置。

    > Enter a file in which to save the key (/c/Users/you/.ssh/id_rsa):[Press enter]
  2. 在提示时输入安全密码。 更多信息请参阅“使用 SSH 密钥密码”

    > Enter passphrase (empty for no passphrase): [Type a passphrase]
    > Enter same passphrase again: [Type passphrase again]

将 SSH 密钥添加到 ssh-agent

将新 SSH 密钥添加到 ssh-agent 以管理密钥之前,应检查现有 SSH 密钥生成新 SSH 密钥

如果已安装 GitHub Desktop,可使用它克隆仓库,而无需处理 SSH 密钥。 它还附带 Git Bash 工具,这是在 Windows 上运行 git 命令的首选方法。

  1. 确保 ssh-agent 正在运行:

    • 如果您使用随 GitHub Desktop 一起安装的 Git Shell,则 ssh-agent 应该正在运行。
    • 如果您使用的是其他终端提示符,例如 Git for Windows,您可以根据“使用 SSH 密钥密码”中的“自动启动 ssh-agent”说明进行操作,或者手动启动它:

      # 在后台启动 ssh-agent
      $ eval $(ssh-agent -s)
      > Agent pid 59566
  2. 将 SSH 私钥添加到 ssh-agent。 如果您创建了不同名称的密钥,或者您要添加不同名称的现有密钥,请将命令中的 id_rsa 替换为您的私钥文件的名称。

    $ ssh-add ~/.ssh/id_rsa
  3. 将 SSH 密钥添加到 GitHub 帐户

git push 详解

git push的一般形式为 git push <远程主机名> <本地分支名> <远程分支名>

例如 git push origin master: refs/for/master

表示将本地的master分支推送到远程主机origin上的对应master分支, origin 是远程主机名,

第一个master是本地分支名,第二个master是远程分支名。

git push origin master

如果远程分支被省略,如上则表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果该远程分支不存在,则会被新建

git push origin: refs/for/master

如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支,等同于 git push origin –delete master

git push origin

如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支

git push

如果当前分支只有一个远程分支,那么主机名都可以省略,形如 git push,可以使用git branch -r ,查看远程的分支名

git push 的其他命令

git push -u origin master

如果当前分支与多个主机存在追踪关系,则可以使用 -u 参数指定一个默认主机,这样后面就可以不加任何参数使用git push,不带任何参数的git push,默认只推送当前分支,这叫做simple方式,还有一种matching方式,会推送所有有对应的远程分支的本地分支, Git 2.0之前默认使用matching,现在改为simple方式,如果想更改设置,可以使用git config命令。git config –global push.default matching OR git config –global push.default simple;可以使用git config -l 查看配置

git push –all origin

当遇到这种情况就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要 -all 选项

git push –force origin git push

的时候需要本地先git pull更新到跟服务器版本一致,如果本地版本库比远程服务器上的低,那么一般会提示你git pull更新,如果一定要提交,那么可以使用这个命令。

git push origin –tags

git push 的时候不会推送分支,如果一定要推送标签的话那么可以使用这个命令

关于 refs/for

refs/for 的意义在于我们提交代码到服务器之后是需要经过code review 之后才能进行merge的,而refs/heads 不需要

分支管理

查看本地分支

使用 git branch命令:

git branch

查看远程分支

git branch -r

查看所有分支

git branch -a

本地创建新的分支

git branch [branch name]

切换到新的分支

git checkout [branch name]

创建+切换分支

创建分支的同时切换到该分支上,命令如下:

git checkout -b [branch name]

git checkout -b [branch name] 的效果相当于以下两步操作:

git branch [branch name]
git checkout [branch name]

将新分支推送到GitHub

git push origin [branch name]

删除本地分支

git branch -d [branch name]

删除GitHub远程分支

git push origin :[branch name]

分支名前的冒号代表删除。

更新与合并分支

要更新你的本地仓库至最新改动,执行:

git pull

以在你的工作目录中 获取(fetch)合并(merge) 远端的改动。
要合并其他分支到你的当前分支(例如 master),执行:

git merge

其他补充

git diff 详解

diff里面a表示前面那个变量,b表示第二个变量

HEAD commit版本

Index staged版本

a、查看尚未暂存的文件更新了哪些部分,不加参数直接输入

git diff

此命令比较的是工作目录(Working tree)和暂存区域快照(index)之间的差异

也就是修改之后还没有暂存起来的变化内容。

b、查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异

git diff --cached
git diff --staged

显示的是下一次commit时会提交到HEAD的内容(不带-a情况下)

c、显示工作版本(Working tree)和HEAD的差别

git diff HEAD

d、直接将两个分支上最新的提交做diff

git diff topic master
或
git diff topic..master

e、输出自topic和master分别开发以来,master分支上的changed。

git diff topic...master
Changes that occurred on the master branch since when the topic
branch was started off it

f、查看简单的diff结果,可以加上–stat参数

git diff –stat

g、查看当前目录和另外一个分支的差别

git diff test

显示当前目录和另一个叫’test’分支的差别

git diff HEAD -- ./lib

显示当前目录下的lib目录和上次提交之间的差别(更准确的说是在当前分支下)

h、比较上次提交commit和上上次提交

git diff HEAD^ HEAD

i、比较两个历史版本之间的差异

git diff SHA1 SHA2

git stash详解_Java_stone_yw的博客-CSDN博客

git stash

应用场景:

  1. 当正在dev分支上开发某个项目,这时项目中出现一个bug,需要紧急修复,但是正在开发的内容只是完成一半,还不想提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到hotfix分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。
  2. 由于疏忽,本应该在dev分支开发的内容,却在master上进行了开发,需要重新切回到dev分支上进行开发,可以用git stash将内容保存至堆栈中,切回到dev分支后,再次恢复内容即可。
    总的来说,git stash命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。这也就是说,stash中的内容不仅仅可以恢复到原先开发的分支,也可以恢复到其他任意指定的分支上。git stash作用的范围包括工作区和暂存区中的内容,也就是说没有提交的内容都会保存至堆栈中。

命令详解:

1 git stash

能够将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   src/main/java/com/wy/CacheTest.java
        modified:   src/main/java/com/wy/StringTest.java
no changes added to commit (use "git add" and/or "git commit -a")
$ git stash
Saved working directory and index state WIP on master: b2f489c second
$ git status
On branch master
nothing to commit, working tree clean

2 git stash save

作用等同于git stash,区别是可以加一些注释,如下:
git stash的效果:

stash@{0}: WIP on master: b2f489c second

git stash save “test1”的效果:

stash@{0}: On master: test1

3 git stash list

查看当前stash中的内容

4 git stash pop

将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。
注:该命令将堆栈中最近保存的内容删除(栈是先进后出)
顺序执行git stash save “test1”和git stash save “test2”命令,效果如下:

$ git stash list
stash@{0}: On master: test2
stash@{1}: On master: test1
$ git stash pop
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   src/main/java/com/wy/StringTest.java
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (afc530377eacd4e80552d7ab1dad7234edf0145d)
$ git stash list
stash@{0}: On master: test1

可见,test2的stash是首先pop出来的。
如果从stash中恢复的内容和当前目录中的内容发生了冲突,也就是说,恢复的内容和当前目录修改了同一行的数据,那么会提示报错,需要解决冲突,可以通过创建新的分支来解决冲突。

5 git stash apply

将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。

$ git stash apply
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   src/main/java/com/wy/StringTest.java
no changes added to commit (use "git add" and/or "git commit -a")
$ git stash list
stash@{0}: On master: test2
stash@{1}: On master: test1

堆栈中的内容并没有删除。
可以使用git stash apply + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录。

6 git stash drop + 名称

从堆栈中移除某个指定的stash

7 git stash clear

清除堆栈中的所有 内容

8 git stash show

查看堆栈中最新保存的stash和当前目录的差异。

$ git stash show
 src/main/java/com/wy/StringTest.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

git stash show stash@{1}查看指定的stash和当前目录差异。
通过 git stash show -p 查看详细的不同:

$ git stash show -p
diff --git a/src/main/java/com/wy/CacheTest.java b/src/main/java/com/wy/CacheTest.java
index 6e90837..de0e47b 100644
--- a/src/main/java/com/wy/CacheTest.java
+++ b/src/main/java/com/wy/CacheTest.java
@@ -7,6 +7,6 @@ package com.wy
  */
 public class CacheTest {
     public static void main(String[] args) {
-        System.out.println("git stash test")
+        System.out.println("git stash test1")
     }
 }
diff --git a/src/main/java/com/wy/StringTest.java b/src/main/java/com/wy/StringTest.java
index a7e146c..711d63f 100644
--- a/src/main/java/com/wy/StringTest.java
+++ b/src/main/java/com/wy/StringTest.java
@@ -12,7 +12,7 @@ public class StringTest {
     @Test
     public void test1() {
-        System.out.println("=================")
+        System.out.println("git stash test1")
         System.out.println(Strings.isNullOrEmpty(""))
         System.out.println(Strings.isNullOrEmpty(" "))
         System.out.println(Strings.nullToEmpty(null))

同样,通过git stash show stash@{1} -p查看指定的stash的差异内容。

9 git stash branch

从最新的stash创建分支。
应用场景:当储藏了部分工作,暂时不去理会,继续在当前分支进行开发,后续想将stash中的内容恢复到当前工作目录时,如果是针对同一个文件的修改(即便不是同行数据),那么可能会发生冲突,恢复失败,这里通过创建新的分支来解决。可以用于解决stash中的内容和当前目录的内容发生冲突的情景。
发生冲突时,需手动解决冲突。

常见问题

failed to push some refs to git

由于本地没有某些远端仓库存在的文件,需要pull远端仓库。

git pull --rebase origin master

error: src refspec master does not match any.

常见原因:

  1. 本地git仓库目录下为空
  2. 本地仓库add后未commit
  3. git init错误

放弃本地所有更改

git reset --hard
# 将名为a的分支重命名为b
git branch -m a b
# 创建一个orphan分支
# orphan分支不会继承所有commit
git checkout --orphan <branch-name>

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.