git:git恢复的更好方法,无需额外的恢复提交
我在远程+本地分支中有一个提交,我想将该提交从历史记录中删除,并将其中一些提交到自己的分支中 基本上,现在我有:git:git恢复的更好方法,无需额外的恢复提交,git,revert,Git,Revert,我在远程+本地分支中有一个提交,我想将该提交从历史记录中删除,并将其中一些提交到自己的分支中 基本上,现在我有: D---E---F---G master 我想: E---G topic / D master 这应该在我的本地存储库和远程存储库中(只有一个称为源存储库) 哪种方法最干净 此外,还有其他人克隆了该回购协议,并签出了主分支。如果我在远程回购中做这样的更改,“git-pull”是否也能让他
D---E---F---G master
我想:
E---G topic
/
D master
这应该在我的本地存储库和远程存储库中(只有一个称为源存储库)
哪种方法最干净
此外,还有其他人克隆了该回购协议,并签出了主分支。如果我在远程回购中做这样的更改,“git-pull”是否也能让他们达到相同的状态?如果你愿意,你可以重写你的历史记录,但如果其他人有历史记录的副本,这是个坏主意。在本例中,您可能会使用交互式rebase:
git rebase-i master topic
。这将为您提供从主机到主题的提交列表,并提示如何使用它们。您只需要删除包含要删除的提交的行
尽管如此,我必须强调,如果其他任何人有这样的历史,那么这样做是不负责任的。您必须强制将其推送到您的中央回购,其他人必须修复其存储库以进行匹配,这可能相对简单,也可能相对复杂,具体取决于具体情况
如果你真的决定这样做的话,在讨论如何处理这一问题时,有一个很好的章节叫做“从上游返利中恢复”
编辑:
对于简单的历史记录,常见的情况是,在强制向中央回购进行非快进推送(push-f
)之后,其他开发人员:
- 备份他们的旧主机:
git分支-m master master\u old
- 从源站获取更新并重新创建主机:
git远程更新源站;git分支主控源/主控
- 将所有主题分支重新设置到新主主题上:
git-rebase——设置到主主题上\u旧主题上
如果他们在其主分支中有尚未起源的工作,他们将不得不变得更加有趣,将此工作和所有主题分支重新定位到主分支的新位置上。。。这应该会让你明白为什么重写别人的历史如此糟糕。事实上,一旦某些内容被传递到公共存储库中,您应该将其视为硬记录的历史,而不是正在进行的工作。如果您已经发布,那么您不想重新编写
master
的历史是对的。您想要的是发布一个commit to master,将其恢复到D
的状态,同时保留其当前历史记录,以便其他用户可以轻松合并或重新设置其工作的基础
如果您计划在将来的某个时候将主题
合并到主
中,那么您可能还想做的是在主
和主题
之间建立一个新的公共基础,以便在随后合并主题
时,您不会丢失在master
中还原的提交。最简单的方法是在将master
重置回其原始状态的“undo”提交的基础上进行“redo”提交,并在此基础上建立新的topic
分支
# checkout master branch (currently at G)
git checkout master
# Reset the index to how we want master to look like
git reset D
# Move the branch pointer back to where it should be, leaving the index
# looking like D
git reset --soft HEAD@{1}
# Make a commit (D') for the head of the master branch
git commit -m "Temporarily revert E, F and G"
# Create the new topic branch based on master.
# We're going to make it on top of master and the 'undo'
# commit to ensure that subsequent merges of master->topic
# or topic->master don't merge in the undo.
git checkout -b topic
# Revert the undo commit, making a redo commit (G').
git revert HEAD
作为替代方案,您可以让提交E',F'和G'分别重做每个部分,但由于E,F和G已经出现在您发布的历史记录中,如果您只是引用“撤消”提交并说该提交正在撤消,可能更容易理解。无论如何,这就是git revert所做的
基本上你知道的就是这个
D -- E -- F -- G -- D' <-- master
\
\
G' <-- topic
D--E--F--G--D'我发现git stash
非常有用
把它藏起来,不要再看了。好的,非常感谢你提供的信息。所以这并不是一个真正的解决方案,因为我不想做这样的力推。要得到类似的结果,最干净的解决方案是什么?我现在想的是在master中恢复E,F,G,然后从该状态创建一个新分支,然后选择E和G。这是一种自然的做法吗?如果不引起此类问题,就无法从历史中删除提交。无论你做什么,你最终都会将你的master ref指向一个在其历史中没有master先前位置的提交。这在我对这个问题的新版本的回答中得到了很大的解决,但要回答你的评论:你如何进入重写master历史的状态并不重要。你仍然会重写它。如果你在当地做这些事情,那就好了。这叫做清理。如果你对已发表的作品做这些操作,你就把事情搞砸了,创建了一个没有人可以信任的公共回购协议,等等。通过还原E、F、G,我想使用git revert。所以历史看起来有点丑陋,但我不需要处理这些问题,因为我真的不想改变已经推动的历史。啊,好吧。对不起,我误解了你的意思,以为你在说把师父指给樱桃树摘的那一套。如果你想创建新的分支,你仍然可以使用相同的重基方法——只需在master new上创建,而不是master。谢谢,这正是我现在所做的(也是我在给Jefromi的一些评论中建议的)。历史现在有点难看,因为这个撤销提交,但我不能做任何事情。2周git用户在这里。首先将G分支到G',然后git恢复到G到D,从而得到D',不是更容易吗?这样你就不必撤销/重做任何事情,这对我来说安全多了。(我已经无法恢复地丢失了编辑,因为我弄乱了git reset
)@bart,看看git reflog
。被提交并随后被破坏的内容应该总是可以通过reflog恢复,至少在几天内是这样。然而,您可能无法恢复地丢失您未能提交的更改。@bart,Charles Bailey解释了为什么他会按照他在这里所做的顺序来做事情,他说“您可能还想做的是创建一个新的公共文件。”