git merge用于将一个分支(branch)的修改应用到另一个分支(branch)上。git merge包含两种类型:fast-forward和no-fast-forward。
当目标分支(branch)相对于源分支(branch)没有额外的修改时,git不会创建额外的commit,直接进行merge。
当目标分支(branch)相对于源分支(branch)都有修改时,git会在目标分支(branch)上创建新的merging commit。
git能够解决一部分合并冲突的问题,但当我们想要合并的两个分支(branch)的同一文件中的同一行代码上有不同的修改,或者一个分支删除了一个文件而另一个分支修改了这个文件时,git就不知所措了。
如下图所示,我们同时修改了README.md文件的同一行:
git在merge时,会告知冲突位置以及冲突的内容。这时候需要手动解决冲突,并手动提交commit。
git rebase拷贝当前分支的提交,然后将这些提交放在目标分支的顶部。
Interactive Rebase允许我们在rebase过程中对commit内容进行一些修改。
reword: Change the commit message
edit: Amend this commit
squash: Meld commit into the previous commit
fixup: Meld commit into the previous commit, without keeping the commit's log message
exec: Run a command on each commit we want to rebase
drop: Remove the commit
移除一个commit:
合并两个commit:
当我们想丢掉之前提交的修改内容时,就可以使用git reset。
Soft Reset将HEAD移至指定的commit,但不会移除该commit之后加入的修改。
3.2 Hard Reset
Hard Reset除了将HEAD移动到指定的commit外,还重置了该commit之后的所有修改,包括暂存区和工作区的所有修改。
另一种回退commit的方法是使用git revert。git revert创建了一个新的commit,该commit包含了reverted changes。
如下所示,在commit ec5be增加了一个index.js文件,然后我们想要回退该Commit:
cherry-pick将其它分支(branch)的某个commit拿过来,合并到当前分支(branch)。
比如我们在dev分支修改了index.js文件,增加了一个commit 76d12,我们需要这个commit应用到master分支:
git fetch从远程分支拉取数据,但不修改本地的状态。
git pull相当于git fetch + git merge。
git reflog是一个非常有用的命令,可以展示已经执行过的所有动作的日志,括合并、重置、还原,基本上包含你对你的分支所做的任何修改。通过它几乎可以还原你所做的所有修改。
假设我们要回退分支merge操作。当我们执行git reflog命令时,我们可以看到当前repo的状态在合并前位于HEAD@{1}。我们就执行一次git reset,将HEAD重新指向在HEAD@{1}的位置,就可以实现回退merge的功能了。