很久以前我有一個不好的提交,我想從git歷史中徹底刪除它,就像它從未發生過一樣。我知道提交ID讓我們說1f020。我已經嘗試了git rebase並將其刪除,但重新綁定時發生太多衝突,以至於無法這樣做。該提交是簡單的1行代碼更改,並推送一些與項目無關的文件。 所以我想寫這1行代碼更改並提交它,然後以某種方式替換這個新的提交很久以前。在git中替換提交
回答
如果違規承諾
git commit -C <SHA1-for-commit-just-after-bad-commit-1f020>
重新應用一切都在一個私人倉庫,什麼你想要做的並不是什麼大不了的事情。重寫已發佈的git歷史令您的協作者感到惱火,因此請確保刪除此行是值得的。
git-rebase
documentation有一個有用的通道。
git rebase [...] [<--onto newbase>] [<upstream>] [<branch>]
提交的範圍也可以與底墊被去除。如果我們有以下的情況:
E---F---G---H---I---J topicA
然後命令
git rebase --onto topicA~5 topicA~3 topicA
會導致拆除提交˚F和摹:
E---H'---I'---J' topicA
這是如果有用的話F and G以某種方式存在缺陷,或者不應該成爲
topicA
的一部分。請注意,參數--onto
和上游參數可以是任何有效的提交。
假設你的歷史是線性的,有問題的承諾是在你的主分支,您可以通過運行
git rebase --onto 1f020~ 1f020 master
對於多毛的情況下適應上面的例子中,使用的交互變基。您可能會發現跟隨an example that merges two commits一起使用會很有幫助,但是不要使用s
作爲壓扁標記提交,請移除整行以從歷史記錄中刪除提交。
你不應該從git的歷史中刪除提交。您稍後會遇到問題。
但是,如果您知道自己在做什麼,則可以在本地回退您的歷史記錄,將當前提交的內容替換掉,然後重新播放所有提交 - 然後對存儲庫執行強制推送。
但我強烈建議不要這樣做。只要做一個新的承諾,並承認歷史上有一個不好的承諾。
我知道如何回放和重放我所有的提交,如上所述。但有數百次提交需要重放數百次衝突。我正在尋求另一種解決方案。如何在不必重播所有數百次提交的情況下刪除該錯誤提交。 – sonnyhe2002
@ sonnyhe2002可以做到這一點,但這並不容易,它需要編寫一個腳本。詳情請參閱我的回答。 – user4815162342
這是稍微複雜的,但不管怎麼說,這是怎麼一回事呢:
分離頭和移動承諾只是後壞提交。使用git log來查找1f020之後的下一次提交。
git checkout <SHA1-for-commit-just-after-bad-commit-1f020>
動腦子犯只是BEFORE壞承諾,但留下的指數和工作樹,因爲它是
git reset --soft <SHA1-for-just-previous-to-bad-commit-1f020>
重做承諾只是後壞提交重新使用提交消息,但現在在之前只提交了那個提交失敗。因此,去除壞承諾從呈交只是後壞起提交到這個新的地方
git rebase --onto HEAD <SHA1-for-commit-just-after-bad-commit-1f020> master
這太棒了。 –
所以,你想要的是:
卸下歷史的錯誤提交,並
是不是一定要重做所有來刪除提交後的合併。即從已刪除的提交中下載的每個提交都應該保持原樣,只需稍作更改即可,不包括從歷史記錄中刪除的更改。基於
git rebase --onto
和git rebase -i
解決方案未能在第二點,因爲它們需要重做所有後來發生的合併。但是,理論上可以簡單地重新創建所有這些其他提交,就好像違規提交從未發生過一樣,前提是不良提交足夠小以至於從其後繼本身恢復衝突。
正如邁克爾和其他人所指出的那樣,這樣做是非常不可取的。這也是一項重大的任務,幾乎肯定不值得。但是,對於教育價值,以下是完成目標的綜合解決方案的概要:
備份存儲庫。
使用
git rev-list
生成一個提交列表,該提交列表以提交錯誤開始並導致提交可達的所有分支頭。初始化一個空映射,以將舊提交映射到新映射。
每個提交列表中,請執行以下操作:
- 退房的承諾,並恢復從壞的變化提交
- 創建樹對象進行使用
git write-tree
當前樹
- 使用
git commit-tree
創建一個新的提交與新的樹,舊的提交信息,父母翻譯從父母使用上述地圖(如果有些父母不在地圖中,只使用舊的父母) - 註冊提交地圖中的新提交。
通過標記和標記對象,並重新創建它們以指向新的提交,查閱地圖。
通過分行負責人並致電
git update-ref
指示他們到新的提交,查閱地圖。
如果提交引入的更改一行(和不必要的文件)不從後提交,這一過程可以完全自動化的變更發生衝突,並執行不需要你手動重做以後提交的所有合併和衝突。
缺點是它仍然需要重寫所有後來的提交,如果它們已在其他地方共享,則使其失效,並使提交消息中的提交引用無效,例如由git revert
生成的提交。
好吧,我如何'初始化一個空的地圖來映射舊的提交到新的' – sonnyhe2002
@ sonnyhe2002澄清,「初始化一個空的地圖」並沒有提到一個git概念,它是算法中的一個步驟。它告訴實現者創建地圖,稍後將用於將舊提交與新提交相關聯。在Python中,映射將作爲字典來實現,在Perl中作爲散列,在Bash中作爲關聯數組。這張地圖在下面的步驟中被填充和查找,所以它必須事先被初始化。 – user4815162342
- 1. GIT中替換其間與另一分支提交提交
- 2. 如何使用git替換替換的樹提交
- 3. 在git中將雙親提交轉換爲單親提交
- 4. Git:從歷史記錄中刪除替換文件的提交
- 5. 如何在git中提交提交?
- 6. jQuery替換提交按鈕
- 7. JavaScript替換表單提交
- 8. 替換提交按鈕
- 9. 在Git中刪除提交
- 10. jquery,在提交時替換html
- 11. jQuery在提交時替換文本
- 12. Git - 在提交時顯示提交者
- 13. 如何在Git中非交互地重新提交提交
- 14. 將本地Git提交到git-svn的一個提交中
- 15. 將git提交轉換爲一個
- 16. 如何刪除所有提交併替換Git存儲庫中的初始提交?
- 17. 提交代碼在Git中,分支在源頭提交一次提交
- 18. 如何用git中的特定提交替換當前分支的頭部?
- 19. Git中的提交對象
- 20. GIT如何在不提交
- 21. 在git捆綁提交
- 22. 卡在git提交窗口
- 23. 提交修改如何幫助您在Git中切換分支?
- 24. Git - 在已提交的文件中不改換行結尾
- 25. 在git中輸出給定提交的提交消息
- 26. 如何在一次提交中提交SVN和GIT?
- 27. 在git中提交一個提交鉤子
- 28. 獲取在git中提交的提交數
- 29. 如何在git中一次提交一系列提交?
- 30. 在git中查找所有未提交的提交?
如果我這樣做,它會給後來的分支上的合併衝突H'我'... – sonnyhe2002
@ sonnyhe2002它取決於您的存儲庫的細節和有問題的提交。 –