远程分支拉取
git fetch -a # 将远程profiling 分支拉到本地
git checkout -b profiling origin/profiling # 切换到gitlab中的profiling分支
创建和合并分支
- 在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