我是一个团队的几个git存储库的经理,经常遇到这个问题.当他们应该创建一个功能分支时,另一个团队成员意外地在master或staging分支上提交他们的工作.
那些提交还没有准备好被推送,所以我被卡住了.我知道如何在创建一个新分支后重置当前分支,但是当事物全部通过远程仓库推送时,它无法正常工作.
我需要一种方法将最后一个x号提交从分支A移动到新分支B,从分支A中删除这些提交(以允许我安全地推回到远程仓库的方式).当分支B完成时,我需要能够将它合并回分支A.
我已经找到了大量的建议,但是没有一个能够在已经推送的提交中正常工作.
据我了解情况,有人已将提交推送到master您origin不想要的中央存储库()中,并且您希望(a)在本地存储库中修复此问题,然后(b)将固定分支推回到中央存储库. adymitruk的回答告诉你如何强制推动主分支 - (b)部分 - 但是值得一谈(a).最后也是最尴尬的考虑因素是(c):使用存储库的其他人如何处理重写的master分支.
首先,我认为值得考虑是否可以恢复不应该在master上的提交.这个选项将对已经退出的其他人造成最小的干扰,master并减少向人们解释如何处理结果的工作 - (c)部分.但是,如果您已经决定不必在master分支中进行这些提交,然后是恢复,那么以下是您应该采取的步骤:
这一点非常简单.像往常一样使用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>
Run Code Online (Sandbox Code Playgroud)
您的主人现在不包含原始主人的完整历史记录,因此您必须"强制推送":
git push -f origin master
Run Code Online (Sandbox Code Playgroud)
...但是你可以照常推送新主题分支,当然:
git push origin ill-advised-experiment
Run Code Online (Sandbox Code Playgroud)
你强行推动重写master分支后的风险是某人已经做了git pull或者git pull --rebase,所以他们在他们的主分支中有意外的提交.如果用户随后推向master上origin,坏提交会回来的master分支,你又回到了起点.因此,假设最早的错误提交具有对象名称(SHA1sum)f414f3l,您可以要求人们检查:
git branch -a --contains f414f3l
Run Code Online (Sandbox Code Playgroud)
如果他们收到错误,那么该提交根本不在他们的存储库中,并且一切正常.
如果他们看到仅在origin/master远程跟踪分支包含了承诺,再次这一切都容易-他们应该只是运行git fetch origin更新其远程跟踪分支.
然而,如果两个master和origin/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
Run Code Online (Sandbox Code Playgroud)
现在,如果此用户只有一些未分级和未提交的更改,那么他们就可以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
Run Code Online (Sandbox Code Playgroud)
我希望有一些用处.