繁体   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