簡體   English   中英

Git:在最新提交之前恢復功能分支中的所有提交

[英]Git: Revert all commits in feature branch prior to latest commit

我有一個分支,由於我們的主分支中的強制推送而導致錯誤的提交歷史記錄。 基本上我在這個分支歷史中有以下提交:A,B,C,D,E,其中應該保留E但是應該刪除ABCD。 添加它們是因為在主要來源強制刪除這些提交之前,主要合並到分支中。 我怎么能做到這一點?

如果A是保存的那個我可以git reset - 硬A但是它是另一個方向....

# make a backup of the current state of your branch
git branch backup your_branch

# reset to the commit prior to A
git reset --hard A^

# then re-apply E
git cherry-pick E

將是一種方法來做到這一點。 Rebase是另一個(參見msanford關於這個主題的非常詳細的答案

帶有rebase + 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM