git分支管理

Git分支功能

Git的主要分为主分支master,开发分支develop(dev),辅助分支dev-*,release-*,hotfix-*

  • 主分支(master)
    作用:开发者可以从主分支上发布新版本,也可以获得线上代码
  • 开发分支(develop)
    作用:开发者将自己的分支首先合并到开发分枝上,也可以从开发分枝上获得最新开发的代码
  • 辅助分支(dev-*,release-*,hotfix-*)
    作用:
Feature branches:“管理功能开发”的分支,命名以`dev-`开头,用于开发版本新功能,完成后合并至develop分支
Release branches:“帮助构建可发布代码”的分支,命名以`release-`开头,从develop上面拉取,用于与发布新版本和修复预发布版本bug,完成后分别合并至master和develop分支
Hotfix branches:“便捷修复发布版本Bug分支”,命名以`hotfix-`开头,从master分支上拉取,用于快速修复线上Bug,完成后分别合并至master和develop分支

分支产生的原因:
1.需要开发这对一个项目进行并行开发
2.修复旧版本中的bug


git分支管理_第1张图片
4.jpg

就像上面的AB,就创建了各自的分支,别人看不到,还可以在原来的分支上面继续工作,等到最后可以合并在一起,即安全,又高效。


git分支管理_第2张图片
5.jpg

创建合并分支

  • 每次提交,Git都会把它们串成一条时间线,这个时间线就是一个分支,每个都会有一个master分支,叫做主分支,默认HEAD开始指向主分支,Git用master指向最新的提交

    git分支管理_第3张图片
    6.jpg

  • 当我们创建新的分支时,比如dev,Git就新建了一个指针dev,指向master相同的提交,再把HEAD指向dev,就表示当前分值在dev

    git分支管理_第4张图片
    7.jpg

  • Git创建一个分支很快,新增一个dev指针,在改变HEAD指向即可,工作区的文件没有变化
    但是从切换分支开始,对工作区的修改和提交就针对dev分支了,每次新的提交,dev就向前移动一次,master指针不移动

    git分支管理_第5张图片
    8.jpg

  • dev分支的工作完成之后想要和master分支合并,只需要把master指针,指向当前dev的提交即可,这样就完成了合并

    git分支管理_第6张图片
    9.jpg

  • 合并分之后,也可以删除dev分支。删除dev分支,就是删除dev指针

    git分支管理_第7张图片
    10.jpg

命令
创建分支:git branch
切换分支:git checkout
查看分支:git branch
创建+切换分支:git checkout -b
合并某分支到当前分支:git merge
删除分支:git checkout -d

eg:
1.创建dev分支,并切换到dev分支

》 git branch dev 创建分支
> git checkout dev 切换到dev分支
或者
> git checkout -b dev 创建并合并分支

2.git branch列出所有分支,Git版本库中总是存在着唯一一个活动分支,用星号(*)标记的就是当前活跃的分支

> git branch
 * dev
   master

3.在dev分支下修改文件file1并提交修改,切换回master分支,你会发现file1文件并没有做任何修改

> git branch 查看目前位于哪个分支(此时为master分支)
  dev
* master
> cat file1 查看master分支下file1文件内容
hello world!
> git checkout dev 切换到dev分支
Switched to branch 'dev'
> echo "I love china" >> file1 修改文件file1(这是追加了一句)
> git add file1
> git commit -m "I love china" 提交修改
[dev b8a482b] I love china
 1 file changed, 1 insertion(+)
> git checkout master 再次切换到master分支
Switched to branch 'master'
> cat file1 查看file1内容,你会发现内容没有改变
hello world!

4.dev分支工作结果可以合并到master分支上了

  • 切换分支错误
    切换分支可能会失败,这是因为我们当前分支工作区、暂存区存在一些修改,并且没有确认提交
> git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        file1
Please, commit your changes or stash them before you can switch branches.
Aborting

解决方法:

1.提交修改后切换
> git commit --all
> git checkout master
2.放弃这部分修改并切换
> git checkout --force master
--force强制切换
  • git merge 合并分支
>  git merge dev
Updating 9c4b701..614031d
Fast-forward
 hello.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

上面信息中有一个Fast-forward,意思是此次合并是“快进模式”。就是把master指针指向dev分值的当前提交,所以合并非常快,Git默认是这种提交模式
5.git branch -d 删除分支

git branch -d dev
Deleted branch dev (was ed7a0b9).
> git branch 只剩下master分支
* master

分支冲突:

编辑冲突:
我们可能会多个人在不同分支上对同一个文件的同一处做不同修改,这时Git不知道采用哪一个,就会出错误
树木冲突:
一个分支修改了内容, 另个一分支删除了文件, 在试图合并时就会出现树冲突。假设子分支(如 dev)是要合并到主分支 master 的, 处理的方法有:
(1)放弃 dev 的修改:强制删除 dev 分支, 然后提交即可。
(2)放弃 master 的修改----分下面两种情况:

    master 修改了内容, dev 删除了文件:
            在 master 分支中删除该文件, 然后提交;
    master 删除了文件, dev 修改了内容:                                         在 master 分支中添加被修改的文件, 然后提交。

eg:编辑冲突
创建新的分支branch2,修改文件file1,

> git checkout -b branch2
> echo "my name is ymd" >> file1

在分支branch2上提交修改

> git add file1
> git commit -m "branch2 commit"

切换到master分支,之后修改文件file1并提交

> git checkout master 
> echo "my name is xiaoyin" >> file1
> git add file1
> git commit -m "master file1"

这时,master分支和branch2分支都有一次提交
合并分支

> git merge branch2
Auto-merging file1
CONFLICT (content): Merge conflict in file1
Automatic merge failed; fix conflicts and then commit the result.

现在,Git不能执行“快速合并”,只能试着把各自的修改合并起来,但是这种合并往往会产生冲突

  • 解决编辑冲突:
    为了方便查看冲突我们可以将git配置成三路模式
> git config merge.conflictstyle diff3

1.启动合并工具

> git mergetool 

或者手动合并

a:编辑受影响的文件
b:采用--ours或者--theirs选项,选择只选用自己或者别人那个版本的文件
> git checkout --theirs 

2.提交修改

> git add .
> git commit -m ""

当然我们也可以取消合并

> git reset --merge
  • --no-ff合并时禁用Fast forward模式
    通常git在合并分支采用的是Fast forward模式,就是合并之后删除分支,会丢掉分支信息,如果强制禁止了Fast forward模式,Git就会在合并时生成一个新的commit,使得我们能在分支历史上看出分支信息。
# git merge --no-ff -m "no-ff" dev

在实际应用中,master分支应该是非常那个稳定的,只用来发布新版本,平时不能在上面工作,需要另选一个分支,比如dev,就是大家合并版本到dev分支上,只有新版本发布时,再把最新版本从dev合并到master分支上
开发一个新功能最好创建一个新分支

  • 编辑冲突
# git merge brnach2
fatal: brnach2 - not something we can merge
  • git checkout -D 强制删除一个从未合并过的分支

变基Rebase

  • 避免钻石链
    git分支管理_第8张图片
    11.jpg

如上图所示,一个项目会多个开发者多次提交,这样就存在许多杂乱的分支,Git用rebase命令帮我们理顺这些历史记录,篡改历史记录

git分支管理_第9张图片
12.jpg

所有rebase操作对象都是commit,但是未push到公共仓库,变基后在没有gc时,还可以通过原来的散列值访问原来的分支

# git rebase master 
  • 移值分支
    移值不属于原分支的版本
    前期:
    git分支管理_第10张图片
    13.jpg

移植后:git rebase master --onto relase1


git分支管理_第11张图片
14.jpg
# git checkout dev切换到待移动分支
# git log master..dev

或者直接在原分支上查看

# git checkout master
# git log HEAD..dev显示在dev上而不在当前分支的提交
# git rebase master --onto relase1
rebase命令的第一个参数所指定的是原分支(这里是master分支),然后,Git会确认dev上面所有不属于原分支的提交(这里是E和F),最后通过--onto选项将这些提交拷贝到指定位置上(这里是release1分支)

一次完整的移植合并分支:
1.原本的分支:

git分支管理_第12张图片
15.jpg

2.现在我需要将client分支上做的改变而非server上面的改变(A8和A9),直接在master分支中重演一遍

# git rebase --onto master server client
取出client分支,找出client分支和server分支共同祖先之后的变化,然后把他们在master上面重放一遍(server和client这两个分支修改的应该是不同的文件)
git分支管理_第13张图片
16.jpg

3.快进master分支:

# git checkout master
# git merge client
git分支管理_第14张图片
17.jpg

4.现在把server分支的变化也包含进来。我们可以直接把server分支变基到master分支
git rebase <主分支> <特性分支>
先取出特性分支,比如server,再到主分支master上重演

# git rebase master server

所以,server分支的进度应用到master基础上,如下图所示:


git分支管理_第15张图片
18.jpg

5.快进主干分支:

# git checkout master
# git merge server

6.删掉client和server分支

# git branch -d clien
# git branch -d server

7.最后的提交历史


git分支管理_第16张图片
19.jpg
  • rebase冲突解决
    rebase命令和merge命令一样会在相关修改不匹配的时候发生冲突
    1.手动解决或者通过合并工具解决,将他们从新添加至暂存区
    然后执行rebase命令,加上--continue选项,从该点继续之前的进程
# git add file1
# git add file2
# git rebase --continue

2.选项--abort选项取消这次rebase命令
3.选项--skip选项跳过引起这次冲突的提交

你可能感兴趣的:(git分支管理)