[英]Can I revert to an old Git commit, while preserving the latest commits?
[英]Git: Revert all commits in feature branch prior to latest commit
我有一個分支,由於我們的主分支中的強制推送而導致錯誤的提交歷史記錄。 基本上我在這個分支歷史中有以下提交:A,B,C,D,E,其中應該保留E但是應該刪除ABCD。 添加它們是因為在主要來源強制刪除這些提交之前,主要合並到分支中。 我怎么能做到這一點?
如果A是保存的那個我可以git reset - 硬A但是它是另一個方向....
drop
選項 正如Romain所說,“rebase是另一種”,這是一種方法,假設你確實希望@-ABCDE
的最終結果是@-E
,正如Lasse所說的那樣。
我提供這個作為你的工具帶中的另一個工具 :它不是解決這個問題的簡單方法。 但它確實允許您刪除不按順序的提交(例如,刪除A,C,E並保留B,D):
git rebase -i HEAD~6
這將使用如下所示的緩沖區打開您的編輯器(可能是vi
):
pick 4231648cb4 Some previous commit
pick 4bccf2ce81 A some message
pick 7b4cd5ff17 B some message
pick faa44efb7c C some message
pick 0ce0525a79 D some message
pick f104648cc3 E some message
# Rebase 76eb9131b5..ed71142fcb onto 4231648cb4 (6 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# 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
是的,從頂部到底部的提交順序是反向時間順序(與git log
相反),最近的順序在底部。 這就是為什么“線從上到下執行” - 從最舊到最近。
按照說明,將單詞pick
更改為要刪除的行上的d
(或drop
)。
pick 4231648cb4 Some previous commit
d 4bccf2ce81 A some message
d 7b4cd5ff17 B some message
d faa44efb7c C some message
d 0ce0525a79 D some message
pick f104648cc3 E some message
如果你犯了一個不可恢復的錯誤,比如刪除一行,則在不保存的情況下退出( :q!
)並重試。
如果一切看起來都不錯,請保存並退出緩沖區( :wq
)並繼續重新定位,直到您的分支被修復為止。
如果在那之后發生了一些不穩定的事情(就像你將一個提交哈希改為一個不存在的,或者rebase停止做某事而你不知道為什么)你可以用git rebase --abort
完全中止git rebase --abort
會帶來你回到了初始狀態。
如果您的分支看起來正確,請強制推送。
git push -f
可能鮮為人知,但是在git 2之前的默認推送策略是matching
,這意味着當你git push
,它將推送所有本地分支機構的匹配遠程分支名稱,而不僅僅是當前分支。
所以,當你git push -f
它會強制推送你所有的分支(這發生在昨天的同事身上)。 檢查git config --global push.default
。 這意味着,如果你玩弄其他一些分支,它也可以強制推動它。
如果不是那樣,我建議將默認推送策略更改為simple
。 這是git 2的默認值。
如果您使用集中托管的git解決方案,如Stash / BitBucket,Gitlab或Github,它們都提供所謂的“分支保護”規則,以防止開發人員強行推送到分支機構。
添加規則以防止強制推送到master
並可能release
分支。
您可以使用git reset --hard A^
轉到最后一個“好”提交,然后git cherry-pick E
來應用您想要保留的提交。
然后你必須強制將它推到分支重置的東西。 一定要讓團隊中的其他人知道發生了什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.