男儿欲遂平生志,五经勤向窗前读。这篇文章主要讲述GIT 版本管理 - 3 (分支管理)相关的知识,希望能为你提供帮助。
分支管理分支管理有什么用呢?
- 便于协同工作时的版本管理
- 便于多任务同步互不干扰的版本管理
$ git checkout -b dev
上面的命令创建了一个 dev 分支,并且将当前工作区分支从默认的master分支切换到dev分支
其实如果对上面的命令进行拆解,可以用两台命令来完成
$ git branch dev
$ git checkout dev
创建分支使用git branch 命令后面跟分支的名称即可
切换分支使用git checkout 后面跟分支的名称即可,感觉很眼熟,是不是哪里用到过?
$ git checkout dev
【GIT 版本管理 - 3 (分支管理)】是的,前面的版本管理中也用到过 git checkout用来丢弃工作区的修改,还原到暂存区的版本
$git checkout — filename
合并分支使用 git branch 可以查看当前版本库中有哪些分支,* 号对应着的是当前正在使用的分支
$ gitbranch
* dev
master
给dev分支加一个文件,然后提交,最后合并到master分支上去,并且在合并分支后将dev分支删除,合并分支需要使用到git merge 命令,具体操作如下:
$ touch dev.txt
$ git add dev.txt
$ git commit -m add file dev.txt
[dev f8ba521] add filedev.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev.txt
$ git checkout master
Switched to branch master
Your branch is up to date with rigion/master.
$ git merge dev
Updating 801d6f0..f8ba521
Fast-forward
dev.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev.txt
$ git branch -d dev
Deleted branch dev (was f8ba521).
$ git branch
* master
$ git push rigion master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 235 bytes | 235.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:zhengbinger/learngit.git
801d6f0..f8ba521master ->
master
上面这堆命令,做了很多操作
第一步:使用touch命令新建了一个dev.txt 的文件
第二步:使用git add命令将 dev.txt 文件加入到dev分支本地仓库的暂存区
第三步:使用git commit命令将暂存区的修改内容提交到本地仓库
第四部:使用git checkout 命令切换到master分支
第五步:在master 分支上使用 git merge 命令合并dev分支上的修改
第六步:使用git branch -d 命令删除dev分支
第七步:使用git branch 查看当前分支
第八步:使用git push推送当前master 上的修改到远程仓库
ok,那么我们这次操作中涉及到的分支操作内容有,创建分支、合并分支、删除分支相关的操作,并且推送到了远程仓库
解决冲突模拟场景
$ gitcheckout -b features
$ vi readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
Creating a new branch is quick &
simple
$ git add readme.txt
$ git commit-m AND simple
[features db758c4] AMD simple
1 file changed, 1 insertion(+)
$ gitcheckout master
Switched to branch master
Your branch is up to date with rigion/master.
$ vi readme.txt
$ gitadd readme.txt
$ git commit -m &
simple
$ git merge features
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed;
fix conflicts and then commit the result.
$ git status
On branch master
Your branch is ahead of rigion/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:readme.txtno changes added to commit (use "git add" and/or "git commit -a")
$ vireadme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<
<
<
<
<
<
<
HEAD
Creating a new branch is quick &
simple.
=======
Creating a new branch is quick AND simple.
>
>
>
>
>
>
>
features
$ gitadd readme.txt
$ git commit-m resolved fixed
[master e68db6c] resolvedfixed
$ gitstatus
On branch master
Your branch is ahead of rigion/master by 3 commits.
(use "git push" to publish your local commits)nothing to commit, working tree clean
$ gitlog --graph --pretty=oneline
*e68db6ce2192645403c90a311c25cee52fcde1e7 (HEAD ->
master) resolvedfixed
|\\
| * db758c4fd8de9f31e87bcb81787f7fd20db977b5 (features) AMD simple
* | c0264af950e75a512dc9895c9b3806c9ed4438ed &
simple
|/
* f8ba521f52ca2b4f6510ec3a35d7929fcde8d937 (rigion/master) add filedev.txt
* 801d6f066eecf1270920a361659dd61db3257457 add mutiplefiles
* ceebf2660aa2eea2f6c4e96a78dd5be08f728f6c add file test.txt
* 65d43dc687b35173b2d312bf7b71eb7593bc88ca append of files
* 400bdba9be3de24fb6077ef573564b6998af5cc9 tracks files
* e17c4d4d2d8d2893009f3e56e7711657055ef779 understand stage
* 7dc80a9b6475908835ab78562d7db68fda83757c appendGPL
* 56fb09bdfefc467e9b2f5aba2060c215c19f68c9 updatereadme.tct
* 9235ffdcced6c829b3f0fb991d5548c14fe49dc7 addreadme.txt
$ gitbranch -d features
Deleted branch features (was db758c4).
说明:版本冲突产生的根源:同一处修改记录存在两个不同的分支进行了修改的情况,git会认为有版本冲突
场面的场景中 features 分支在readme.txt文件末尾添加了一行内容:Creating a new branch is quick & simple 并提交到版本库
然后切换到mastermaster 在未进行合并的情况下,同样在readme.txt 文件的末尾添加了一行内容
Creating a new branch is quick and simple 并提交到版本库
在没有进行合并的情况下我们和git并不知晓两个版本存在冲突
但是在我们将master分支与features分支进行合并的时候,git会发现这两个分支修改了同一处内容,所以需要手动去处理冲突之后再进行提交才能够合并两个版本的内容
分支管理策略git 默认的master 分支常用作上线分支,一般不进行轻易改动,到上线前才将开发分支上经过充分测试,没有问题的版本内容合并到master主分支进行上线版本整理
然后会有一个dev分支用来日常开发,每个开发人员通过拉取dev分支的内容并且创建自己的分支来进行开发,开发完成之后合并dev分支,测试环境可以拉取dev分支进行测试环境发布
分支合并时默认情况下git会使用 Fast-Forward 快速合并分支,使用这种模式的话,在删除被合并掉的分支后,不会留痕迹的,当然我们也可以在合并的时候使用参数 --no-ff 来配置不使用快速合并,这时在要合并的分支上回创建一次commit
这样的话,即使在合并之后删除被合并的分支,在合并分支上也会留下一次commit的痕迹,便于后期查找修改记录的来源
$ git checkout-b zhengbing_dev
Switched to a new branch zhengbing_dev
$ gitbranch
master
* zhengbing_dev
$ rm readme2.txt
$ gitstatus
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:readme2.txtno changes added to commit (use "git add" and/or "git commit -a")
$ git rm readme2.txt
rm readme2.txt
$ gitcommit -m delete readme2.txt
[zhengbing_dev a2fb2cd] delete readme2.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 readme2.txt
$ gitcheckout master
Switched to branch master
Your branch is ahead of rigion/master by 3 commits.
(use "git push" to publish your local commits)
$ git merge zhengbing_dev --no-ff
Removing readme2.txt
Merge made by the recursive strategy.
readme2.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 readme2.txt
$ git log --pretty=oneline
4464110564988026594dd4263d707c10577074da (HEAD ->
master) Merge branch zhengbing_dev
a2fb2cda5f71231c9c0dd3eea6c9d6b673121529 (zhengbing_dev) delete readme2.txt
$ git branch -dzhengbing_dev
Deleted branch zhengbing_dev (was a2fb2cd).
$gitlog--pretty=oneline
4464110564988026594dd4263d707c10577074da (HEAD ->
master) Merge branch zhengbing_dev
使用Fast-Forward模式
$ gitcheckout -b zhengbing_dev
Switched to a new branch zhengbing_dev
$ ll
total 8
-rw-r--r--1 zhengbingstaff0 10 13 15:54 LICENSE
-rw-r--r--1 zhengbingstaff0 10 16 22:50 china
-rw-r--r--1 zhengbingstaff0 10 17 01:03 dev.txt
-rw-r--r--1 zhengbingstaff0 10 16 22:50 no
-rw-r--r--1 zhengbingstaff0 10 16 22:50 one
-rw-r--r--1 zhengbingstaff203 10 19 11:29 readme.txt
-rw-r--r--1 zhengbingstaff0 10 14 01:15 test.txt
bogon:git zhengbing$ rmno
bogon:git zhengbing$ ll
total 8
-rw-r--r--1 zhengbingstaff0 10 13 15:54 LICENSE
-rw-r--r--1 zhengbingstaff0 10 16 22:50 china
-rw-r--r--1 zhengbingstaff0 10 17 01:03 dev.txt
-rw-r--r--1 zhengbingstaff0 10 16 22:50 one
-rw-r--r--1 zhengbingstaff203 10 19 11:29 readme.txt
-rw-r--r--1 zhengbingstaff0 10 14 01:15 test.txt
$ git status
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:nono changes added to commit (use "git add" and/or "git commit -a")
$ gitrm no
rm no
$ gitcommit -m delete no
[zhengbing_dev fc0536e] delete no
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 no
$ gitcheckoutmaster
Switched to branch master
Your branch is ahead of rigion/master by 5 commits.
(use "git push" to publish your local commits)
$ gitmergezhengbing_dev
Updating 4464110..fc0536e
Fast-forward
no | 0
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 no
bogon:git zhengbing$ git log --pretty=oneline
fc0536e853bc505d45375746a3df4d5fd4e2cfad (HEAD ->
master, zhengbing_dev) delete no
4464110564988026594dd4263d707c10577074da Merge branch zhengbing_dev
a2fb2cda5f71231c9c0dd3eea6c9d6b673121529 delete readme2.txt
e68db6ce2192645403c90a311c25cee52fcde1e7 resolvedfixed
c0264af950e75a512dc9895c9b3806c9ed4438ed &
simple
db758c4fd8de9f31e87bcb81787f7fd20db977b5 AMD simple
f8ba521f52ca2b4f6510ec3a35d7929fcde8d937 (rigion/master) add filedev.txt
801d6f066eecf1270920a361659dd61db3257457 add mutiplefiles
ceebf2660aa2eea2f6c4e96a78dd5be08f728f6c add file test.txt
65d43dc687b35173b2d312bf7b71eb7593bc88ca append of files
400bdba9be3de24fb6077ef573564b6998af5cc9 tracks files
e17c4d4d2d8d2893009f3e56e7711657055ef779 understand stage
7dc80a9b6475908835ab78562d7db68fda83757c appendGPL
56fb09bdfefc467e9b2f5aba2060c215c19f68c9 updatereadme.tct
9235ffdcced6c829b3f0fb991d5548c14fe49dc7 addreadme.txt
bogon:git zhengbing$ gitbranch-d zhengbing_dev
Deleted branch zhengbing_dev (was fc0536e).
bogon:git zhengbing$ git log --pretty=oneline
fc0536e853bc505d45375746a3df4d5fd4e2cfad (HEAD ->
master) delete no
4464110564988026594dd4263d707c10577074da Merge branch zhengbing_dev
a2fb2cda5f71231c9c0dd3eea6c9d6b673121529 delete readme2.txt
e68db6ce2192645403c90a311c25cee52fcde1e7 resolvedfixed
c0264af950e75a512dc9895c9b3806c9ed4438ed &
simple
db758c4fd8de9f31e87bcb81787f7fd20db977b5 AMD simple
f8ba521f52ca2b4f6510ec3a35d7929fcde8d937 (rigion/master) add filedev.txt
801d6f066eecf1270920a361659dd61db3257457 add mutiplefiles
ceebf2660aa2eea2f6c4e96a78dd5be08f728f6c add file test.txt
65d43dc687b35173b2d312bf7b71eb7593bc88ca append of files
400bdba9be3de24fb6077ef573564b6998af5cc9 tracks files
e17c4d4d2d8d2893009f3e56e7711657055ef779 understand stage
7dc80a9b6475908835ab78562d7db68fda83757c appendGPL
56fb09bdfefc467e9b2f5aba2060c215c19f68c9 updatereadme.tct
9235ffdcced6c829b3f0fb991d5548c14fe49dc7 addreadme.txt
很明显的对比就能看到,没有使用—no-ff的情况下删除被合并的分支后,被删除的分支没有留下任何痕迹
Bug分支考虑两个问题:
- 开发某个任务的途中,leader告诉你要修改一个线上的bug,这时开发的内容么有提交,也不能提交,咋办?
- bug修复完成之后,最先是提交到master分支了,那么如何将这次bug的提交同步到dev分支?
$ gitcheckout -bzhengbing_dev
Switched to a new branch zhengbing_dev
bogon:git zhengbing$ ll
total 8
-rw-r--r--1 zhengbingstaff0 10 13 15:54 LICENSE
-rw-r--r--1 zhengbingstaff0 10 16 22:50 china
-rw-r--r--1 zhengbingstaff0 10 17 01:03 dev.txt
-rw-r--r--1 zhengbingstaff0 10 16 22:50 one
-rw-r--r--1 zhengbingstaff203 10 19 11:29 readme.txt
-rw-r--r--1 zhengbingstaff0 10 14 01:15 test.txt
$ rm china one
$ gitstatus
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:china
deleted:oneno changes added to commit (use "git add" and/or "git commit -a")
$ gitstash
Saved working directory and index state WIP on zhengbing_dev: fc0536e delete no
$ gitstatus
On branch zhengbing_dev
nothing to commit, working tree clean
$ git checkout master
Switched to branch master
Your branch is ahead of rigion/master by 6 commits.
(use "git push" to publish your local commits)
$ git checkout-bissue-1024
Switched to a new branch issue-1024
$ vireadme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
Creating a new branch is quick AND simple.
fix bug-1024
$ git add readme.txt
$ gitcommit -mfixbug 1024
[issue-1024 70edc45] fixbug 1024
1 file changed, 1 insertion(+)
$ gitmerge -m fixbug1024 issue-1024
Updating fc0536e..70edc45
Fast-forward (no commit created;
-m option ignored)
readme.txt | 1 +
1 file changed, 1 insertion(+)
bogon:git zhengbing$ git branch -d issue-1024
Deleted branch issue-1024 (was 70edc45).
$ gitcheckout zhengbing_dev
Switched to branch zhengbing_dev
$ gitstatus
On branch zhengbing_dev
nothing to commit, working tree clean
$ gitstash list
stash@0: WIP on zhengbing_dev: fc0536e delete no
bogon:git zhengbing$ gitstashpop
Removing one
Removing china
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:china
deleted:oneno changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@0 (bb34ec868164fa0522c4037054524aa0abf7eade)
$ git stashlist
$ git status
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:china
deleted:oneno changes added to commit (use "git add" and/or "git commit -a")
恢复保留区有两种方式,
- git apply取出保留区的内容到工作区,但是不会删除stash中的内容
- git stashpop取出保留区的内容到工作区,并且同时删除取出的保留记录
第二个问题:bug修改完成之后的同步问题
因为dev分支是在修改bug之前拉取出来的,那么同样的在dev分支上也同时存在这个bug,那么,如何在不重复在dev分支上进行操作的情况下,将bug修复到dev分支上来呢?
git cherry-pick
git提供了git cherry-pick 可以将其他分支的某次修改同步到当前分支
$ gitbranch
master
* zhengbing_dev
$ gitstash
Saved working directory and index state WIP on zhengbing_dev: fc0536e delete no
$ gitstatus
On branch zhengbing_dev
nothing to commit, working tree clean
$ git checkout master
Switched to branch master
Your branch is ahead of rigion/master by 7 commits.
(use "git push" to publish your local commits)
$ git log --pretty=oneline
70edc45fc6118b1c9fbe1027b1160e0120468938 (HEAD ->
master) fixbug 1024
fc0536e853bc505d45375746a3df4d5fd4e2cfad (zhengbing_dev) delete no
4464110564988026594dd4263d707c10577074da Merge branch zhengbing_dev
...
$ git checkout zhengbing_dev
Switched to branch zhengbing_dev
$ git stash pop
Removing one
Removing china
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:china
deleted:oneno changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@0 (74a9941a154523548a542a729ffac95bb6ed4c88)
$ gitstashlist
$ gitcherry-pick 70edc45
[zhengbing_dev 515389b] fixbug 1024
Date: Sat Oct 19 18:11:57 2019 +0800
1 file changed, 1 insertion(+)
bogon:git zhengbing$ gitstatus
On branch zhengbing_dev
Changes not staged for commit:
(use "git add/rm <
file>
..." to update what will be committed)
(use "git checkout -- <
file>
..." to discard changes in working directory)deleted:china
deleted:oneno changes added to commit (use "git add" and/or "git commit -a")
$ vi readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
Creating a new branch is quick AND simple.
fix bug-1024
操作步骤:
- 将当前工作区保留到git
- 切换分支到master
- 找到修复bug的那次修改记录
- 切换分支到zhengbing_dev
- 将保留区的内容取出并删除保留区内容
- 使用 git cherry-pick 将master 上的修改记录同步过来
- 检查bug的内容是否已经同步过来
新功能开发分支当接到leader的任务要开发一个新功能时,最好不要在dev分支上进行开发,从dev分支上拉取一个新功能的分支来进行开发,因为dev分支会提供给多个开发人员并行开发,所以dev尽量不要让开发人员直接在上面做开发,只做合并,这样的话正常情况下我们只需要按要求在新功能分支上进行开发,完成后合并到dev分支,最后删除新功能分支就可以了,但是如果中途要取消这个分支的功能开发怎么处理呢?在合并前直接销毁就好了,即使合并之后也可以版本回退来取消新功能合并的修改记录,还原到之前的版本(这里不做赘述)
$ git checkout master
Switched to branch master
Your branch is ahead of rigion/master by 7 commits.
(use "git push" to publish your local commits)
$ git branch-d zhengbing_dev
error: The branch zhengbing_dev is not fully merged.
If you are sure you want to delete it, run git branch -D zhengbing_dev.
$ gitbranch -D zhengbing_dev
Deleted branch zhengbing_dev (was a2237c7).
销毁分支使用git branch -D 即可
多人协作(远程仓库操作)查看远程库信息
$ git remote
origion
显示更多详细信息
$ git remote -v
origion git@github.com:zhengbinger/learngit.git (fetch)
origion git@github.com:zhengbinger/learngit.git (push)
推送修改到远程仓库git push [远程分支名][本地分支名]
$ gitpush origion master
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 4 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (15/15), 1.26 KiB | 1.26 MiB/s, done.
Total 15 (delta 11), reused 0 (delta 0)
remote: Resolving deltas: 100% (11/11), completed with 2 local objects.
To github.com:zhengbinger/learngit.git
f8ba521..70edc45master ->
master
推送当前分支到远程仓库,并在远程仓库创建新的dev分支git pushorigion[要推送的分支名]:[远程分支名-自定义]
$ git push origion zhengbing_dev:dev
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 226 bytes | 226.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for dev on GitHub by visiting:
remote:https://github.com/zhengbinger/learngit/pull/new/dev
remote:
To github.com:zhengbinger/learngit.git
* [new branch]zhengbing_dev ->
dev
克隆远程分支到本地,默认情况下只会clone master 分支,克隆下来再进行切换就好
$ git clone git@github.com:zhengbinger/learngit.git
切换并新建dev分支,并且是从远程的dev分支拉取
$ gitcheckout -b dev origion/dev
Branch dev set up to track remote branch dev from origion.
Switched to a new branch dev
协同开发当自己的dev分支想要push之前有其他人在该分支上进行了修改,那么当前push是不会成功的。
那么要怎么做呢?
先把对方的修改拉取下来gitpull
那么如果对方的修改记录与当前的修改记录存在冲突呢?那git会让你拉取下来再进行手工处理冲突后进行提交处理
还有一种情况下是gitpull 无法都无法处理,就是当前本地版本与远程版本未建立连接的情况
使用命令可以为当前版本与远程版本建立连接git branch --set-upstream-to=origin/< branch> dev
Rebaserebase操作可以把本地未push的分叉提交历史整理成直线;
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比
rebase 其实主要功能就是对想在本地提交的历史记录进行整理,让你能够更清楚的去看版本或者分支的历史记录
git删除远程分支
git push origin:zhengbing_dev
推荐阅读
- #yyds干货盘点#剑指 Offer 61. 扑克牌中的顺子
- Android技术分享|自定义View实现Material Design的Loading效果
- HCL模拟器防火墙WEB方式登录配置
- 设计模式之策略模式
- AOP详解之三-创建AOP代理后记,创建AOP代理
- 平衡树(为什么Redis内部实现用跳跃表)
- linux下lvm逻辑卷配置
- 存储性能测试漫谈
- Kubeadm集群证书过期后的处理