如何批量刪除一些很久之前的提交記錄,但保留那些修改的內容。
這個問題有一點 A/B,因為你沒有說明刪除很久之前的提交記錄的場景是什麼,這很重要因為會影響到接下來 Git 的使用選擇。舉例來說:
git rebase -i <ref>
git rebase --onto <ONTO_BASE_ref> <START_ref> <END_ref>
START
END
ONTO_BASE
git checkout --orphan new_start
new_start
HEAD
git replace
其實還有很多種場景可以說道,Git 的用法非常靈活,即使暫時用不到也值得細細過一遍知道它能做什麼樣的事情,然後遇到各種複雜的場景就可以自己推導出解決方案了。
身為 Repo 的維護者,最常見的事情就是從某一 ref 開始到 HEAD保留下來,然後先前的歷史刪除。因為這個任務比較常見,所以這裡也有一個 shell script 分享給你:
sh#!/bin/bash git checkout --orphan temp git commit -m "截取的历史记录起点" git rebase --onto temp master git branch -D temp
sh
#!/bin/bash git checkout --orphan temp git commit -m "截取的历史记录起点" git rebase --onto temp master git branch -D temp
使用的時候這樣(例如該腳本保存叫 git-detach): git-detach <ref>,其中 <ref> 就是你要保留的歷史記錄的起點。
git-detach
git-detach <ref>
<ref>
需要注意的是,這個腳本只是把歷史記錄「分離」開來,然後其中的一部分沒有了可見的引用因此在歷史記錄裡看不見,然而它們的git object 仍然存在(換言之你還能恢復過來,自行查閱git-reflog),如果你真要彻底丢掉这些历史(为了给 repo 减肥),可以用 git gc --prune,那就再也找不回來了。
git-reflog
git gc --prune
P.S. 這個腳本依賴 Orphan Branch,低版本的 Git 不支援(大概是
這個問題有一點 A/B,因為你沒有說明刪除很久之前的提交記錄的場景是什麼,這很重要因為會影響到接下來 Git 的使用選擇。舉例來說:
1.2 如果要刪除的歷史記錄是分散的,則可以考慮 Interactive Rebase,自行挑選/合併等。如
git rebase -i <ref>
1.1 如果要刪除的歷史記錄是連續的,比如說從最開始到某一刻全部都刪除或者是中間一截可以刪除,則可以考慮 Onto Rebase,如
git rebase --onto <ONTO_BASE_ref> <START_ref> <END_ref>
,其中START
到END
之间的是需要保留的部分,而ONTO_BASE
则是最新的基点;换言之,从ONTO_BASE
到START
之間的歷史記錄會被幹掉。git checkout --orphan new_start
,这条命令会创建一个叫做new_start
的分支,该分支没有任何历史记录,但是所有的文件都会原封不动的存在,你可以据此开始重新提交。完成之后甚至可以把旧的分支直接废弃。另外,也可以指定新分支的起点,默认当然是从HEAD
開始了。git replace
的文檔:http://git-scm.com/2010/ 03/17/replace.html其實還有很多種場景可以說道,Git 的用法非常靈活,即使暫時用不到也值得細細過一遍知道它能做什麼樣的事情,然後遇到各種複雜的場景就可以自己推導出解決方案了。
身為 Repo 的維護者,最常見的事情就是從某一 ref 開始到 HEAD保留下來,然後先前的歷史刪除。因為這個任務比較常見,所以這裡也有一個 shell script 分享給你:
使用的時候這樣(例如該腳本保存叫
git-detach
):git-detach <ref>
,其中<ref>
就是你要保留的歷史記錄的起點。需要注意的是,這個腳本只是把歷史記錄「分離」開來,然後其中的一部分沒有了可見的引用因此在歷史記錄裡看不見,然而它們的git object 仍然存在(換言之你還能恢復過來,自行查閱
git-reflog
),如果你真要彻底丢掉这些历史(为了给 repo 减肥),可以用git gc --prune
,那就再也找不回來了。P.S. 這個腳本依賴 Orphan Branch,低版本的 Git 不支援(大概是