master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分支为中心进行的 ,从 master 分支创 建 feature-A 分支和 fix-B 分支后,每个分支中都拥有自己的最新代码 。不同分支中,可以同时进行完全不同的作业。等该分支的作业完成之后再与 master 分支合并 ,利用分支可以使并行开发更加高效。
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)
特性分支顾名思义,是集中实现单一特性(主题),除此之外不进行任何作业的分支。
之前我们创建了 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命令可以用图表形式输出提交日志,非常直观!
Git 的另一特征便是可以灵活操作历史版本。借助分散仓库的优势,可以在不影响其他仓库的前提下对历史版本进行操作。
先创建为一个名为fix-B的特性分支:
要让仓库的 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分支的下一步目标:
首先恢复到 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' 当前状态为:
现在只要合并 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(+)转载于:https://www.cnblogs.com/SrtFrmGNU/p/7390977.html