Quantcast
Channel: 簡睿隨筆
Viewing all articles
Browse latest Browse all 897

建立測試環境以git rebase -i變更Commit歷史

$
0
0

為了方便測試與簡化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改成 edite

▼ 「pick」是要被挑選到版本庫的Commit
rebase pick

▼ 把要變更的[c07f]改為edit操作,存檔並關閉編輯器
rebase 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

##

您可能也會有興趣的類似文章

The post 建立測試環境以git rebase -i變更Commit歷史 appeared first on 簡睿隨筆.


Viewing all articles
Browse latest Browse all 897

Trending Articles