将提交移动到新分支,从推出的repo上的当前分支中删除

时间:2011-03-22 17:38:55

标签: git

我是团队的几个git存储库的经理,经常遇到这个问题。当他们应该创建一个功能分支时,另一个团队成员意外地在master或staging分支上提交他们的工作。

这些提交还没有准备好被推送,所以我被卡住了。我知道如何在创建一个新分支后重置当前分支,但是当所有东西都通过远程仓库推送时,它无法正常工作。

我需要一种方法将最后一个x号提交从分支A移动到新分支B,从分支A中删除这些提交(以允许我安全地推送回远程仓库的方式)。当分支B完成时,我需要能够将它合并回分支A。

我已经找到了大量的建议,但是没有任何建议可以正常推送。

2 个答案:

答案 0 :(得分:6)

根据我了解情况,有人将您提交的master提交到您不想要的中央存储库origin,并且您希望(a)在您的本地修复此问题存储库然后(b)将固定分支推送回中央存储库。 adymitruk's answer告诉你如何强制推动主分支 - (b)部分 - 但是也值得一谈(a)。最后也是最尴尬的考虑因素是(c):使用存储库的其他人如何处理重写的master分支。

首先,我认为值得考虑是否可以恢复不应该在master上的提交。这个选项对已经退出master的其他人造成的影响最小,并且可以减少向人们解释如何处理结果的工作 - (c)部分。但是,如果您决定在master分支中不必进行这些提交,然后再进行恢复,那么以下是您应采取的步骤:

(a)本地修复主人

这一点非常简单。像往常一样使用git,确保git状态是干净的。然后:

# Make sure you're on master:
git checkout master

# Create a branch at this point for the commits that your co-worker should
# have put on a topic branch:
git branch ill-advised-experiment

# Reset your master branch to the last good commit:
git reset --hard <SHA1-OF-LAST-GOOD-COMMIT>

(b)推动修订后的主要和主题分支

您的主人现在不包含原始主人的完整历史记录,因此您必须“强行推送”:

git push -f origin master

...但你可以照常推送新的主题分支,当然:

git push origin ill-advised-experiment

(c)让其他人知道他们应该做什么

强制推送重写的master分支后的风险是某人已经完成了git pullgit pull --rebase,因此他们在其主分支中进行了意外提交。如果那个人然后在master上推送origin,那么错误的提交将返回到master分支,然后你就会回到原点。因此,假设最早的错误提交具有对象名称(SHA1sum)f414f3l,您可以要求人们检查:

git branch -a --contains f414f3l

如果他们收到错误,那么该提交根本不在他们的存储库中,并且一切正常。

如果他们看到 origin/master远程跟踪分支包含该提交,那么这一切都很简单 - 他们应该只运行git fetch origin来更新他们的远程跟踪分支

但是,如果masterorigin/master都包含该提交,则用户需要更加小心。首先,用户应该隐藏或提交他们的所有工作,以确保git status是干净的。然后我会建议如下:

# Leave a branch pointing to your old master, just to make it easy to find
# commits from there:
git checkout master
git branch old-master

# Now update all the remote-tracking branches from origin (you should see
# a "forced update" message for master):
git fetch origin

# Now reset the master branch to the right remote version:
git reset --hard origin/master

现在,如果此用户只有一些未暂停和未提交的更改,那么他们就可以git stash apply继续进行。

如果他们刚刚完成了一两次新提交,那么从git log old-master找到这些提交的对象名称并为每个提交执行git cherry-pick <SHA1sum-OF-MY-COMMIT>可能最容易。然后他们可以照常进行。

最后,如果他们做了很多提交,最简单的方法就是使用交互式rebase将这些提交应用到新的master上,并跳过糟糕的提交。这将涉及:

# To be extra cautious, create a new branch based on "old-master" for
# rebasing and switch to that:
git checkout -b old-master-for-rebasing old-master

# Start an interactive rebase:
git rebase -i master

# At this stage, delete every line that refers to a bad commit or anything
# that shouldn't be in master now.  Leave everything else in the file, as
# a line beginning with "pick".

# If all went well, this branch can now be merged into master, which should
# be a fast-forward merge:
git checkout master
git merge old-master-for-rebasing

我希望有一些用处。

答案 1 :(得分:1)

如果您掌控团队并将其传达给每个人,那么在您将存储库看作是您希望在本地获取之后强制推送。

git push origin master -f

因为您已经推送过它,除了还原构成该功能的所有提交之外,没有其他方法可以做到这一点。