為了方便測試與簡化Git指令操作,我們可以用alias來建立各式縮寫與指令擴充,也可以用批次檔自動產生檔案來快速測試。本文主要是測試git rebase
變更前面某個Commit內容的操作。
環境設定
編輯C:\Users\USERNAME.gitconfig或在cmd.exe執行下列指令;[core] editor是設定預設的編輯器,在此是使用GitExtensions的檔案編輯器。第一次接觸Windows Git,其實可以使用GitExtensions,透過它可以一併把msysGit和Kdiff3等必備工具都一次安裝起來,會比個別安裝簡便一些。
git config --global core.editor d:/util/GitExtensions/GitExtensions.exe fileeditor
再來設定命令的alias(代名),以節省輸入命令的時間。
git config --global alias.st status git config --global alias.l "log --abbrev-commit --abbrev=4 --pretty=format:\"%C(yellow)%h %C(green)[%cn] %C(cyan)%ar %C(bold magenta)%d %C(reset)%s\" -10"
快速加入、提交測試檔案
以下用來建立git-test.bat,建立好後將之存入PATH環境變數裡的資料夾,爾後就能用git-test 檔名1 [檔名2]...[檔名n]
來產生同名.html並加入與提交。
@echo off set MSG= for %%x in (%*) do call :CREATE %%x set MSG=%MSG:~1% git commit -m "%MSG%" goto END :CREATE echo %1 > %1.html git add %1.html set MSG=%MSG% %1 :END
另一個方法是使用Git的alias,直接編輯.gitconfig,加入下列alias到[alias]裡。此處的alias是Bash script,行末的反斜線是續行的連接符號。有些工具不認識反斜線,遇到出現錯誤時先將這些有反斜線的代名移除即可。
[alias] snapshot = "!snapshot() {\ COMMENT=wip;\ if [ \"$*\" ]; then\ COMMENT=\"$*\";\ fi;\ git add -A;\ git commit -m \"$COMMENT\";\ }; snapshot" create-file = "!createFile() {\ for name in \"$@\"; do \ echo $name>$name.txt; \ done; \ }; createFile" simple-commit = "!simpleCommit() {\ for name in \"$@\"; do \ git create-file \"$name\"; \ git snapshot $name; \ done; \ }; simpleCommit"
開始建立測試工作區
1.先將d:\git-root\test資料夾啟始為Git的工作目錄。
d:\git-root\test>git init
Initialized empty Git repository in d:/git-root/test/.git/
2.加入與提交index.html、page1.html、page2.html。以下使用git-test.bat來執行,若使用Git代名的話,將git-test
換成git simple-commit
即可。
d:\git-root\test>git-test index page1 page2
[master (root-commit) 575f6ba] index page1 page2
3 files changed, 3 insertions(+)
create mode 100644 index.html
create mode 100644 page1.html
create mode 100644 page2.html
3.加入與提交menu1.html、menu2.html
d:\git-root\test>git-test menu1 menu2
[master 4944913] menu1 menu2
2 files changed, 2 insertions(+)
create mode 100644 menu1.html
create mode 100644 menu2.html
4.加入與提交button1.html、button2.html、button3.html
d:\git-root\test>git-test button1 button2 button3
[master 5846174] button1 button2 button3
3 files changed, 3 insertions(+)
create mode 100644 button1.html
create mode 100644 button2.html
create mode 100644 button3.html
5.用git log查看一下最後的狀態
d:\git-root\test>git l
e393 [jerry] 2 seconds ago (HEAD, master) button1 button2 button3
c07f [jerry] 13 seconds ago menu1 menu2
8017 [jerry] 56 seconds ago index page1 page2
接著要執行改寫歷史的動作了。有時候在提交後,發現漏了檔案要放在同一個Commit裡,若馬上就發覺漏檔,則可以用git commit --amend
修正,但若過了好幾個Commit後才發覺要修正,此時只能用git rebase
來改寫歷史的Commit了。
任務:把新建立的menu3.html加回前面第二個Commit裡([c07f])
6.建立menu3.html
d:\git-root\test>echo menu3 > menu3.html
7.用git rebase -i 改寫對象的前一個Commit ID
操作
-i參數是指定使用交互式的介面來操作,Commit ID則是[c07f]的前一個,即[8017]:
d:\git-root\test>git rebase -i 8017
本例是變更第二個Commit,因此有前一個節點,但若要變更第一個節點時該如何指定「前一個Commit ID」呢?第一個節點是根節點([8017]),無法指定前一節點,此時使用git rebase -i --root
就可以了。
上述git rebase -i 8017
指令執行後會開啟設定好的編輯器,將[8017]之後的Commit都列出來,我們要變動的是[c07f]這個Commit,因此將其開頭的pick改成 edit 或 e。
▼ 「pick」是要被挑選到版本庫的Commit
▼ 把要變更的[c07f]改為edit操作,存檔並關閉編輯器
跳出編輯器後,Git依剛才編輯器裡的指示開始處理
Stopped at c07fdf7175edc9f31312bdeb04802f9bbfcb1d5d... menu1 menu2 You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue
8.用git status
查看一下執行rebase後的狀態。會看到rebase處理中的訊息。
d:\git-root\test>git st rebase in progress; onto 8017367 You are currently editing a commit while rebasing branch 'rebase1' on '8017367'. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes)
9.也用git log
查看一下執行rebase後的工作區記錄,此時HEAD移回要變 更的[c07f]了。
d:\git-root\test>git l
c07f [jerry] 76 minutes ago (HEAD) menu1 menu2
8017 [jerry] 77 minutes ago index page1 page2
10.接著把新建檔案menu3.html加入staging area,再用git commit –amend -m把變更存入本地版本庫。
d:\git-root\test>git add menu3.html d:\git-root\test>git commit --amend -m "menu1, menu2 and menu3" [detached HEAD e424d6c] menu1, menu2 and menu3 3 files changed, 3 insertions(+) create mode 100644 menu1.html create mode 100644 menu2.html create mode 100644 menu3.html
11.用git log
看一下工作區記錄,[c07f]節點已經被新節點[e424]取代了。
d:\git-root\test>git l
e424 [emisjerry] 2 hours ago (HEAD) menu1, menu2 and menu3
8017 [emisjerry] 2 hours ago index page1 page2
12.用git status
看一下狀態,rebase還沒結束,我們要以git rebase --continue
繼續做rebase操作。
d:\git-root\test>git st rebase in progress; onto 8017367 You are currently editing a commit while rebasing branch 'master' on '8017367'. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) d:\git-root\test>git rebase --continue Rebasing (2/2)
在看到幾個Rebasing後,終於成功結束了。
d:\git-root\test>git rebase --continue
Successfully rebased and updated refs/heads/master.
13.用git log
確認一下是否是預期中的結果。注意:示範button1 button2 button3這個Commit ID是[e393],也被新節點[4608]取代了。
d:\git-root\test>git l
4608 [jerry] 2 hours ago (HEAD, master) button1 button2 button3
e424 [jerry] 2 hours ago menu1, menu2 and menu3
8017 [jerry] 2 hours ago index page1 page2
git rebase過程中若有發生狀況,可以用git rebase --abort
放棄rebase操作。
Graph的變化
我們以Graph來看一下rebase的變化。
指令 | 執行後的圖形 |
---|---|
尚未執行rebase前 | |
執行git rebase -i 8017 後 |
|
執行git commit --amend -m 後 |
|
執行git rebase --continue 後 |
##
您可能也會有興趣的類似文章
- 為何無法正確執行git reset --hard HEAD^ (0則留言, 2014/09/20)
- 撰寫git info工具以模擬svn info功能 (0則留言, 2014/09/01)
- 將Git分支名稱加到提示字元(Prompt)裡 (0則留言, 2014/09/02)
- Subversion版本庫匯入Git的步驟與SVN整合步驟 (0則留言, 2014/10/03)
- Git的Staging Area的中文翻譯探討 (0則留言, 2014/09/12)
- Linus談Git與TortoiseGit (0則留言, 2008/12/19)
- 第一個jqGrid範例:Local array (1則留言, 2010/02/13)
- Nexus 7最推薦10大工作用Apps 十之八:文字編輯器-Jota+ Editor (0則留言, 2012/12/14)
- 第4個jqGrid範例: 資料列處理 (15則留言, 2010/02/14)
- [HTML&CSS] 鎖定左側功能選單,不隨頁面捲動 (0則留言, 2007/04/05)
- Galaxy S3的純文字編輯器:Jota Text Editor (0則留言, 2012/07/25)
- 第3個jqGrid範例: XML與XML STRING格式 (2則留言, 2010/02/14)
- 螢幕擷取工具:ScreenShot Captor新版下載 (0則留言, 2005/10/26)
- Android快速啟動器SwipePad、Smart Taskbar、GMD GestureControl評比 (0則留言, 2012/08/25)
- 三款「桌面便利貼」試用、剖析與建議 (3則留言, 2008/05/03)
The post 建立測試環境以git rebase -i變更Commit歷史 appeared first on 簡睿隨筆.