我怎样才能将多个Git提交(已经推送到)发布的存储库?
新来的混帐,已经搞乱了。
我已经提交并将一些更改推送到远程开发机器。 我需要恢复一个旧版本,但保持“糟糕的进展”到目前为止继续在一个单独的分支上工作;
我在想这样做:
- 创build一个名为“tested-thing” 的本地分支
- 将本地存储库恢复到其工作的状态(希望有意义的提交将有所帮助) ;
-
推到远程
-
完成testing的东西的testing
- 将 “被testing的东西” 合并 到dev中
- 推到远程
在其他开发者之间的第3步和第5步可能会犯下并推动,恐怕这可能导致“合并悲剧” – 无论如何,这可能是一个正确的路?
更新:
这里主要的问题在于2)
在这里,关于主题:“打破主题分支的工作” http://learn.github.com/p/undoing.html
他们build议:
- $ git分支testing
- $ git reset –hard a6b4c974
通过这样做,其他开发者仍然可以:
$ git commit
(在开发分支上)
我可以签出testing和工作,直到合并时间。
尽pipe所有的select,这感觉就像是一个不错的方法来跟随。 但是,我们没有说这是否可以在我们推后?
请注意以下几点: 由于我做了这些改变,我搞砸了所有的事情, 迄今为止没有其他人在仓库上工作 。 所以,如果我恢复工作目录,没有人会注意到。
问题
有许多工作stream程可以使用。 重点是不要打破已发布的分支的历史,除非你已经与每个可能消费分支的人交stream,并愿意为每个人的克隆做手术。 如果可以避免的话,最好不要这样做。
发布分支的解决scheme
您所概述的步骤有其优点。 如果你需要开发分支马上稳定,就这样做。 你有很多用Gitdebugging的工具,可以帮助你find正确的分支点,然后你可以恢复最后一个稳定的提交和HEAD之间的所有提交。
要么以相反的顺序一次性提交一个提交,要么使用<first_bad_commit>..<last_bad_commit>
范围。 哈希是指定提交范围的最简单的方法,但还有其他的表示法。 例如,如果您推送了5个错误提交,则可以使用以下方法恢复它们:
# Revert a series using ancestor notation. git revert --no-edit dev~5..dev # Revert a series using commit hashes. git revert --no-edit ffffffff..12345678
这将按顺序将反转的补丁应用于您的工作目录,向着您已知的良好提交方向反向工作。 使用–no-edit标志,应用每个反向修补程序后,将自动提交对您的工作目录的更改。
请参阅man 1 git-revert
获取更多选项, man 7 gitrevisions
以不同的方式指定要提交的提交。
或者,你可以分解你的HEAD,按照他们需要的方式修复,重新合并。 在此期间你的构build将被打破,但在某些情况下这可能是有意义的。
危险区域
当然,如果您确定没有人从存储库中取出数据,并且远程存储是裸仓库 ,那么您可以执行非快进提交。
git reset --hard <last_good_commit> git push --force
这会使得reflog在你的系统和上游主机上保持不变,但是你的坏提交将会从直接访问的历史logging中消失,并且不会在pull上传播。 旧的修改会一直存在,直到修改版本库,但只有Git ninjas才能看到或恢复错误提交。
如果你已经把东西推到了远程服务器上(并且你有其他开发者在同一个远程分支上工作),要记住的重要一点是你不想重写历史
不要使用git reset –hard
您需要还原更改,否则任何在其历史logging中删除提交的结帐将在下次推送时将其添加回远程存储库; 而其他任何结账都会在下一次拉动时将其拉入。
如果您尚未将更改推送到远程,则可以使用
git reset --hard <hash>
如果您推动了更改,但是确定没有人拉动它们,您可以使用
git reset --hard git push -f
如果您推送了更改,并且有人将其拖入了结帐,您仍然可以执行此操作,但其他团队成员/结帐需要协作:
(you) git reset --hard <hash> (you) git push -f (them) git fetch (them) git reset --hard origin/branch
但总的来说,这变成了一团糟。 所以,恢复:
承诺删除是最新的
这可能是最常见的情况,你做了一些事情 – 你把它们推出来,然后意识到它们不应该存在。
首先,您需要确定您想要返回的提交,您可以通过以下操作执行此操作:
git log
只需在更改之前查找提交,并记下提交哈希。 您可以使用-n
标志将日志限制为最新的提交: git log -n 5
然后重置您的分支到您希望其他开发人员看到的状态:
git revert <hash of first borked commit>..HEAD
最后一步是创build自己的本地分支,重新应用您还原的更改:
git branch my-new-branch git checkout my-new-branch git revert <hash of each revert commit> .
继续在my-new-branch
工作,直到完成,然后将其合并到主开发分支中。
承诺删除与其他承诺混合
如果您想要还原的提交不在一起,则可能最容易单独还原它们。 再次使用git log
查找要删除的提交,然后:
git revert <hash> git revert <another hash> ..
然后,再次创build你的分支继续你的工作:
git branch my-new-branch git checkout my-new-branch git revert <hash of each revert commit> .
然后,当你完成后,再次破解并合并。
你最终应该在my-new-branch
上看到一个提交历史
2012-05-28 10:11 AD7six o [my-new-branch] Revert "Revert "another mistake"" 2012-05-28 10:11 AD7six o Revert "Revert "committing a mistake"" 2012-05-28 10:09 AD7six o [master] Revert "committing a mistake" 2012-05-28 10:09 AD7six o Revert "another mistake" 2012-05-28 10:08 AD7six o another mistake 2012-05-28 10:08 AD7six o committing a mistake 2012-05-28 10:05 Bob I XYZ nearly works
更好的方式®
特别是现在你已经意识到在同一个分支工作的几个开发人员的危险,所以请考虑使用function分支总是为你的工作。 所有这一切意味着在一个分支中工作,直到完成任务,然后才将其合并到主分支。 还要考虑使用诸如git-flow之类的工具来以一致的方式自动创build分支。
git revert HEAD -m 1
在上面的代码行。 “最后一个参数代表”
- 1 – 恢复一个提交。 2 – 恢复最后的提交。 n – 恢复最后n个提交
要么
git reset –hard siriwjdd