创建和合并分支
- 在git中,会把每次提交都连成一条时间线,这条时间线就是一个分支。(在我们初始化一个目录后,默认提交后产生的就是master分支,称为主分支)。在git里HEAD用来指向当前分支,而master指针(或者你新建的dev等分支)是用来指向最近的一次提交。通过这种方式,我们就可以知道当前分支以及当前分支的最新提交点
- 接下来进入测试:先创建分支dev(git创建一个dev指针,然后指向最新的提交),然后切换分支到dev(HEAD指针指向dev分支)。所以git创建一个分支很简单,只是添加一个dev指针,然后改变HEAD的指向就完成了。这也是git为什么比较( ఠൠఠ )ノ的原因
$ git checkout -b dev Switched to a new branch 'dev'
或者
$ git branch * dev master
- 现在,我们就可以在dev分支上work了。commit提交后,这样dev指针就往前移动一步,而master指针还在原处
$ cat >> doc1.txt add a new branch named dev $ git add doc1.txt $ git commit -m "branch dev test" [dev b796f15] branch dev test 1 file changed, 1 insertion(+)
- 当处理完dev分支的任务后,切回master分支,但此时因为master指针还在原处,所以doc1文件并没有 在dev中加的内容
$ git checkout master Switched to branch 'master' Your branch is up-to-date with 't3/master'. $ cat doc1.txt this is 1 line this is 5 line this is 7 line
- 那如何将dev分支上的修改同步到master分支上呢?git则是直接通过将master指针指向dev指针指向的提交,这样就完成了合并,只是改动下指针的指向就可以,并未修改工作区的内容
$ git merge dev Updating feed81d..b796f15 Fast-forward doc1.txt | 1 + 1 file changed, 1 insertion(+) $ cat doc1.txt this is 1 line this is 5 line this is 7 line add a new branch named dev
最后,就可以删除dev分支了。
$ git branch -d dev Deleted branch dev (was b796f15). $ git branch * master
合并冲突分支
上面合并分支的时候并未在主分支上做修改commit,然后merge合并,所以一切顺利。但是,如果你在创建的新分支上提交后,又在主分支上修改后提交(注意:如果没有修改,直接add--->commit是不会发生合并冲突的。因为你没有修改内容,也就没有内容add到暂存区,当然此时你commit的话,master指针就不会往前移动啦)
- 接下来就实例演示下,先在tre分支上修改并提交
$ cat >> doc1.txt this is new house $ git checkout -b tre Switched to a new branch 'tre' M doc1.txt $ git add doc1.txt $ git commit -m "tre" [tre 9d53879] tre 1 file changed, 1 insertion(+)
- 然后在master分支上修改并提交
$ git checkout master Switched to branch 'master' Your branch is up-to-date with 't3/master'. $ cat doc1.txt this is 1 line this is 5 line this is 7 line $ cat >> doc1.txt this is old house $ git add doc1.txt $ git commit -m "mas" [master a684d34] mas 1 file changed, 1 insertion(+)
- 最后合并
$ git merge tre Auto-merging doc1.txt CONFLICT (content): Merge conflict in doc1.txt Automatic merge failed; fix conflicts and then commit the result.
发现,报错了,此时的结构树是这样的
再用万能的git status查看也能看出错误
$ git status On branch master Your branch is ahead of 't3/master' by 1 commit. (use "git push" to publish your local commits) You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: doc1.txt no changes added to commit (use "git add" and/or "git commit -a")
如果直接查看doc1文件
$ cat doc1.txt this is 1 line this is 5 line this is 7 line <<<<<<< HEAD this is old house ======= this is new house >>>>>>> tre
从doc1文件可以看出在master分支和tre分支上的修改,这样我们就可以手动修改为 this is maybe old or new house 并提交了,此时的结构树就是这样的了
$ vim doc1.txt $ cat doc1.txt this is 1 line this is 5 line this is 7 line this is maybe old or new house $ git add doc1.txt $ git commit -m "handle conflict" [master cbf3047] handle conflict
通过 git log --graph --pretty=oneline --abbrev-commit 也能查看提交结构
$ git log --graph --pretty=oneline --abbrev-commit * cbf3047 (HEAD -> master) handle conflict |\ | * 9d53879 (tre) tre * | a684d34 mas |/ * 50e1e19 (t3/master) 1
分支管理策略
在上面合并分支的时候用的是Fast forward模式进行的合并,而这种模式虽然效率高,但是弊端是如果删除掉分支,就会丢掉分支信息。
如果合并的时候禁用 Fast forward模式,那么merge的时候会产生一个新的commit,从分支历史信息就能知道分支信息
实例演示:
在分支dev上修改数据并commit
$ git init Initialized empty Git repository in /data/project/lh/testgit/git4/.git/ $ cat >> doc 1 $ git add doc $ git commit -m "m 1" [master (root-commit) ec0e911] m 1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 doc $ git checkout -b dev Switched to a new branch 'dev' $ cat >> doc dev 1 $ git add doc $ git commit -m "dev 1" [dev 0564329] dev 1 1 files changed, 1 insertions(+), 0 deletions(-)
然后切换到master分支(一定要切换到master分支),在用--no-ff提交。就能看出分支历史树的具体提交信息
$ git checkout master Switched to branch 'master' $ git merge --no-ff -m "--no-ff merge dev" dev Merge made by recursive. doc | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) $ git log --graph --pretty=oneline --abbrev-commit * c61833a --no-ff merge dev |\ | * b9eabc6 dev 1 |/ * b127f76 m 1
这时候如果你再在dev分支commit后,然后到master分支merge。此时,不管你加不加--no-ff参数,分支历史树都能显示具体的提交信息。
$ cat >> doc dev2 $ git add doc $ git commit -m "dev 2" [dev e655732] dev 2 1 files changed, 1 insertions(+), 0 deletions(-) $ git checkout master Switched to branch 'master' [lh@super git4]$ git merge dev Merge made by recursive. doc | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) [lh@super git4]$ git log --graph --pretty=oneline --abbrev-commit * 579bfd8 Merge branch 'dev' |\ | * e655732 dev 2 * | c61833a --no-ff merge dev |\ \ | |/ | * b9eabc6 dev 1 |/ * b127f76 m 1