【Chapter 4】通过实际操作学习 Git

唉~我以为休息几天就不会痛了,看来我还是太天真了,实在是闲不住了,今天重新开始写笔记吧,读者们也注意身体,不要久坐。

第四章 通过实际操作学习 Git

4.1 基本操作

  • git init ——初始化仓库
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello (master)
    $ mkdir git-tutorial
    
    $ cd git-tutorial
    bash: cd: git-tutorial: No such file or directory
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master)
    $ git init
    Initialized empty Git repository in C:/Users/76152/Desktop/PyProjects/GitHub/Hello/git-tutorial/.git/
    
    
    

    如果初始化成功了,执行了 git init 命令的目录下会生成 .git 目录。这个目录存储着管理当前目录内容所需的仓库数据

  • git status——查看仓库的状态
    $ git status
    On branch master
    
    Initial commit
    
    nothing to commit (create/copy files and use "git add" to track)
    
    

    结果显示了我们当前正处于 master 分支下,且没有可提交的内容。

    接着我们创建 README.md 文件作为管理对象,为第一次提交做前期准备。

    $ touch README.md
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master)
    $ git status
    On branch master
    
    Initial commit
    
    Untracked files:
      (use "git add ..." to include in what will be committed)
    
            README.md
    
    nothing added to commit but untracked files present (use "git add" to track)
    

    可以看到在 Untracked files中显示了 README.md文件。

    类似地, 只要对 Git 的工作树或仓库进行操作,git status命令的显示结果就 会发生变化。

  • git add——向暂存区中添加文件
    $ git add README.md
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master)
    $ git status
    On branch master
    
    Initial commit
    
    Changes to be committed:
      (use "git rm --cached ..." to unstage)
    
            new file:   README.md
    
    

    将 README.md 文件加入暂存区后,使用 git status 命令查看 README.md 文件,显示结果已经变化。

  • git commit——保存仓库的历史记录

    git commit命令可以将当前暂存区中的文件实际保存到仓库的历 史记录中。通过这些记录,我们就可以在工作树中复原文件。

    1. 记述一行提交信息

    $ git commit -m "First commit"
    [master (root-commit) 51e40bb] First commit
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 README.md
    
    

    -m 参数后的 "First commit" 称作提交信息,是对这个提交的概述。

    2. 记述详细提交信息

    如果想要记述得更加详 细,请不加 -m,直接执行 git commit命令。

  • git log——查看提交日志
    $ git log
    commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master)
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 15:39:19 2018 +0800
    
        First commit
    

    屏幕显示了刚刚的提交操作。 commit 栏旁边显示的 “51e40bb0c……” 是指向这个提交的哈希值。Git 的其他命令中,在指向提交时会用到这个哈希值。 最后就是该提交的提交信息。

    1. 只显示提交信息的第一行

    如果只想让程序显示第一行的简述性信息,可以在 git log 命令后加上 --pretty=short。

    $ git log --pretty=short
    commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master)
    Author: Jadon <[email protected]>
    
        First commit
    
    

    2. 只显示指定文件、目录的日志

    只要在 git log 命令后面加上目录名/文件名。便会显示相应的日志。

    $ git log README.md
    commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master)
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 15:39:19 2018 +0800
    
        First commit
    

    3. 显示文件的改动

    如果想查看提交所带来的改动,可以加上 -p 参数,文件的前后差 别就会显示在提交信息之后。

    $ git log -p
    commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master)
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 15:39:19 2018 +0800
    
        First commit
    
    diff --git a/README.md b/README.md
    new file mode 100644
    index 0000000..e69de29
    
    

    比如,我们修改 README.md,并执行下面的命令,就可以只查看 README.md 文件的提交日志以及提交前后的差别。

    $ git log -p README.md
    commit 95cf441aad40363e03326657aa25667a965078f9 (HEAD -> master)
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 16:03:56 2018 +0800
    
        text2
    
    diff --git a/README.md b/README.md
    index e69de29..f3ca610 100644
    --- a/README.md
    +++ b/README.md
    @@ -0,0 +1 @@
    +你好
    \ No newline at end of file
    
    commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 15:39:19 2018 +0800
    
        First commit
    
    diff --git a/README.md b/README.md
    new file mode 100644
    index 0000000..e69de29
    :
    
  • git diff——查看更改前后的差别

    git diff命令可以查看工作树、暂存区、最新提交之间的差别。

    1. 查看工作树和暂存区的差别

    我们修改 README.md 文件,并执行 git diff 命令。

    $ git diff
    diff --git a/README.md b/README.md
    index e69de29..0d34868 100644
    --- a/README.md
    +++ b/README.md
    @@ -0,0 +1 @@
    +# Hello GitHub
    
    

    由于我们尚未用 git add 命令向暂存区添加任何东西,所以程序 只会显示工作树与最新提交状态之间的差别。

    “+”号标出的是新添加的行,被删除的 行则用“-”号标出。我们可以看到,这次只添加了一行。

    2. 查看工作树和最新提交的差别

    $ git add README.md
    
    $ git diff HEAD
    diff --git a/README.md b/README.md
    index 0d34868..4b4963b 100644
    --- a/README.md
    +++ b/README.md
    @@ -1 +1 @@
    -# Hello GitHub
    
    

    执行 git add README.md 后,如果现在执行 git diff命令,由于工作树和暂存区的状态并无 差别,结果什么都不会显示。要查看与最新提交的差别,请执行 git diff HEAD 命令。

    不妨养成这样一个好习惯:在执行 git commit 命令之前先执行 git diff HEAD命令,查看本次提交与上次提交之间有什么差别,等确认完毕后再进行提交。

    这里的 HEAD是指向当前分支中最新一次提交的指针。

    由于我们刚刚确认过两个提交之间的差别,所以直接运行git commit命令。

    $ git commit -m "Add index"
    [master 65f2814] Add index
     2 files changed, 1 insertion(+), 1 deletion(-)
     create mode 100644 test.txt
    
    

    保险起见,我们查看一下提交日志,确认提交是否成功。

    $ git log
    commit 65f2814a20db917f2d71457b3e5db95c377f4af9 (HEAD -> master)
    Author: Jadon <[email protected]>
    Date:   Wed Apr 18 16:24:56 2018 +0800
    
        Add index
    
    

4.2 分支操作

在进行多个并行作业时,我们会用到分支。在这类并行开发的过程 中,往往同时存在多个最新代码状态。

如下图所示,从master分支创建 feature-A 分支和 fix-B 分支后,每个分支中都拥有自己的最新代码。master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分支为中心进行的。

【Chapter 4】通过实际操作学习 Git_第1张图片

不同分支中,可以同时进行完全不同的作业。等该分支的作业完成之后再与 master 分支合并。比如 feature-A分支的作业结束后与 master 合并,如下图所示。

【Chapter 4】通过实际操作学习 Git_第2张图片
  • git branch——显示分支一览表

    git branch 命令可以将分支名列表显示,同时可以确认当前所在 分支。

  • git checkout -b——创建、切换分支

    如果想以当前的master分支为基础创建新的分支,我们需要用到 git checkout -b命令。

    1. 切换到 feature-A 分支并进行提交

    创建并切换到名为 feature-A 的分支

    $ git checkout -b feature-A
    Switched to a new branch 'feature-A'
    
    

    连续执行下面两条命令也能收到同样效果。

    $ git branch feature-A 
    $ git checkout feature-A
    

    使用 git branch 命令查看分支一览表, “ * ”表示我们当前的分支。

    $ git branch
    * feature-A
      master
    
    

    在这个状态下像正常开发那样修改代码、执行 git add 命令并进行提交的话,代码就会提交至 feature-A 分支。像这样不断对一个分支(例如 feature-A)进行提交的操作,我们称为“培育分支”。

    修改 README.md

    # Hello GitHub 
    
     - feature-A
    

    提交 README.md 到 feature-A 分支中。

    $ git add README.md
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (feature-A)
    $ git commit -m "Add feature-A"
    [feature-A f0adaa3] Add feature-A
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    

    2. 切换到 master 分支

    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master)
    $ git checkout master
    Switched to branch 'master'
    

    打开文件 README.md ,发现文件并没有发生变化。

    feature-A分支的更改不会影响到 master分支,这正是在开发中创建分支的优点。

    3. 切换回上一个分支

    $ git checkout -
    Switched to branch 'feature-A'
    
    

    将“-”替换成 feature-A 同样可以切换到 feature-A 分支。

  • 特性分支

    特性分支顾名思义,是集中实现单一特性(主题),除此之外不进 行任何作业的分支。

    在日常开发中,往往会创建数个特性分支,同时在此之外再保留一个随时可以发布软件的稳定分支。稳定分支的角色通常 由 master 分支担当。

    【Chapter 4】通过实际操作学习 Git_第3张图片

  • 主干分支

    主干分支是刚才我们讲解的特性分支的原点,同时也是合并的 点。

    通常人们会用 master 分支作为主干分支(拥有多个版本发布时,主干分支可以有多个)。主干分支中并没有开发到 一半的代码,可以随时供他人查看。

  • git merge——合并分支

    假设 feature-A 已经实现完毕,想要将它合并到主干分 支 master 中。

    首先切换到 master 分支。

    $ git checkout master
    Switched to branch 'master'
    
    

    然后合并 feature-A 分支。为了在历史记录中明确记录下本次分支合 并,我们需要创建合并提交。因此,在合并时加上 --no-ff参数。

    $ git merge --no-ff feature-A
    
    

    随后编辑器会启动,用于录入合并提交的信息。

    Merge branch 'feature-A'
    
    # Please enter a commit message to explain why this merge is necessary, 
    # especially if it merges an updated upstream into a topic branch. 
    #
    # Lines starting with '#' will be ignored, and an empty message aborts 
    # the commit.
    
    

    默认信息中已经包含了是从 feature-A 分支合并过来的相关内容,所 以可不必做任何更改。将编辑器中显示的内容保存,关闭编辑器,然后就会看到下面的结果。

    Merge made by the 'recursive' strategy.
    README.md | 2 ++ 
    1 file changed, 2 insertions(+)
    

    这样一来,feature-A 分支的内容就合并到 master 分支中了。

    注意:

    使用 git merge --no-ff feature-A 命令,会进入到vim 编辑器。

    然后你会发现编辑器里你怎么输入都没反应,这是因为vim处在不可编辑状态,按下字母键 c,此时进入编辑状态,可以开始修改注释信息了;

    再然后你会发现你怎么都退出不了,回到 shell 了,此时,按下 ESC 退出编辑状态;

    最后连续按两次大写字母键 Z,就可以保存信息并退出来了(第一次玩这个,折腾了挺久的)。

  • git log --graph——以图表形式查看分支

    用 git log --graph 命令进行查看的话,能很清楚地看到特性 分支(feature-A)提交的内容已被合并。

    除此以外,特性分支的创建 及合并也都清楚明了

    $ git log --graph
    *   commit a120a5cc58d1665b0b12793b92267a3f4f665491 (HEAD -> master)
    |\  Merge: 0fcf070 07f5b0a
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 17:43:07 2018 +0800
    | |
    | |     Merge branch 'feature-A'
    | |
    | * commit 07f5b0a0eb2598964c09082693749d201f905f7c (feature-A)
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 17:40:15 2018 +0800
    | |
    | |     Add feature-A
    | |
    | * commit ac3e358ca1848a6b1387d376acc3a008e3cb5172
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 17:27:42 2018 +0800
    | |
    | |     Add feature-A
    | |
    | * commit 34be8333a59d28ea692e002ff91eb55eed4398ff
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 17:20:46 2018 +0800
    | |
    
    

4.3 更改提交的操作

  • git reset——回溯历史版本

    Git的另一特征便是可以灵活操作历史版本。借助分散仓库的优势, 可以在不影响其他仓库的前提下对历史版本进行操作。

    为了让各位熟悉对历史版本的操作,我们先回溯历史版本,创建一个名为 fix-B 的特性分支。

【Chapter 4】通过实际操作学习 Git_第4张图片

1. 回溯到创建 feature-A 分支前

让我们先回溯到上一节feature-A分支创建之前,创建一个名为 fix-B 的特性分支。

要让仓库的HEAD、暂存区、当前工作树回溯到指定状态,需要用 到 git rest --hard命令。只要提供目标时间点的哈希值 A,就可以完全恢复至该时间点的状态。

$ git reset --hard 65f2814a20db917f2d71457b3e5db95c377f4af9
HEAD is now at 65f2814 Add index

我们已经成功回溯到特性分支(feature-A)创建之前的状态。由于所有文件都回溯到了指定哈希值对应的时间点上,README.md 文件的 内容也恢复到了当时的状态(只有标题的状态)。

2. 创建 fix-B 分支

$ git checkout -b fix-B
Switched to a new branch 'fix-B'

修改 README.md

Hello GitHub

- fix-B

提交文件

$ git add README.md

Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (fix-B)
$ git commit -m "Fix-B"
[fix-B dfa4302] Fix-B
 1 file changed, 3 insertions(+), 1 deletion(-)

现在的状态如图 4.5 所示。接下来我们的目标是图 4.6 中所示的状 态,即主干分支合并 feature-A 分支的修改后,又合并了 fix-B 的修改。

【Chapter 4】通过实际操作学习 Git_第5张图片
图4.5
【Chapter 4】通过实际操作学习 Git_第6张图片
图4.6

3. 推进至 feature-A 分支合并后的状态

首先恢复到 feature-A 分支合并后的状态。不妨称这一操作为“推进 历史”。(什么鬼?)

git log 命令只能查看以当前状态为终点的历史日志。

所以这里 要使用 git reflog 命令,查看当前仓库的操作日志。在日志中找出 回溯历史之前的哈希值,通过 git reset --hard 命令恢复到回溯历 史前的状态。

只要不进行 Git 的 GC(Garbage Collection,垃圾回收), 就可以通过日志随意调取近期的历史状态。

即便开发者错误执行了Git操作, 基本也都可以利用 git reflog 命令恢复到原先的状态。

$ git checkout -
Switched to branch 'master'

$ git reset --hard a120a5c
HEAD is now at a120a5c Merge branch 'feature-A'

当前状态为


【Chapter 4】通过实际操作学习 Git_第7张图片

  • 消除冲突

    现在只要合并 fix-B 分支,就可以得到我们想要的状态。

    $ git merge --no-ff fix-B
    Auto-merging README.md
    CONFLICT (content): Merge conflict in README.md
    Automatic merge failed; fix conflicts and then commit the result.
    
    

    这时,系统告诉我们 README.md 文件发生了冲突(Conflict)。

    系统在合并 README.md 文件时,feature-A 分支更改的部分与本次想要合并的 fix-B 分支更改的部分发生了冲突。

    不解决冲突就无法完成合并,所以我们打开 README.md文件,解决这个冲突。

    1.  查看冲突部分并将其解决

    此时打开 README.md 文件,就会发现内容变成了下面这个样子

    # Hello GitHub 
    
    <<<<<<< HEAD
     - feature-A
    =======
    - fix-B
    >>>>>>> fix-B
    
    

    =======以上的部分是当前HEAD的内容,以下的部分是要合并 的 fix-B 分支中的内容。我们在编辑器中将其改成想要的样子(直接改?我还以为有什么高端的操作)。

    # Hello GitHub 
    
     - feature-A
     - fix-B
    
    

    如上所示,本次修正让 feature-A 与 fix-B 的内容并存于文件之中。

    但是在实际的软件开发中,往往需要删除其中之一,所以各位在处理冲突时,务必要仔细分析冲突部分的内容后再行修改。

    2. 提交解决后的结果

    $ git add README.md
    
    $ git commit -m "Fix conflict"
    [master 51a829b] Fix conflict
    
    

  • git commit --amend——修改提交信息

    要修改上一条提交信息,可以使用 git commit --amend命令。

    我们将上一条提交信息记为了 "Fix conflict",但它其实是 fix-B分 支的合并,解决合并时发生的冲突只是过程之一,这样标记实在不妥。 于是,我们要修改这条提交信息。

    $ git commit --amend
     
    

    执行上面的命令后,编辑器就会启动。

    Fix conflict
    
    # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. 
    # On branch master # Changes to be committed: 
    #   (use "git reset HEAD^1 ..." to unstage) 
    # 
    #       modified:   README.md 
    #
    

    编辑器中显示的内容如上所示,其中包含之前的提交信息。

    请将 提交信息的部分修改为 Merge branch 'fix-B',然后保存文件,关闭编辑器(我也不知道是不是这样改,结果一样)。

    【Chapter 4】通过实际操作学习 Git_第8张图片

    更改后

    $ git log --graph
    *   commit 2d9907ae4bc6efccdc647d181346794f65a4fa86 (HEAD -> master)
    |\  Merge: a120a5c dfa4302
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 20:26:32 2018 +0800
    | |
    | |     Merge branch 'fix-B'
    
    

  • git rebase -i——压缩历史

    在合并特性分支之前,如果发现已提交的内容中有些许拼写错误等, 不妨提交一个修改,然后将这个修改包含到前一个提交之中,压缩成一 个历史记录。这是个会经常用到的技巧,让我们来实际操作体会一下。

    1. 创建 feature-C 分支

    $ git checkout -b feature-C
    Switched to a new branch 'feature-C'
    
    

    修改文件,故意拼错

    # Hello GitHub 
    
     - feature-A
     - fix-B
     - faeture-C
    
    

    提交这部分内容。这个小小的变更就没必要先执行 git add命令 再执行 git commit命令了,我们用 git commit -am命令来一次 完成这两步操作。

    $ git commit -am "Add feature-C"
    [feature-C ae1dd4a] Add feature-C
     2 files changed, 1 insertion(+)
     delete mode 100644 test.txt
    
    

    2. 修正拼写错误

    自行修正 README.md 文件。

    修正后差别如下:

    $ git diff
    diff --git a/README.md b/README.md
    index 30e62c5..b77c703 100644
    --- a/README.md
    +++ b/README.md
    @@ -2,4 +2,4 @@
    
      - feature-A
      - fix-B
    - - faeture-C
    + - feature-C
    
    

    进行提交

    $ git commit -am "Fix typo"
    [feature-C 75b6433] Fix typo
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    

    错字漏字等失误称作 typo,所以我们将提交信息记为 "Fix typo"。

    实际上,我们不希望在历史记录中看到这类提交,因为健全的历史记录 并不需要它们。如果能在最初提交之前就发现并修正这些错误,也就不 会出现这类提交了。

    3. 更改历史

    将 "Fix typo"修正的内容与之前一次的提交合并,在历史记录中合并为一次完美的提交。为此,我们要用到 git rebase命令。

    $ git rebase -i HEAD~2
    

    用上述方式执行 git rebase命令,可以选定当前分支中包含 HEAD(最新提交)在内的两个最新历史记录为对象,并在编辑器中打开。


    【Chapter 4】通过实际操作学习 Git_第9张图片

    如上所示,我们将 Fix typo 的 pick 改为 fixup,这样就可以把 Fix typo 的历史记录压缩到 Add feature-C 里。

    $ git rebase -i HEAD~2
    Successfully rebased and updated refs/heads/feature-C.
    
    

    系统显示 rebase 成功。也就是将 "Fix typo" 的内容合并到了上一个提交 "Add feature-C" 中,改写成了一个新的提交。

    $ git log --graph
    * commit 70e60670827b9c962a2532a421d4c01eb93c90b7 (HEAD -> feature-C)
    | Author: Jadon <[email protected]>
    | Date:   Wed Apr 18 21:01:11 2018 +0800
    |
    |     Add feature-C
    |
    *   commit 2d9907ae4bc6efccdc647d181346794f65a4fa86 (master)
    |\  Merge: a120a5c dfa4302
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 20:26:32 2018 +0800
    | |
    | |     Merge branch 'fix-B'
    | |
    | * commit dfa4302d449eb325dae383a02e5e152723dbed26 (fix-B)
    | | Author: Jadon <[email protected]>
    | | Date:   Wed Apr 18 19:53:59 2018 +0800
    | |
    | |     Fix-B
    
    

    这样一来,Fix typo 就从历史中被抹去,也就相当于 Add feature-C 中从来没有出现过拼写错误。这算是一种良性的历史改写。

    4.合并至 master 分支

    $ git checkout master
    Switched to branch 'master'
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master)
    $ git merge --no-ff feature-C
    Merge made by the 'recursive' strategy.
     README.md | 1 +
     1 files changed, 1 insertion(+)
    
    

4.4 推送至远程仓库

Git 是分散型版本管理系统,但我们前面所学习的,都是针对单一 本地仓库的操作。下面,我们将开始接触远在网络另一头的远程仓库。

远程仓库顾名思义,是与我们本地仓库相对独立的另一个仓库。 让我们先在 GitHub 上创建一个仓库,并将其设置为本地仓库的远程仓库。

在 github 上新建一个名为 git-tutorial 的仓库,并且创建时请不要勾选 Initialize this repository with a README 选项。因为一旦勾 选该选项,GitHub一侧的仓库就会自动生成 README 文件,从创建之初便与本地仓库失去了整合性。

  • git remote add——添加远程仓库
    $ git remote add origin [email protected]:Jun-Dong/git-tutorial.git
    

  • git push——推送至远程仓库

    1. 推送至 master 分支

    使用 git push 将当前分支下本地库的内容推送给远程仓库。

    $ git push -u origin master
    Counting objects: 46, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (28/28), done.
    Writing objects: 100% (46/46), 3.82 KiB | 0 bytes/s, done.
    Total 46 (delta 7), reused 0 (delta 0)
    remote: Resolving deltas: 100% (7/7), done.
    To github.com:Jun-Dong/git-tutorial.git
     * [new branch]      master -> master
    Branch master set up to track remote branch master from origin.
    
    

    像这样执行 git push 命令,当前分支的内容就会被推送给远程仓库 origin 的 master 分支。-u参数可以在推送的同时,将 origin 仓库的 master 分支设置为本地仓库当前分支的 upstream(上游)。添加了这个参数,将来 运行 git pull 命令从远程仓库获取内容时,本地仓库的这个分支就可以直接从 origin 的 master 分支获取内容,省去了另外添加参数的麻烦。

    在 github 上可以确认远程 master 分支的内容是否和本地 master 分支相同。

    2. 推送至 master 以外的分支

    除了master分支之外,远程仓库也可以创建其他分支。举个例子,我们在本地仓库中创建 feature-D 分支,并将它以同名形式 push 至远程仓库。

    $ git checkout -b feature-D
    Switched to a new branch 'feature-D'
    
    $ git push -u origin feature-D
    Total 0 (delta 0), reused 0 (delta 0)
    To github.com:Jun-Dong/git-tutorial.git
     * [new branch]      feature-D -> feature-D
    Branch feature-D set up to track remote branch feature-D from origin.
    
    

    我们在本地仓库创建了 feature-D 分支,并将它 push 给远程仓库并保持分支名称不变。

    在 github 上查看 feature-D 分支。

【Chapter 4】通过实际操作学习 Git_第10张图片

4.5 从远程仓库获取

我们把在 GitHub 上新建的仓库设置成了远程仓库,并向 这个仓库push了 feature-D 分支。现在,所有能够访问这个远程仓库的 人都可以获取 feature-D 分支并加以修改。

接下来我们从实际开发者的角度出发,在另一个目录下新建一个本地仓库,学习从远程仓库获取内容的相关操作。这就相当于我们刚刚执行过 push 操作的目标仓库又有了另一名新开发者来共同开发。

  • git clone——获取远程仓库

    1. 获取远程仓库

    首先我们换到其他目录下,将 GitHub 上的仓库 clone 到本地。注意不要与之前操作的仓库在同一目录下。

    $ git clone [email protected]:Jun-Dong/git-tutorial.git
    Cloning into 'git-tutorial'...
    remote: Counting objects: 46, done.
    remote: Compressing objects: 100% (21/21), done.
    Receiving objects: 100% (46/46), done.
    Resolving deltas: 100% (7/7), done.
    remote: Total 46 (delta 7), reused 46 (delta 7), pack-reused 0
    
    Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Helo2
    $ cd git-tutorial
    
    

    执行 git clone 命令后我们会默认处于 master 分支下,同时系统会自动将 origin设 置成该远程仓库的标识符。也就是说,当前本地仓库 的 master 分支与 GitHub端远程仓库(origin)的 master分支在内容上是完全相同的。

    $ git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/feature-D
      remotes/origin/master
    
    

    我们用 git branch -a命令查看当前分支的相关信息。添加 -a 参数可以同时显示本地仓库和远程仓库的分支信息。

    2. 获取远程的 feature-D 分支

    $ git checkout -b feature-D origin/feature-D
    Switched to a new branch 'feature-D'
    Branch feature-D set up to track remote branch feature-D from origin.
    
    

    -b 参数的后面是本地仓库中新建分支的名称。为了便于理解,我们仍将其命名为 feature-D,让它与远程仓库的对应分支保持同名。新建分支名称后面是获取来源的分支名称。例子中指定了origin/feature-D, 就是说以名为 origin的仓库(这里指 GitHub 端的仓库)的 feature-D 分支为来源,在本地仓库中创建 feature-D 分支。

    3. 向本地的 feature-D 分支提交更改

    现在假定我们是另一名开发者,要做一个新的提交。在README. md 文件中添加一行文字,查看更改,并提交。

    $ git diff
    diff --git a/README.md b/README.md
    index b77c703..4309f62 100644
    --- a/README.md
    +++ b/README.md
    @@ -3,3 +3,4 @@
      - feature-A
      - fix-B
      - feature-C
    + - feature-D
    
    $ git commit -am "Add feature-D"
    [feature-D fe60f80] Add feature-D
     1 file changed, 1 insertion(+)
    
    

    4. 推送 feature-D 分支

    现在来推送 feature-D 分支

    $ git push
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 277 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To github.com:Jun-Dong/git-tutorial.git
       4275a5a..fe60f80  feature-D -> feature-D
    
    

    从远程仓库获取 feature-D 分支,在本地仓库中提交更改,再将 feature-D 分支推送回远程仓库,通过这一系列操作,就可以与其他开发者相互合作,共同培育 feature-D 分支,实现某些功能。

  • git pull——获取最新的远程仓库分支

    现在回到原先的那个目录下,这边的本地仓库中只创建了 feature-D分支,并没有在 feature-D分支中进行任何提交。然而远程仓库的 feature-D 分支中已经有了我们刚刚推送的提交。 这时我们就可以使用 git pull 命令,将本地的 feature-D 分支更新到最新 状态。切换到 feature-D 分支。

    $ git pull origin feature-D
    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
    Unpacking objects: 100% (3/3), done.
    From github.com:Jun-Dong/git-tutorial
     * branch            feature-D  -> FETCH_HEAD
       4275a5a..fe60f80  feature-D  -> origin/feature-D
    Updating 4275a5a..fe60f80
    Fast-forward
     README.md | 1 +
     1 file changed, 1 insertion(+)
    
    

    GitHub 端远程仓库中的 feature-D 分支是最新状态,所以本地仓库中的 feature-D 分支就得到了更新。今后只需要像平常一样在本地进行提交再push给远程仓库,就可以与其他开发者同时在同一个分支中进行作业,不断给 feature-D 增加新功能。

    如果两人同时修改了同一部分的源代码,push 时就很容易发生冲突。所以多名开发者在同一个分支中进行作业时,为减少冲突情况的发 生,建议更频繁地进行 push 和 pull 操作。

这一章有点长,今天就一章了哈。

你可能感兴趣的:(【Chapter 4】通过实际操作学习 Git)