- 在平时开发中我们因为版本管理的因素,我们可能同时开发多个功能。我们是通过分支来管理的。不同的分支对应不同的功能不同的时间上线。
分支合并
git merge --squash [分支名]
-
git merge --squash 和 git merge是不同的。后者是直接将其他的提交记录合并进来。而前者是内容的合并。
-
这里的分支名可以是远程的也可以是本地的分支
- origin dev : 远程dev
- dev : 本地dev
-
现在我们dev分支上开发了某个功能。并提交至远程仓库中。我们现在打算合入master分支中。
-
dev 和 master 两个分支已经很久没有合并了。此时合并可能会有冲突
-
dev代码提交远程
- 现在我们在另外一台机器上进行远程分支合并请求
- 执行完squash我们看到有两个文件冲突。我们需要解决冲突。我们通过
git status
也可以看到这两个文件冲突both modified
- 解决冲突也很方便,我们只需要去认为分析两个文件内容取舍问题,然后进行重新提交就行了。比如说现在分析20190423trace.txt文件
- 加入我们认为dev提交过来的只有hello zfxx是有效的。那么我们留下他就行了。
- 然后一系列提交推送就行了
- 提交完之后我们先看看master上日志记录
- 然后看看另外一台机器的dev提交记录
-
我们发现dev提交的test甚至之前的commit并没有在master里面。这就是squash与merge的不同之处了
-
squash是将其他分支内容合并和重新进行一次提交封装。这样方便我们对主分支的管理。dev分支开发可能会随心所欲的进行提交已经对提交日志的细小记录。但是对于主分支根本不关心这些或者需要进行一些提交信息的规则定义。这时候我们可以squash先合并内容然后在重新一次性提交
注意点
- squash 后当前分支执行git status 会看到合并过来的文件在暂存区中我们需要commit 、 push 到远程
git rebase [分支名]
- 我们先基于master分支切除一个名为rebase_dev分支
-
此时rebase_dev 和 master是完全一样的。
-
现在我们在rebase_dev 分支上修改一个文件并commit。我们在看看commit log如何
- 我们的rebase_dev分支的head节点已经走到了054de46这个commit了。这个commit就是我们刚才提交的commit
- 8ad6924这个commit 后面括号内容表示是基于远程master、远程head、本地master为基点的。这也能说明现在本地master和远程master一致。且远程master在最新节点上。
- 此时我们在本地master提交内容并进行推送再看看log
-
这个时候master和rebase_dev两个分支分别向前推进了2步。
-
我们先来整理下master推进了两个commit. rebase_dev推进了两个分支
git rebase
- git rebase 命令实际上是将rebase_dev分支缓存到.git/rebase目录下
- 然后将rebase_dev基点即8ad6924移动到当前master的head节点。
- 然后将.git/rebase文件中的两个commit分别更新到rebase_dev上。所以这里涉及到更新是会发生冲突。我们上面rebase_dev推进了两个commit就会进行两次更新。如果遇到冲突git rebase就会停止操作。
- 我们此时需要解决冲突并将文件重新加入缓存区git add [文件名].
- 然后执行git rebase --continue
git rebase --abort
-
在上面我们何如了第一个commit后,突然不想rebase此次操作了。我们可以git rebase --abort停止。此时当前分支回到rebase之前状态。即基点在8ad6924。且自己的两个commit还在。
-
现在我们执行在rebase_dev分支上执行git rebase master 后看看效果
-
图中大意是重新设置基点,并将存储在./git/rebase中的patch进行添加到当前分支上。
-
首先合并第一个commit patch, 里面涉及改动了trace.txt。我们有三种方式进行合并。git自动已经帮我们合并了,就是我们常见的冲突形式。我们也可以通过
git am --show-current-patch
查看冲突细节。当我们已经认定解决冲突后我们git add 重新添加或者git rm删除文件。然后执行git rebase --continue
进行放行至下一个commit。或者执行git rebase --skip
跳过当前的commit.实际上就是丢弃该commit。或者执行git rebase --abort
停止当前rebase回到之前状态
- skip之后我们看到applying rebase V2 ,说明开始何如第二个patch 即commit了。此时也出现了冲突。这个时候第一个commit已经被我们抛弃了。不会对我们产生影响的。
-
我们执行
git rebase --abort
停止了当前的基点改变。我们查看源文件发现没有冲突也没有被主分支内容改动。 -
下面我们git rebase master将内容合并进来。
- 我们一顿操作下来最后提示我们合并成功了。只是我在处理合并的时候将自动合并信息留下来了。我们看看最终的文件
- 我们查看log发现。master日志在rebase_dev之前。且rebase_dev两个commit id发生了变化。这也说明我们基点移动到master上且rebase_dev的commmit是重新添加到rebase_dev分支上的。
git rebase -i
- 这个时候我看了rebase_dev和master的四个commit 有点不顺眼,我们也可以把这四个commit合并。
- 执行
git rebase -i HEAD~4
- 弹出的窗口我们可以发现前四行使我们的commit倒叙排列的。下面也有关于参数的解释,将该四个commit合并到最后一个commit上。及702de33 。
看看常用的两个。后面的我也不明白后面再补补吧
|缩写|关键字|作用|
|---|---|---|
|p|pick|use commit 使用该提交,如上所示四个都pick,即没有合并|
|r|reword|使用该commit,但是从新编写提交信息|
- 我们发现四条commit合并成一条了。这样有利于我们对commit提交信息的管理。
git merge [分支名]
- git merge 到这里其实已经没啥好说的。上面的对比已经梳理完毕了。主要和git rebase的区别。git merge 适合主分支操作。