2019 iT 邦幫忙鐵人賽

DAY 29

Day twenty-nine

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

Hello everyone. It's Ray.

Yesterday I introduced git rebase, the great magician who is good at manipulating history.
昨天跟大家分享了git rebase,偉大的歷史操縱魔術師~

Today I'm going to share the true power of this magician.

Let me give an example:

Hypothetically, I've completed our meat function branch. However, Alas, we used git log --oneline to check the history and suddenly doubted whether I could use git due to the mess of it.
假設今天,我在功能的分支上完成一個功能了,但git log --oneline回首一看,我的媽媽咪啊!! 歷史紀錄亂到讓我有點懷疑我自己會不會用git了...

In this case, we could use git rebase -i to re-organize the history.
這時候我們就可以利用git rebase -i來重新編輯我們的歷史。

Currently the git looks like the image below

We are going to add some wrong commit on meat branch, and assume that this function is completed.
現在我們將在meat branch上增加一些錯的commit,並假設這個分支上的功能已經完善。

touch smallFunction1
touch smallFunction2
git add *
git commit -m 'small function 1 and 2 completed'
touch smallFunction3
git add *
git commit -m 'small function 3 completed'
git log --oneline

Currently the history of meat branch should look like image below:
目前meat branch的log看起來應該如下:

I highly recommand that we should make a commit based on a small function.

When we commit, if you can't even think of a description, then it might mean that it doens't require a commit yet.

If you find that the description not only contains a singgle event, then which might mean that this commit is a bit too big. Maybe we could break it into smaller parts.

Let's take a look on this case with the concept I just mentioned. It seems like it would be better to break 'small function 1 and 2 completed' into two commits.
以上面的例子來看,較好的commit模式應該是要把'small function 1 and 2 completed' 拆分成兩個commit。

Watch it! We are going to do it.

git rebase -i master

You would see a window as image below:

Firstly, let's seperate this window into two parts.

The image above shows the commits we are going to rebase this time.

pick represents one of the options that we could use on each commit. With git rebase -i, we could change the history with different options according to what we want.
pick代表的是操作選項之一,代表將在此次rebase中應用在這個commit的選項。而在git rebase -i的過程中,我們可以任意地依照我們的需求是改變我們的歷史。

Let's take a look on the other part as follows:

Image above make explanations to each option.

In this case, we need 'edit' option, which allows us to revise or even add new commit during the progress of rebasing. Let's choose edit on specific commit as follows:
在我們的例子中,我們會需要使用 edit 操作選項,它可以讓我們在rebase的過程中針對該commit的點去做修改以及甚至新增,讓我們使用edit 選項,如下圖:

And then:


  • :wq save and leave.
  • git reset HEAD^ --mixed go one commit backwards but keep the content
  • git status we could see that the files 'smallFunction1' and 'smallFunction2' that we had committed became untracked again.
  • git add smallFunction1 git commit -m 'small function 1 completed' make a commit for 'smallFunction1'
  • git add smallFunction2 git commit -m 'small function 2 completed' make a commit for 'smallFunction2'
  • git log --oneline


  • :wq 儲存離開
  • git reset HEAD^ --mixed 往前退一個commit,並且保留工作資料夾中的內容
  • git status 可以看到原本已經commit的檔案'smallFunction1'以及'smallFunction2'又重新出現在追蹤清單中了。
  • git add smallFunction1 git commit -m 'small function 1 completed' 特別針對'smallFunction1'建立一個commit
  • git add smallFunction2 git commit -m 'small function 2 completed' 特別針對'smallFunction2'建立一個commit
  • git log --oneline

As photo above, we've successfully revised the history. We broke the commit 'small function 1 and 2 completed' into two commits 'small function 1 completed' and 'small function 2 completed'. Now we could checkout to master and merge this feature branch.
由上圖可以看到,我們已經成功修改了歷史,為'smallFunction1'以及'smallFunction2'分別建立了commit,這下我們可以放心地讓master branch來merge這個功能分支了!

Some command we mentioned above like git reset HEAD^ --mixed might not be mentioned in my previous article, I will probaby introduce it in my later module.
上面有一些指令例如git reset HEAD^ --mixed可能之前的文章裡面並沒有提到,之後若有機會會再跟各位作介紹。

Isn't git rebase -i so amazing?
git rebase -i是不是很神奇呢?

See you guys tomorrow.

操縱歷史的魔術師- git rebase
雖然人生不能重來,但是git可以。讓我們回到過去-`git reflog`
Experience of a backend novice30