怎么去除網址(怎樣去除圖片上的網址)
650
2022-05-30
title: Git工具-重寫歷史 date: 2020-11-18 17:43:57 permalink: /pages/1832fe/ categories: - 《Git》學習筆記 tags: -
Git 工具 - 重寫歷史
許多時候,在使用 Git 時,你可能想要修訂提交歷史。 Git 很棒的一點是它允許你在最后時刻做決定。 你可以在將暫存區內容提交前決定哪些文件進入提交,可以通過 git stash 來決定不與某些內容工作, 也可以重寫已經發生的提交就像它們以另一種方式發生的一樣。 這可能涉及改變提交的順序,改變提交中的信息或修改文件,將提交壓縮或是拆分, 或完全地移除提交——在將你的工作成果與他人共享之前。
在本節中,你可以學到如何完成這些工作,這樣在與他人分享你的工作成果時你的提交歷史將如你所愿地展示出來。
修改最后一次提交
修改你最近一次提交可能是所有修改歷史提交的操作中最常見的一個。 對于你的最近一次提交,你往往想做兩件事情:簡單地修改提交信息, 或者通過添加、移除或修改文件來更改提交實際的內容。
修改提交信息
如果,你只是想修改最近一次提交的提交信息,那么很簡單:
$ git commit --amend
上面這條命令會將最后一次的提交信息載入到編輯器中供你修改。 當保存并關閉編輯器后,編輯器會將更新后的提交信息寫入新提交中,它會成為新的最后一次提交。
修改實際內容
另一方面,如果你想要修改最后一次提交的實際內容,那么流程很相似:首先作出你想要補上的修改, 暫存它們,然后用 git commit --amend 以新的改進后的提交來 替換 掉舊有的最后一次提交,
使用這個技巧的時候需要小心,因為修正會改變提交的 SHA-1 校驗和。 它類似于一個小的變基——如果已經推送了最后一次提交就不要修正它。
修改多個提交信息
為了修改在提交歷史中較遠的提交,必須使用更復雜的工具。 Git 沒有一個改變歷史工具,但是可以使用變基工具來變基一系列提交,基于它們原來的 HEAD 而不是將其移動到另一個新的上面。 通過交互式變基工具,可以在任何想要修改的提交后停止,然后修改信息、添加文件或做任何想做的事情。 可以通過給 git rebase 增加 -i 選項來交互式地運行變基。 必須指定想要重寫多久遠的歷史,這可以通過告訴命令將要變基到的提交來做到。
例如,如果想要修改最近三次提交信息,或者那組提交中的任意一個提交信息, 將想要修改的最近一次提交的父提交作為參數傳遞給 git rebase -i 命令,即 HEAD~2^ 或 HEAD~3。 記住 ~3 可能比較容易,因為你正嘗試修改最后三次提交;但是注意實際上指定了以前的四次提交,即想要修改提交的父提交:
$ git rebase -i HEAD~3
再次記住這是一個變基命令——在 HEAD~3..HEAD 范圍內的每一個修改了提交信息的提交及其 所有后裔 都會被重寫。 不要涉及任何已經推送到中央服務器的提交——這樣做會產生一次變更的兩個版本,因而使他人困惑。
運行這個命令會在文本編輯器上給你一個提交的列表,看起來像下面這樣:
pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file # Rebase 710f0f8..a5f4a0d onto 710f0f8 # # Commands: # p, pick
需要重點注意的是相對于正常使用的 log 命令,這些提交顯示的順序是相反的。 運行一次 log 命令,會看到類似這樣的東西:
$ git log --pretty=format:"%h %s" HEAD~3..HEAD a5f4a0d added cat-file 310154e updated README formatting and added blame f7f3f6d changed my name a bit
注意其中的反序顯示。 交互式變基給你一個它將會運行的腳本。 它將會從你在命令行中指定的提交(HEAD~3)開始,從上到下的依次重演每一個提交引入的修改。 它將最舊的而不是最新的列在上面,因為那會是第一個將要重演的。
你需要修改腳本來讓它停留在你想修改的變更上。 要達到這個目的,你只要將你想修改的每一次提交前面的 ‘pick’ 改為 ‘edit’。 例如,只想修改第三次提交信息,可以像下面這樣修改文件:
edit f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file
當保存并退出編輯器時,Git 將你帶回到列表中的最后一次提交,把你送回命令行并提示以下信息:
$ git rebase -i HEAD~3 Stopped at f7f3f6d... changed my name a bit You can amend the commit now, with git commit --amend Once you're satisfied with your changes, run git rebase --continue
這些指令準確地告訴你該做什么。 輸入
$ git commit --amend
修改提交信息,然后退出編輯器。 然后,運行
$ git rebase --continue
這個命令將會自動地應用另外兩個提交,然后就完成了。 如果需要將不止一處的 pick 改為 edit,需要在每一個修改為 edit 的提交上重復這些步驟。 每一次,Git 將會停止,讓你修正提交,然后繼續直到完成。
重新排序提交
也可以使用交互式變基來重新排序或完全移除提交。 如果想要移除 “added cat-file” 提交然后修改另外兩個提交引入的順序,可以將變基腳本從這樣:
pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file
改為這樣:
pick 310154e updated README formatting and added blame pick f7f3f6d changed my name a bit
當保存并退出編輯器時,Git 將你的分支帶回這些提交的父提交,應用 310154e 然后應用 f7f3f6d,最后停止。 事實修改了那些提交的順序并完全地移除了 “added cat-file” 提交。
壓縮提交
通過交互式變基工具,也可以將一連串提交壓縮成一個單獨的提交。 在變基信息中腳本給出了有用的指令:
# # Commands: # p, pick
如果,指定 “squash” 而不是 “pick” 或 “edit”,Git 將應用兩者的修改并合并提交信息在一起。 所以,如果想要這三次提交變為一個提交,可以這樣修改腳本:
pick f7f3f6d changed my name a bit squash 310154e updated README formatting and added blame squash a5f4a0d added cat-file
當保存并退出編輯器時,Git 應用所有的三次修改然后將你放到編輯器中來合并三次提交信息:
# This is a combination of 3 commits. # The first commit's message is: changed my name a bit # This is the 2nd commit message: updated README formatting and added blame # This is the 3rd commit message: added cat-file
當你保存之后,你就擁有了一個包含前三次提交的全部變更的提交。
拆分提交
拆分一個提交會撤消這個提交,然后多次地部分地暫存與提交直到完成你所需次數的提交。 例如,假設想要拆分三次提交的中間那次提交。 想要將它拆分為兩次提交:第一個 “updated README formatting”,第二個 “added blame” 來代替原來的 “updated README formatting and added blame”。 可以通過修改 rebase -i 的腳本來做到這點,將要拆分的提交的指令修改為 “edit”:
pick f7f3f6d changed my name a bit edit 310154e updated README formatting and added blame pick a5f4a0d added cat-file
然后,當腳本帶你進入到命令行時,重置那個提交,拿到被重置的修改,從中創建幾次提交。 當保存并退出編輯器時,Git 帶你到列表中第一個提交的父提交,應用第一個提交(f7f3f6d), 應用第二個提交(310154e),然后讓你進入命令行。 那里,可以通過 git reset HEAD^ 做一次針對那個提交的混合重置,實際上將會撤消那次提交并將修改的文件取消暫存。 現在可以暫存并提交文件直到有幾個提交,然后當完成時運行 git rebase --continue:
$ git reset HEAD^ $ git add README $ git commit -m 'updated README formatting' $ git add lib/simplegit.rb $ git commit -m 'added blame' $ git rebase --continue
Git 在腳本中應用最后一次提交(a5f4a0d),歷史記錄看起來像這樣:
$ git log -4 --pretty=format:"%h %s" 1c002dd added cat-file 9b29157 added blame 35cfb2b updated README formatting f3cc40e changed my name a bit
再次強調,這些改動了所有在列表中的提交的 SHA-1 校驗和,所以要確保列表中的提交還沒有推送到共享倉庫中。
核武器級選項:filter-branch
有另一個歷史改寫的選項,如果想要通過腳本的方式改寫大量提交的話可以使用它——例如,全局修改你的郵箱地址或從每一個提交中移除一個文件。 這個命令是 filter-branch,它可以改寫歷史中大量的提交,除非你的項目還沒有公開并且其他人沒有基于要改寫的工作的提交做的工作,否則你不應當使用它。 然而,它可以很有用。 你將會學習到幾個常用的用途,這樣就得到了它適合使用地方的想法。
從每一個提交中移除一個文件
這經常發生。 有人粗心地通過 git add . 提交了一個巨大的二進制文件,你想要從所有地方刪除。 可能偶然地提交了一個包括一個密碼的文件,然而你想要開源項目。 filter-branch 是一個可能會用來擦洗整個提交歷史的工具。 為了從整個提交歷史中移除一個叫做 passwords.txt 的文件,可以使用 --tree-filter 選項給 filter-branch:
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten
--tree-filter 選項在檢出項目的每一個提交后運行指定的命令然后重新提交結果。 在本例中,你從每一個快照中移除了一個叫作 passwords.txt 的文件,無論它是否存在。 如果想要移除所有偶然提交的編輯器備份文件,可以運行類似 git filter-branch --tree-filter 'rm -f *~' HEAD 的命令。
最后將可以看到 Git 重寫樹與提交然后移動分支指針。 通常一個好的想法是在一個測試分支中做這件事,然后當你決定最終結果是真正想要的,可以硬重置 master 分支。 為了讓 filter-branch 在所有分支上運行,可以給命令傳遞 --all 選項。
使一個子目錄做為新的根目錄
假設已經從另一個源代碼控制系統中導入,并且有幾個沒意義的子目錄(trunk、tags 等等)。 如果想要讓 trunk 子目錄作為每一個提交的新的項目根目錄,filter-branch 也可以幫助你那么做:
$ git filter-branch --subdirectory-filter trunk HEAD Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) Ref 'refs/heads/master' was rewritten
現在新項目根目錄是 trunk 子目錄了。 Git 會自動移除所有不影響子目錄的提交。
全局修改郵箱地址
另一個常見的情形是在你開始工作時忘記運行 git config 來設置你的名字與郵箱地址, 或者你想要開源一個項目并且修改所有你的工作郵箱地址為你的個人郵箱地址。 任何情形下,你也可以通過 filter-branch 來一次性修改多個提交中的郵箱地址。 需要小心的是只修改你自己的郵箱地址,所以你使用 --commit-filter:
$ git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; then GIT_AUTHOR_NAME="Scott Chacon"; GIT_AUTHOR_EMAIL="schacon@example.com"; git commit-tree "$@"; else git commit-tree "$@"; fi' HEAD
這會遍歷并重寫每一個提交來包含你的新郵箱地址。 因為提交包含了它們父提交的 SHA-1 校驗和,這個命令會修改你的歷史中的每一個提交的 SHA-1 校驗和, 而不僅僅只是那些匹配郵箱地址的提交。
Git GitHub 代碼托管 CodeHub 代碼檢查 CodeCheck 彈性云服務器 ECS
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。