8

我在远程+本地分支中有一个提交,我想将该提交从历史记录中删除,并将其中一些放入自己的分支中。

基本上,现在我有:

           D---E---F---G master

而且我要:

             E---G topic
            /
           D master

这应该在我的本地和(只有一个,称为源)远程存储库中。

哪种方法最干净?

此外,还有其他人克隆了该 repo 并签出了 master 分支。如果我要在远程仓库中进行这样的更改,'git pull' 是否可以让他们也达到相同的状态?

4

3 回答 3

7

如果你已经发表了,那么你是对的,你不想重写master. 您想要的是向 master 发布一个提交,使其恢复到它所处的状态,D同时保留其当前历史记录,以便其他用户可以轻松地合并或重新调整他们的工作。

如果您计划在未来的某个时候合并topicmaster那么您可能还想做的是在 and 之间建立一个新的公共基础mastertopic这样当您随后进行合并时topic,您就不会丢失在 中恢复的提交master。最简单的方法是在“撤消”提交的基础上进行“重做”提交,该提交将重置master为其原始状态,并在此基础上建立新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

重要的是您没有重写历史记录,并且主题基于 master,因此合并不会意外应用任何“撤消”提交。您现在可以安全地将两者推master送到topic您的远程存储库。

于 2009-10-06T18:12:16.987 回答
4

如果你愿意,你可以重写你的历史,但如果其他人有历史的副本,那就不好了。在这种情况下,您可能会使用交互式 rebase: git rebase -i master topic。这将为您提供从 master 到 topic 的提交列表,并提供有关如何使用它们的提示。您只需要删除包含要删除的提交的行。

也就是说,我必须强调,如果其他人有这样的历史,这样做是不负责任的。您必须将其强制推送到您的中央存储库,并且其他所有人都必须修复他们的存储库以匹配,根据情况可能相对简单或复杂。

如果你真的决定这样做,在git-rebase 手册页中有一个很好的部分叫做“从上游 rebase 恢复”讨论如何处理这个问题。

编辑:

对于简单的历史,一个常见的情况是,在强制非快进推送到中央仓库 ( push -f) 之后,其他开发人员:

  • 备份他们的老主人:git branch -m master master_old
  • 从原点获取更新并重新创建主控:git remote update origin; git branch master origin/master
  • 将所有主题分支重新设置为新的主分支:git rebase --onto master master_old topic

如果他们在他们的master 分支中有工作但还没有在 origin 中,他们将不得不变得更好,将这项工作和所有主题分支重新定位到 master 的新位置......这应该让你知道为什么它是如此糟糕改写别人的历史。真的,一旦有东西被传递到公共存储库,你应该把它看作是硬性记录的历史,而不是正在进行的工作。

于 2009-10-06T16:50:54.017 回答
-3

我觉得git stash很有帮助

把它藏起来,永远不要再看它。

于 2010-04-30T06:36:06.527 回答