2019 iT 邦幫忙鐵人賽

DAY 28

Day twenty-eight

操縱歷史的魔術師-git rebase
Who is manipulating the history-git rebase

Hello everyone. It's Ray.

Today I'm going to introduce git rebase, the magician of manipulating the history.
今天要來跟大家介紹操縱git歷史的魔術師-git rebase!

When would we use this function?

Let me give an example.

Hypothetically speaking, we created a branch for a new function, and before the new function was completed, we were informed of a bug on master branch. It's not quite possible to wait for the new function being completed before disposing of this bug, so we switched to master branch, and fix the bug and create a new commit for that.
假如今天我們開了一個分支來發展一個新功能,而在這個新功能完成之前,我們臨時被通知master branch上有bug,所以我們趕緊切換到master brnach上,並且趕緊把bug解掉,並新增了一個commit。

In this case, the new function we were developing also has this bug, and we are afraid that this bug might have some unknown effect on this function, so we would like the new function also possess the commit of debugging. We could use git rebase to move the this function branch to be on top of the commit we just made on master branch.
這個時候呢,我們原本開的功能分支上也有著這個bug,而我們害怕這個bug會對我們的功能造成未知的影響,所以我們想要讓我們的分支也有修掉bug的這個commit。這個時候我們就可以使用git rebase來將我們這個功能分支的起點,移動到master 分支上最新的commit上。

Let's grok it by hand-on work.

If you've been following along our module, on meat branch, the history should look like the image below:
如同你有從之前的文章照著我們的進度走,從meat branch的視角來看,目前我們的歷史是這樣的。

Through the image above, we could see that master branch is pointing to the commit 9b256ac, and it's also one of meat brnach's parent's commits.
由上圖可以看到,master branch目前正指向9b256ac這個commit,而這個commit也是meat branch的父commit之一。

Now we are going to switch to master branch, and make a new commit, and switch back to meat branch and rebase to the commit we are about to make on master branch.
現在我們將切換到master branch,並且做新的commit,然後再切換到meat branch上去rebase到master branch上我們新commit的點。

git checkout master
touch debug.html
git add *
git commit -m 'debug'
git log --oneline

As image below, the log of master branch looks like that:

Let's go back to meat branch and rebase to the commit we just made.
現在我們回到meat branch,然後將我們原本從master上一個commit上的起點挪到master新的commit點。

git checkout meat
git log --oneline

As photo below you could see that master occurring in log above was gone, becauae now the master branch is pointing to the new commit, and this being-pointed commit doesn't exist in meat branch's history.

git rebase master

Oops! as photo below, we came across a conflict

By default setting,git rebase would replay all of its commits on designated new commit, so where should be merged would be merged again, and where a conflict occurred would occur again, so we need to resolve it again.
'git rebase'預設會被所有的commit,整個在新的指定的commit點上重新跑一次,所以原本該merge的地方會重新merge,而原本會衝突的地方會再發生衝突,所以我們必須要重新解衝一次。

As what we resolve it previously, we keep what we want and remove the rest as followings:

And then

git add *
git rebase --continue
git log --oneline

As photo above, we've successfully rebased meat branch to the debug commit of master branch's, so now meat branch should possess all of the commits on master branch including the debug commit we just made.
如上圖,我們已經成功地將meat branch的起點移到了master branch的debug commit上,所以此時的meat分支會擁有master branch上所有的commit,包含我們剛新增的debug commit。


Through the image above, the debug commit appeared on meat branch.
由上圖中我們可以看到,debug已經出現在meat branch上。

Is it amazing? Actually it hasn't shown its true power.
git rebase是不是很神奇呢? 其實他真正神奇的地方還沒出現。

See you guys tomorrow.

操縱歷史的魔術師 part 2
Experience of a backend novice30