0%

git branch

前言

Branches in Git are incredibly lightweight as well. They are simply pointers to a specific commit – nothing more. This is why many Git enthusiasts chant the mantra:

branch early, and branch often.

Because there is no storage / memory overhead with making many branches, it’s easier to logically divide up your work than have big beefy branches.

When we start mixing branches and commits, we will see how these two features combine. For now though, just remember that a branch essentially says “I want to include the work of this commit and all parent commits.”

创建分支

1、创建本地bugfix分支
git branch bugfix

2、切换到bugfix分支

1
2
git branch -a
git checkout bugfix

3、创建远程bugfix分支
git push origin HEAD:bugfix
创建远程bugfix2分支
git push origin HEAD:bugfix2

4、下载后切换到bugfix分支
git checkout origin/bugfix

上传分支

在bugfix分支下进行了修改,然后提交修改,命令如下:

1
2
3
git add .
git commit -m "something"
git push origin HEAD:bugfix

删除分支

1、删除本地分支
git branch -D bugfix

2、删除线上分支
git push --delete origin bugfix

恢复已删除分支

1、查看全局日志
git reflog或者git log -g

2、新建分支
git branch bugfix 3eac14d

3、上传分支
git checkout bugfix
git push origin HEAD:bugfix

合并分支

合并分支,可以使用merge,也可以使用rebase。它们俩有什么区别呢?主要是适用场景不同:

场景一:基于 master 拉出来一个开发分支 dev,在 dev 分支开发完成了之后,要合并到 master 上。
操作:切换到 master 分支,使用 git merge dev
PS:对于git服务器端的merge合并,往往要发起MR,也就是Merge Request
为什么不使用git rebase dev?因为master是主干,rebase的话,主干就长歪了。为了保证master提交记录是笔直的主干,是一条直线,所以使用merge。

场景二:基于 master 拉出来一个开发分支 dev,在 dev 上开发了一段时间后,master分支也有了新的变更。为了保证我们在最新的版本基础上进行开发,这时需要把 master 分支提交的新内容更新到 dev 分支。
操作:切换到 dev 分支,使用 git rebase master
为什么不使用git merge master?因为dev最终是要merge到master的,如果master先merge到dev,开发一段时间后dev最后又merge到master,整个提交树会很混乱。为了保证提交记录的清晰明了,所以使用rebase。

查看提交树命令:git log --graph --pretty=oneline

模拟分支变更

1、初始化仓库和分支

1
2
3
4
5
6
7
mkdir test
cd test
git init
touch test.txt
git add .
git commit -m "first commit"
git checkout -b bugfix

2、bugfix分支上,新建test.txt文件,提交

1
2
3
echo "hello bugfix" > test.txt
git add .
git commit -m "update file in bugfix branch"

3、切到master分支,新建test.txt文件,提交

1
2
3
4
git checkout master
echo "hello master" > test.txt
git add .
git commit -m "update file in master branch"

merge

1、通过merge命令合并bugfix分支到master

1
git merge bugfix

提示冲突:

1
2
3
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.

2、查看冲突
git status,提示test.txt文件冲突。
打开test.txt,可以看到如下冲突:

1
2
3
4
5
<<<<<<< HEAD
hello master
=======
hello bugfix
>>>>>>> update file in bugfix branch

其中 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行 merge 命令时检出的分支)中的内容,下半部分是在bugfix分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。

3、解决冲突
修改test.txt如下:

1
hello master

4、提交

1
2
git add test.txt
git commit -m "merge bugfix into master"

5、查看提交记录
git log

rebase

1、通过rebase命令合并master分支到bugfix

1
2
git checkout bugfix
git rebase master

提示冲突:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
First, rewinding head to replay your work on top of it...
Applying: update file in bugfix branch
Using index info to reconstruct a base tree...
M test.txt
Falling back to patching base and 3-way merge...
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
error: Failed to merge in the changes.
Patch failed at 0001 update file in bugfix branch
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort"

此时我们进入了一个临时分支。

2、查看冲突
git status,提示test.txt文件冲突。
打开test.txt,可以看到如下冲突:

1
2
3
4
5
<<<<<<< HEAD
hello master
=======
hello bugfix
>>>>>>> update file in bugfix branch

3、解决冲突
修改test.txt如下:

1
hello master bugfix

4、提交

1
2
git add test.txt
git rebase --continue

5、查看提交记录
git log
可以看到三条记录:

1
2
3
update file in bugfix branch
update file in master branch
first commit

如果text.txt修改为:

1
hello master

这个修改可以手动操作,也可以使用命令git checkout --ours test.txt

那么提交命令为:

1
2
git add test.txt
git rebase --skip

此时只会有两个提交记录:

1
2
update file in master branch
first commit

rebase过程中,可以随时放弃rebase
git rebase --abort

解决冲突小结

合并时难免代码冲突,git会将冲突的代码用 <<<<<<< HEAD ======= >>>>>>> xxx 标识出来,其中=======之前表示的是ours分支,之后表示theirs分支。

解决冲突办法:首先确定保留哪一部分代码,然后手动删除标志 <<<<<<< HEAD ======= >>>>>>> xxx,最后commit。

如果想要保留两个分支中的某一个,可以使用 git chekout --ours <fileName> 或者 git checkout --theirs <fileName>

对于merge和rebase来说,这两个选项对应的分支正好是相反的。在使用 merge 时,ours指的是当前分支(master),theirs指的是要被合并的分支(dev)。而在 rebase 时,theirs指的是当前分支(dev),ours指向(master)。

书签

Learn Git Branching

git merge简介

Git Book - rebase

  • 本文作者: 好好学习的郝
  • 本文链接: https://www.voidking.com/dev-git-branch/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!源站会及时更新知识点及修正错误,阅读体验也更好。欢迎分享,欢迎收藏~