强制更新后的Git拉


332

我只是压缩了一些提交git rebase并执行了git push --force(我知道这是邪恶的)。

现在其他软件工程师有不同的历史记录,当他们执行时git pull,Git将合并。除了执行操作外,是否有办法解决此问题rm my-repo; git clone git@example.org:my-repo.git

我需要类似的相反的东西git push --force,但git pull --force没有给出预期的结果。


16
他们可以删除分支并重新创建分支,而不必删除整个仓库:git checkout master && git branch -D test && git checkout -b test origin/test
Florian Klein 2013年

1
可能的Force Git
gpoo 2015年

Answers:


509

接收新的提交

git fetch

重启

您可以使用重置本地分支的提交git reset

更改本地分支的提交:

git reset origin/master --hard

但是要小心,如文档所述:

重置索引和工作树。自<commit>以来,工作树中对跟踪文件的任何更改都将被放弃。

如果您想实际保留本地所做的任何更改,请--soft重置。这将更新分支的提交历史记录,但不会更改工作目录中的任何文件(然后您可以提交它们)。

变基

您可以使用git rebase以下命令在任何其他提交/分支之上重播本地提交:

git rebase -i origin/master

这将在交互模式下调用rebase,您可以在其中选择如何应用不在基础之上的每个单独提交。

如果您删除的提交(带有git push -f)已经被拉入本地历史记录,它们将被列为将被重新应用的提交-它们将需要作为重新设置的一部分被删除,或者它们将被简单地重新包含在历史记录中分支-并在下次推送时重新出现在远程历史记录中。

使用帮助可git command --help获取有关任何上述(或其他)命令的更多详细信息和示例。


2
@iblue在丢失所有更改,删除提交历史记录但保留文件更改或尝试将每个提交应用于新文件头之间进行选择。最简单的选项可能是软复位。
AD7six 2012年

1
@iblue当您的同事使用git reabse origin / master时,意味着他们之前已经进行过一些提交,git会将您的提交写到提交的后面。
蒂姆(Tim)

6
可能值得一提的是,如果这是另一个分支:git reset origin/otherbranch --hard
bmaupin

因此,要澄清,这是两种:方案1: reset --hard选项2:reset --soft+ rebase,对不对?
PlasmaBinturong

2
@PlasmaBinturong号git reset --soft origin/master将改变提交历史相匹配的远程和阶段的差异到远程随后被提交。在这种情况下,无需重新设置基准(由于未提交更改,因此您将无法这样做),因为提交历史记录没有差异。重置重置两个选项-不能同时使用。请提出一个问题,如果你的情况是一个比我在这里回答不同。
AD7six

16

这将无法修复已经在其中包含您不想要的代码的分支(请参见下文,了解如何执行此操作),但是如果他们已经拉了一些分支并且现在希望它是干净的(而不是“超前”)起源/分支),那么您只需:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

注意:您可以通过在它们之间加上&&来组合所有这些

注2:Florian在评论中提到了这一点,但是谁在寻找答案时会阅读评论?

注意3:如果分支受到污染,则可以基于新的“哑分支”创建新分支,而只是进行摘樱桃提交。

例如:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

现在,新功能是您的分支,无需额外的(可能是错误的)提交!


这就是我真正想要的。有人改变了主分支的基础(上帝知道原因),但是我没有要提交的本地更改或任何其他内容。因此,我要做的就是删除本地master分支(感觉很奇怪),然后再次签出。谢谢!
Danilo Carvalho

@彼得-莫特森编辑根据实质应该是stackoverflow.com/help/editing
汤姆·普拉斯

对于最后一步,你也可以使用git checkout -b base-branch origin/base-branch带有git checkout --track origin/base-branch
bluesmonk

1

拉底

常规提取是获取+合并,但您想要的是获取+重新设置基准。这是pull命令的一个选项:

git pull --rebase

我一直在使用它,以便将最新的代码从master拿到我的功能分支中,而不会在历史记录中包含所有这些合并提交。
赫尔曼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.