zoukankan      html  css  js  c++  java
  • Git与GitHub的简单了解(2)

    3. 分支的操作

    ​ master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分支为中心进行的 ,从 master 分支创
    建 feature-A 分支和 fix-B 分支后,每个分支中都拥有自己的最新代码 。不同分支中,可以同时进行完全不同的作业。等该分支的作业完成之后再与 master 分支合并 ,利用分支可以使并行开发更加高效。

    ![1.jpg](http://wx4.sinaimg.cn/mw690/7b8d2108gy1fio0hrhdgij207f04i0sn.jpg)
    • git branch ---- 显示分支一览表
    $ git branch
    * master
    

    ​ master 分支左侧标有“*”(星号),表示这是我们当前所在的分支。 结果中没显示其他的分支名,表示本地仓库中只存在master一个分支。

    • git checkout -b ---- 创建、切换分支
    $ git checkout -b feature-A
    Switched to a new branch 'feature-A'
    

    ​ 此时当前分支自动切换到了feature-A分支:

    $ git branch
    * feature-A
    	master
    

    ​ 在这个状态下像正常开发那样修改代码、执行 git add命令并进行提交的话,代 码 就 会 提 交 至 feature-A 分 支。

    ​ 现在我们在之前的README.md中添加一行feature-A,进行提交:

    $ git add README.md
    $ git commit -m "Add feature-A"
    [feature-A 8a6c8b9] Add feature-A
     1 file changed, 2 insertions(+)
    

    ​ 现在我们切换到master分支下,

    $ git checkout master
    Switched to branch 'master'
    

    ​ 现在我们再打开README.md文档,会发现并没有添加文字。

    ​ 现在在回到上一分支下,即feature-A分支下:

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

    ​ 用“-”(连字符)代替分支名,就可以切换至上一个分支。当然,我们直接输入 feature-A 同样可以切换到 feature-A 分支。


    • 特性分支(Topic)

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

    ![2.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fio0hs14ebj205o04kq2u.jpg)
    ​ 之前我们创建了 feature-A 分支,这一分支主要实现 feature-A,除feature-A 的实现之外不进行任何作业。即便在开发过程中发现了 BUG,也需要再创建新的分支,在新分支中进行修正。
    • 主干分支-master

    ​ 主干分支是刚才我们讲解的特性分支的原点,同时也是合并的终点。通常人们会用 master 分支作为主干分支。主干分支中并没有开发到一半的代码,可以随时供他人查看。

    • git merge ---- 合并分支

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

    $ git checkout master
    Switched to branch 'master'
    

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

    $ git merge --no-ff feature-A
    

    ​ 随后进入编辑器状态(笔者的电脑默认打开的是VIM编辑器),vim基本命令:链接 ,默认信息中已经包含了是从 feature-A 分支合并过来的相关内容,所以可以不做任何更改,将编辑器中显示的内容保存,关闭编辑器(-wq)。 会看到以下的结果:

    Merge made by the 'recursive' strategy.
     README.md | 2 ++
     1 file changed, 2 insertions(+)
    
    • git log --graph ---- 以图表形式查看分支
    $ git log --graph
    * commit 83b0b94268675cb715ac6c8a5bc1965938c15f62
    | Merge: fd0cbf0 8a6c8b9
    | | Author: hirocaster <hohtsuka@gmail.com>
    | | Date: Sun May 5 16:37:57 2013 +0900
    | |
    | | Merge branch 'feature-A'
    | |
    | * commit 8a6c8b97c8962cd44afb69c65f26d6e1a6c088d8
    |/ Author: hirocaster <hohtsuka@gmail.com>
    | Date: Sun May 5 16:22:02 2013 +0900
    |
    | 		Add feature-A
    |
    * commit fd0cbf0d4a25f747230694d95cac1be72d33441d
    | Author: hirocaster <hohtsuka@gmail.com>
    | Date: Sun May 5 16:10:15 2013 +0900
    |
    |	    Add index
    |
    * commit 9f129bae19b2c82fb4e98cde5890e52a6c546922
    Author: hirocaster <hohtsuka@gmail.com>
    Date: Sun May 5 16:06:49 2013 +0900
    
    		First commit
    

    ​ git log --graph命令可以用图表形式输出提交日志,非常直观!

    4. 更改提交操作

    • git reset --- 回溯历史版本

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

    ​ 先创建为一个名为fix-B的特性分支:

    ![3.jpg](http://wx1.sinaimg.cn/mw690/7b8d2108gy1fio0hsl49rj203u042744.jpg)
    ​ 要让仓库的 HEAD、暂存区、当前工作树回溯到指定状态,需要用到 git rest --hard命令。只要提供目标时间点的哈希值 ,就可以完全恢复至该时间点的状态。
    $ git reset --hard fd0cbf0d4a25f747230694d95cac1be72d33441d
    HEAD is now at fd0cbf0 Add inde
    

    ​ 由于所有文件都回溯到了指定哈希值对应的时间点上, README.md 文件的内容也恢复到了当时的状态。

    ​ 创建fix-B分支:

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

    ​ 在 README.md 文件中添加一行文字 :- fix-B,接着提交README.md :

    $ git add README.md
    
    $ git commit -m "Fix B"
    [fix-B 4096d9e] Fix B
     1 file changed, 2 insertions(+)
    

    ​ 我们对于fix-B分支的下一步目标:

    ![4.jpg](http://wx3.sinaimg.cn/mw690/7b8d2108gy1fio0hs7325j2069067glk.jpg)

    5.jpg

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

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

    ​ 通过git reflog命令查看当前仓库执行过的操作日志:

    $ git reflog
    4096d9e HEAD@{0}: commit: Fix B
    fd0cbf0 HEAD@{1}: checkout: moving from master to fix-B
    fd0cbf0 HEAD@{2}: reset: moving to fd0cbf0d4a25f747230694d95cac1be72d33441d
    83b0b94 HEAD@{3}: merge feature-A: Merge made by the 'recursive' strategy.
    fd0cbf0 HEAD@{4}: checkout: moving from feature-A to master
    8a6c8b9 HEAD@{5}: checkout: moving from master to feature-A
    fd0cbf0 HEAD@{6}: checkout: moving from feature-A to master
    8a6c8b9 HEAD@{7}: commit: Add feature-A
    fd0cbf0 HEAD@{8}: checkout: moving from master to feature-A
    fd0cbf0 HEAD@{9}: commit: Add index
    9f129ba HEAD@{10}: commit (initial): First commit
    

    ​ 在日志中,我们可以看到 commit、 checkout、 reset、 merge 等 Git 命令的执行记录。只要不进行 Git 的 GC(Garbage Collection,垃圾回收),就可以通过日志随意调取近期的历史状态 。即便开发者错误执行了 Git 操作,基本也都可以利用 git reflog命令恢复到原先的状态,所以务必牢记本部分!

    ​ 上面第四行表示 feature-A 特性分支合并后的状态,对应哈希值为 83b0b94 ,将 HEAD、暂存区、工作树恢复到这个时间点的状态。

    $ git checkout master
    $ git reset --hard 83b0b94
    HEAD is now at 83b0b94 Merge branch 'feature-A'
    

    ​ 当前状态为:

    ![6.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fio0hte7ydj207g06tdft.jpg)
    ​ 现在只要合并 fix-B 分支,就可以得到我们想要的状态 。
    $ git merge --no-ff fix-B
    Auto-merging README.md
    CONFLICT (content): Merge conflict in README.md
    Recorded preimage for 'README.md'
    Automatic merge failed; fix conflicts and then commit the result.
    

    ​ 系统告诉我们 README.md 文件发生了冲突(Conflict)。系统在合并 README.md 文件时, feature-A 分支更改的部分与本次想要合并的 fix-B 分支更改的部分发生了冲突 ,不解决冲突就无法完成合并,所以我们打开 README.md 文件,解决这个冲突。 (cat、vim指令可以打开)

    # Git教程
    
    <<<<<<< HEAD
      - feature-A
    =======
      - fix-B
    >>>>>>> fix-B
    

    ​ ======= 以上的部分是当前 HEAD 的内容,以下的部分是要合并的 fix-B 分支中的内容。修改文档后,执行 git add命令与 git commit命令 。

    git add README.md
    
    $ git commit -m "Fix conflict"
    Recorded resolution for 'README.md'.
     [master 6a97e48] Fix conflict
    
    • git commit --amend ---- 修改提交信息

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

    $ git commit --amend
    

    ​ 此时进入vim编辑器模式,我们将Fix conflict 修改为Merge branch 'fix-B' 即可。(按照之前的vim命令链接操作,1、光标选中Fix后,按“i”键,进入写模式,删除第一行,添加即可,2、按下ESC键,进入编辑模式,输入:wq保存退出)

    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 <file>..." to unstage)
    #
    #     modified: README.md
    #
    
    • git rebase -i ---- 压缩历史

    ​ 在合并特性分支之前,如果发现已提交的内容中有些许拼写错误等,不妨提交一个修改,然后将这个修改包含到前一个提交之中,压缩成一个历史记录。

    ​ 首先创建特性分支feature-C:

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

    ​ 此外打开REDME.md文档故意添加一行错误的文字: - faeture-C ,提交这个小小的变更没必要先执行 git add命令再执行 git commit命令,我们用 git commit -am命令来一次完成这两步操作。

    $ git commit -am "Add feature-C"
    [feature-C 7a34294] Add feature-C
    1 file changed, 1 insertion(+)
    

    ​ 现在来修正刚才预留的拼写错误,修正后的差别为:

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

    ​ 我们将提交信息记为 "Fix typo" 进行提交。

    ​ 实际上,我们不希望在历史记录中看到这类提交 ,所以我们要更改历史。

    更改历史

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

    $ git rebase -i Head~2
    

    注:此处为波浪~符号,而非减法-号

    ​ 此时编辑器显示:

    pick 7a34294 Add feature-C
    pick 6fba227 Fix typo
    
    
    # Rebase 2e7db6f..6fba227 onto 2e7db6f
    #
    # Commands:
    # p, pick = use commit
    # r, reword = use commit, but edit the commit message
    # e, edit = use commit, but stop for amending
    # s, squash = use commit, but meld into previous commit
    # f, fixup = like "squash", but discard this commit's log message
    # x, exec = run command (the rest of the line) using shell
    #
    # These lines can be re-ordered; they are executed from top to bottom.
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    #
    # However, if you remove everything, the rebase will be aborted.
    #
    # Note that empty commits are commented out
    

    ​ 我们将 6fba227 的 Fix typo 的历史记录压缩到 7a34294 的 Add feature-C里。按照下图所示,将 6fba227 左侧的 pick 部分删除,改写为 fixup,保存好编辑器后:

    [detached HEAD 51440c5] Add feature-C
     1 file changed, 1 insertion(+)
    Successfully rebased and updated refs/heads/feature-C.
    

    ​ 再次查看日志有:

    $ git log --graph
    * commit 51440c55b23fa7fa50aedf20aa43c54138171137
    | Author: hirocaster <hohtsuka@gmail.com>
    | Date: Sun May 5 17:07:36 2013 +0900
    |
    | Add feature-C
    |
    * commit 2e7db6fb0b576e9946965ea680e4834ee889c9d8
    | Merge: 83b0b94 4096d9e
    | | Author: hirocaster <hohtsuka@gmail.com>
    | | Date: Sun May 5 16:58:27 2013 +0900
    | |
    | | Merge branch 'fix-B'
    | |
    | * commit 4096d9e856995a1aafa982aabb52bfc0da656b74
    | | Author: hirocaster <hohtsuka@gmail.com>
    | | Date: Sun May 5 16:50:31 2013 +0900
    | |
    | | Fix B
    省略
    

    ​ 现在将feature-C分支合并到master分支中:

    $ git checkout master
    Switched to branch 'master'
    
    $ git merge --no-ff feature-C
    Merge made by the 'recursive' strategy.
     README.md | 1 +
     1 file changed, 1 insertion(+)
    
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
  • 相关阅读:
    第一部分:开发前的准备-第二章 基础入门
    多线程笔记
    .net平台下垃圾回收机制
    xml基本操作和保存配置文件应用实例
    .net平台下C#socket通信(中)
    .net平台下C#socket通信(上)
    泛型
    面向过程和面向对象及面向对象的三大特征
    值类型和引用类型及参数传递
    js中typeof与instanceof区别
  • 原文地址:https://www.cnblogs.com/SrtFrmGNU/p/7390977.html
Copyright © 2011-2022 走看看