人總會有犯錯的時候,值得感激的是Git容許你在任什麼時候候反悔,而且將對應信息從歷史記錄中抹除,這樣的歷史記錄每每看起來行雲流水,使人賞心悅目,嚴謹的提交信息是對他人的一種尊重。git
git commit --amend
若是你想改變上一個commit的提交信息與文件內容,便可使用--amend命令,它容許你將暫存區的修改合併到上一個commit,從而生成一個新的commit,您也能夠僅適用它來修改commit message。shell
須要注意的是,若是已經將commit到遠程庫,不建議使用ammend命令,由於這樣會修改掉最近一次commit的hash值,只能強制推送才能push上去,若是你的commit已經同步到了其餘倉庫或別人已經拉取以前的提交,這樣強推上去就會產生衝突。this
git revert [<commit>]
若當某一次的提交內容致使一些錯誤發生,一般會進行還原操做,此時revert就派上用場了,它會生成一條新的commit,將指定的commit中包含的更改進行還原。3d
revert是一個十分禮貌的命令,對於多人協做的項目來說,是十分有用的,由於它會保持HEAD指針在不斷的前進,不會產生意想不到的衝突。指針
git rebase -i [<start_commit>] [<end_commit>]
在推送到遠程分以前,爲了保持邏輯清晰可回溯步驟,咱們須要會進行許多個小的提交,而到推送到遠程庫的時候,更但願將其彙總爲一個feat提交,這時命令就派上了用場。rest
首先咱們來初始化一個git倉庫:code
mkdir gittest && cd gittest && git init touch a && git add * && git commit -m 'a' touch b && git add * && git commit -m 'b' touch c && git add * && git commit -m 'c' touch d && git add * && git commit -m 'd'
這時執行git log
可獲取到如下信息:排序
commit b9843274e87455a87b16802ebb2b48cf8cb67175 (HEAD -> master) d commit dc681aadc81491c3d2b2cb2f8ca1d66586f65903 c commit db9dc842b6c854b7175c03c7fd50bf08a262cfcb b commit 3bc7dbe4ddfad85606e6dd39c6583d8fa7b353b7 a
爲了將b、c合成爲一個提交,咱們須要選取最近3個提交進行才行,須要注意的是指定兩個commit範圍時區間爲前開後閉區間(]
,若是省略第二個end_commit則會指向HEAD指針,所以如下三個命令是等效的:索引
git rebase -i HEAD~3
git rebase -i 3bc7dbe4ddfad85606e6dd39c6583d8fa7b353b7
git rebase -i 3bc7dbe4ddfad85606e6dd39c6583d8fa7b353b7 b9843274e87455a87b16802ebb2b48cf8cb67175
這時會彈出一個交互界面:rem
pick 3a13544 b pick 3b3d704 c pick 9205e1b d # Rebase 97b2217..9205e1b onto 97b2217 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
註釋裏已經包含了一切你須要知道的信息,在這裏仍是簡單的描述下:
a -> c -> b -> d
命令有如下不一樣的模式:
在選取範圍時,咱們每每會指定一個start_commit,那麼若是commit爲第一個提交呢?由於命令爲前開區間,這時候就沒法選取了,只能經過--root指定:git rebase -i --root
。
以上命令儘可能都本身嘗試一遍。
git reset [<mode>] [<commit>]
首先應該理清HEAD、暫存區、工做區三者的關係再去使用reset
命令。使用reset回退版本一般是經過移動HEAD指針的指向來實現的,HEAD是當前分支引用的指針,它老是指向該分支上的最後一次提交。當HEAD指針發生變化時,有幾種模式能夠選擇:
--soft
,暫存區與工做區都不會重置,只會重置掉提交。此模式不改變暫存區與工做區的文件內容,僅僅是將HEAD指針位置邊了,這樣全部在reset指定的提交以後的提交都會被撤銷,文件更改集中放在了暫存區。--mixed
,重置暫存區,但不會重置工做區。reset會用HEAD指向的快照去更新暫存區的內容,只保留工做區的文件,簡單的說,回到了git add
以前。--hard
,同時重置暫存區和工做區。它會完全棄用以後的提交,且不可撤銷。文章只是涉及一些淺顯的用法,但願在玩轉重寫Git時,您也應該掌握:
git reflog
隨時對進行的操做進行撤銷。以上只是拋磚引玉,最重要的是能知道本身在作什麼,清楚操做帶來的影響。