分支
查看当前的分支 默认只有一个 master 主分支
[root@Check1 test]# git branch
* master
创建一个分支
创建并切换的过程很快 即创建一个指针 HEAD指向新的指针
git checkout -b <分支名> 是创建并切换分支,是创建分支git branch <分支名>和切换分支 git checkout <分支名>的结合
[root@Check1 test]# git checkout -b dev
Switched to a new branch 'dev'
[root@Check1 test]# git branch
* dev
master
新分支会有之前主分支的所有内容
[root@Check1 test]# git log --pretty=oneline
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
在dev分支下编辑文件
[root@Check1 test]# echo "version 4.0" >> code.txt
[root@Check1 test]# git add code.txt
[root@Check1 test]# git commit -m "dev分支提交"
[dev 80d1fe8] dev分支提交
1 files changed, 1 insertions(+), 0 deletions(-)
切换分支
dev分支工作完成,切换回master分支
[root@Check1 test]# git checkout master
Switched to branch 'master'
查看当前所在分支
[root@Check1 test]# git branch
dev
* master
查看当前master分支下有没有dev下的版本记录 并没有
[root@Check1 test]# git log --pretty=oneline
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
合并分支
快速合并,直接把master指针指向dev的当前提交,所以速度也非常快
[root@Check1 test]# git merge dev
Updating e39c2ef..80d1fe8
Fast-forward
code.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
再查看一下分支记录
[root@Check1 test]# git log --pretty=oneline
80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
合并后删除dev分支
删除分支其实是直接删除指针
[root@Check1 test]# git branch -d dev
Deleted branch dev (was 80d1fe8).
[root@Check1 test]# git branch
* master
解决冲突
现象
现象:创建一个分支dev,在分支中修改code.txt文件并提交
[root@Check1 test]# git checkout -b dev
Switched to a new branch 'dev'
[root@Check1 test]# echo "version 5.0" >> code.txt
[root@Check1 test]# git add code.txt
[root@Check1 test]# git commit -m "版本5.0"
[dev b001913] 版本5.0
1 files changed, 1 insertions(+), 0 deletions(-)
[root@Check1 test]# git log --pretty=oneline
b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0
80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
提交后切换到master分支,也修改code.txt文件并提交
[root@Check1 test]# git checkout master
Switched to branch 'master'
[root@Check1 test]# git log --pretty=oneline
80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
[root@Check1 test]# echo "version 5.0 in master" >> code.txt
[root@Check1 test]# git add code.txt
[root@Check1 test]# git commit -m "版本5.0master分支提交"
[master 064fe6a] 版本5.0master分支提交
1 files changed, 1 insertions(+), 0 deletions(-)
[root@Check1 test]# git log --pretty=oneline
064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交
80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
合并分支失败
自动合并code.txt 合并时起了一个冲突 合并失败
[root@Check1 test]# git merge dev
Auto-merging code.txt
CONFLICT (content): Merge conflict in code.txt
Automatic merge failed; fix conflicts and then commit the result.
找到冲突的文件,可以通过git status
[root@Check1 test]# git status
# On branch master
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: code.txt 双方修改 冲突
#
no changes added to commit (use "git add" and/or "git commit -a")
查看这个文件,git已给标注是哪里起了冲突
[root@Check1 test]# cat code.txt
version 1.0
version 2.0
version 3.0
version 4.0
<<<<<<< HEAD
version 5.0 in master
=======
version 5.0
>>>>>>> dev
手动解决冲突
开始解决 (手动修改冲突的部分 并提交)在两个分支上面都有新的提交,并且编辑的还是同一个文件 才会有这样的冲突 冲突解决后需要一个手动的提交
[root@Check1 test]# cat code.txt
version 1.0
version 2.0
version 3.0
version 4.0
version 5.0 in master
version 5.0
[root@Check1 test]# git add code.txt
[root@Check1 test]# git commit -m "解决冲突"
[master b893d4c] 解决冲突
[root@Check1 test]# git log --pretty=oneline
b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突
064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交
b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0
80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
e39c2efc2c787218c481a625893af153aed3e42b new code
9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
查看分支冲突的情况
[root@Check1 test]# git log --graph --pretty=oneline
* b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突
|
| * b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0
* | 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交
|/
* 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交
* e39c2efc2c787218c481a625893af153aed3e42b new code
* 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0
* c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0
* 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
解决冲突后再删除dev分支
[root@Check1 test]# git branch -d dev
Deleted branch dev (was b001913).
[root@Check1 test]# git branch
* master
分支的管理策略
通常,合并分支时,如果可能,Git会用fast forward模式(快速合并),但是有些快速合并不能成功,而且合并时没有冲突,这个时候Git会在合并之后做一次新的提交。但这种模式下,删除分支后,会丢掉分支信息。
非快速合并
创建并切换到dev分支下,创建code3.txt文件,添加内容并提交
[root@Check1 test]# git checkout -b dev Switched to a new branch 'dev' [root@Check1 test]# git branch * dev master [root@Check1 test]# echo "version 1.0" >> code3.txt [root@Check1 test]# git add code3.txt [root@Check1 test]# git commit -m "创建code3.txt" [dev c021942] 创建code3.txt 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 code3.txt
切换回master分支,编辑code.txt文件,并提交修改
[root@Check1 test]# git checkout master Switched to branch 'master' [root@Check1 test]# git branch dev * master [root@Check1 test]# cat code.txt version 1.0 version 2.0 version 3.0 version 4.0 version 5.0 in master version 5.0 [root@Check1 test]# echo "version 6.0" >> code.txt [root@Check1 test]# git add code.txt [root@Check1 test]# git commit -m "版本6.0" [master 409fb33] 版本6.0 1 files changed, 1 insertions(+), 0 deletions(-) [root@Check1 test]# git log --pretty=oneline 409fb33e6dbe1e651cee019c06be7b17a5ab9a49 版本6.0 b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交 b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交 e39c2efc2c787218c481a625893af153aed3e42b new code 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0 c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
合并分支
可以看到这是合并版本后,Git又重新提交了一次 提交信息是Merge branch 'dev'
也可以看到这次合并不是fast forward模式,而且recuesive
[root@Check1 test]# git merge dev Merge made by recursive. code3.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 code3.txt [root@Check1 test]# git log --pretty=oneline 96ee7a7c4bf06a6303e26a5ff287e178558a7de2 Merge branch 'dev' 409fb33e6dbe1e651cee019c06be7b17a5ab9a49 版本6.0 c0219421a8af157adfc92e78f57edfaa1d88f419 创建code3.txt b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交 b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交 e39c2efc2c787218c481a625893af153aed3e42b new code 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0 c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
查看一下分支情况,也可以看到合并之后做了一次新的提交
[root@Check1 test]# git log --pretty=oneline --graph * 96ee7a7c4bf06a6303e26a5ff287e178558a7de2 Merge branch 'dev' | | * c0219421a8af157adfc92e78f57edfaa1d88f419 创建code3.txt * | 409fb33e6dbe1e651cee019c06be7b17a5ab9a49 版本6.0 |/ * b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突 | | * b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0 * | 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交 |/ * 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交 * e39c2efc2c787218c481a625893af153aed3e42b new code * 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0 * c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0 * 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
再删除dev分支
[root@Check1 test]# git branch -d dev
Deleted branch dev (was c021942).
[root@Check1 test]# git branch
* master
禁用快速合并
设置场景:
创建并切换dev分支
修改code.txt文件并提交版本
再切换回master分支
合并dev分支(使用:git merge --no-ff -m "禁用fast forward" dev)禁用快速合并,这样就会在合并的时候做一次新的提交,说明信息为 -m 后的信息
有时候默认使用快速合并,设置使用快速合并的模式就需要这样做
[root@Check1 test]# git checkout -b dev Switched to a new branch 'dev' [root@Check1 test]# git branch * dev master [root@Check1 test]# echo "version 7.0" >> code.txt [root@Check1 test]# git add code.txt [root@Check1 test]# git commit -m "版本7.0" [dev 745ffd4] 版本7.0 1 files changed, 1 insertions(+), 0 deletions(-) [root@Check1 test]# git checkout master Switched to branch 'master' [root@Check1 test]# git branch dev * master [root@Check1 test]# git merge --no-ff -m "禁用fast forward" dev Merge made by recursive. code.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) [root@Check1 test]# git log --pretty=oneline --graph * f3ace3470ddf06d51ddce146f0427755fbd866ac 禁用fast forward | | * 745ffd4664d6529c92cfcf09b5fc5bed72841070 版本7.0 |/ * 96ee7a7c4bf06a6303e26a5ff287e178558a7de2 Merge branch 'dev' | | * c0219421a8af157adfc92e78f57edfaa1d88f419 创建code3.txt * | 409fb33e6dbe1e651cee019c06be7b17a5ab9a49 版本6.0 |/ * b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突 | | * b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0 * | 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交 |/ * 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交 * e39c2efc2c787218c481a625893af153aed3e42b new code * 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0 * c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0 * 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
BUG分支
软件开发中,bug就像家常便饭一样,有了bug就需要修复,在Git中,由于分支是如此的强大,所以每个bug都可以通过一个临时分支来修复,修复后,合并分支,然后将临时分支删除。
当接收到一个代号为001的bug任务时,则创建一个bug-001分支来修复它,但是,当前正在dev分支上进行的工作好没有结束提交。。。
需要马上去修复bug,当前的工作区已修改,还没有做完,还不能提交
[root@Check1 test]# git branch dev * master [root@Check1 test]# git checkout dev Switched to branch 'dev' [root@Check1 test]# git branch * dev master [root@Check1 test]# echo "version 2.0" >> code3.txt [root@Check1 test]# git status # On branch dev # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: code3.txt # no changes added to commit (use "git add" and/or "git commit -a")
保存现场
使用git stash 命令,把当前工作现场保存起来,修复完bug,再回来继续工作
[root@Check1 test]# git stash Saved working directory and index state WIP on dev: 745ffd4 版本7.0 HEAD is now at 745ffd4 版本7.0 [root@Check1 test]# git status # On branch dev nothing to commit (working directory clean)
下面就可以修复这个bug了
假如是master分支上出现的bug,首先需要切换到master分支上,新建一个临时的分支bug-001来修改这个bug,在bug-001分支里面修改code.txt文件里的version 5.0
[root@Check1 test]# git checkout master Switched to branch 'master' [root@Check1 test]# git branch dev * master [root@Check1 test]# git checkout -b bug-001 Switched to a new branch 'bug-001' [root@Check1 test]# git branch * bug-001 dev master [root@Check1 test]# cat code.txt | grep '5.0' #查看需要删除的内容 version 5.0 in master version 5.0 [root@Check1 test]# sed -i '/.*5.0.*/d' code.txt #删除内容 [root@Check1 test]# cat code.txt | grep '5.0' #再次查看 [root@Check1 test]# git add code.txt [root@Check1 test]# git commit -m "删除错误代码 version 5.0.*" [bug-001 2089bfe] 删除错误代码 version 5.0.* 1 files changed, 0 insertions(+), 2 deletions(-) [root@Check1 test]# git checkout master Switched to branch 'master' [root@Check1 test]# git merge --no-ff -m "修复bug-001" bug-001 Merge made by recursive. code.txt | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) [root@Check1 test]# git branch -d bug-001 Deleted branch bug-001 (was 2089bfe). [root@Check1 test]# git log --pretty=oneline --graph * 823c5338340377fd44fa409fc2938ab234ace331 修复bug-001 | | * 2089bfe746d45ef5a030db9e848a5b52575f787f 删除错误代码 version 5.0.* |/ * f3ace3470ddf06d51ddce146f0427755fbd866ac 禁用fast forward | | * 745ffd4664d6529c92cfcf09b5fc5bed72841070 版本7.0 |/ * 96ee7a7c4bf06a6303e26a5ff287e178558a7de2 Merge branch 'dev' | | * c0219421a8af157adfc92e78f57edfaa1d88f419 创建code3.txt * | 409fb33e6dbe1e651cee019c06be7b17a5ab9a49 版本6.0 |/ * b893d4cfa12894c24f255ce25590f47f9ca62e15 解决冲突 | | * b001913d7d2959b1ef47ab9af50c84d105d3a4c0 版本5.0 * | 064fe6aa5727578e412f52f693d4fd27e67f4c49 版本5.0master分支提交 |/ * 80d1fe86dc1c5e1070018783b733729428dc99aa dev分支提交 * e39c2efc2c787218c481a625893af153aed3e42b new code * 9f9899114fdb0f59b8cd0cb3e009f33f2b7702e5 版本3.0 * c94bcab611218e72f9d806ee347dcfb1d12e73a3 版本2.0 * 0367a6a3bd901309e282dc630e6562b7f270e39b 版本1.0
还原现场
当bug修复完成后,可以回到dev分支下进行继续工作
切换到dev分支下,通过git stash list 查看已经保存的工作现场
再通过git stash pop来恢复工作环境
[root@Check1 test]# git checkout dev Switched to branch 'dev' [root@Check1 test]# git branch * dev master [root@Check1 test]# git status # On branch dev nothing to commit (working directory clean) [root@Check1 test]# git stash list stash@{0}: WIP on dev: 745ffd4 版本7.0 [root@Check1 test]# git stash pop # On branch dev # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: code3.txt # no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (edaf82450a0499576775f497988f8c532d315854)
总结
修复BUG时,通常会通过新的bug分支来进行修复,然后合并(禁止快速合并),最后删除,当手头工作没有完成时,先把工作现场保存一下(git stash),然后去修复bug,修复后,再恢复工作环境(git stash pop),再回到工作现场。