git merge
Merging in Git creates a special commit that has two unique parents. A commit with two parents essentially means “I want to include all the work from this parent over here and this one over here, and the set of all their parents.”
比如我想将bugFix分支合并到master,模拟下图流程:
用文字来描述上图:
- I found some bugs on master (c1), so I create a new branch named “bugFix” and send Tom to handle it,
- I working on master, do something and commit it (c3).
- Tom fix the bugs and commit (c4)
- I merge Tom’s job to master.All the change has been merged.
通关命令:
git branch bugFix
git switch bugFix
git commit
git switch main
git commit
git merge bugFix
git rebase
比如创建了一个future分支,rebase到main之后,就看起来像你所有在future的commit一直写到了main一样。merge和rebase都可以用来合并分支,但是目前一般提倡使用rebase,因为这使得代码历史很清晰。
Rebasing essentially takes a set of commits, “copies” them, and plops them down somewhere else.
Head
First we have to talk about “HEAD”. HEAD is the symbolic name for the currently checked out commit – it’s essentially what commit you’re working on top of.
e.g. "main^ is equivalent to “the first parent of main”.
git checkout
用于切换branch,会更换work tree到指定版本。
比如我想切换回HEAD的上一个版本:
git checkout HEAD^
git branch -f
You can directly reassign a branch to a commit with the -f option. (branch本质就是指向某个commit的指针。)
git branch -f main HEAD~3
场景描述:
- 让bugFix分支回退到c0
- 让main分支指向c6
- 让HEAD指向c1
git branch -f bugFix HEAD~2
git branch -f main c6
git switch c1
Reversing Changes in Git
Git Reset
git reset reverts changes by moving a branch reference backwards in time to an older commit.
Git Revert
While resetting works great for local branches on your own machine, its method of “rewriting history” doesn’t work for remote branches that others are using.
远程仓库场景下,我们不可能在每台机器上使用Git Reset来回退。
比如使用Git Revert使得c2回退到c1,不像前面的Git Reset直接让分支指向父节点,Git Revert会产生一个新的commit,来逆转c2的commit:
new commit C2’ introduces changes – it just happens to introduce changes that exactly reverses the commit of C2.
场景描述:
- 让local分支(仅存在于本地)回退到上一次commit
- 让pushed分支(远程)回退到上一次commit
git reset HEAD^
git switch pushed
git revert HEAD
git cherry-pick
It’s a very straightforward way of saying that you would like to copy a series of commits below your current location (HEAD).
场景描述:把三个分支并入main。
首先想到的是merge,merge三个分支,结果如下:
看起来有些乱。使用git cherry-pick 试试:
git cherry-pick 仅仅对一些commit进行了复制。
git rebase -i
假如我要回退到c1,但是要保留c3和c4两个commit,那么应该使用git rebase -i,并通过git 弹出的文本编辑器选择保留c3和c4.
从结果中可以看到Git rebase到c1之后复制了c3和c4两个commit。还可以调整各个保留的commit的复制顺序。
比如bugFix分支有一些commit我仅仅希望有用的那个commit(真正修复了bug的那个commit)被合并到主分支,那么就可以使用rebase -i 命令。
git rebase -i HEAD~3
git switch main
git rebase bugFix
这样bug修复了,也没有包含一些debug、打印的commit进来。
以上已经包含了常用的Git命令,就到这了。