Git强制更新后拉

我只是用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没有给出预期的结果。

169088 次浏览

接收新的提交

git fetch

重置

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

修改本地分支的提交。

git reset origin/main --hard

但是要小心,正如文档所说:

重置索引和工作树。提交后工作树中被跟踪文件的任何更改被丢弃。

如果你真的想要保留你在本地得到的任何更改-做一个--soft重置。它将更新分支的提交历史,但不会更改工作目录中的任何文件(然后您可以提交它们)。

变基

你可以使用git rebase在任何其他提交/分支上重播你的本地提交:

git rebase -i origin/main

这将在交互模式下调用rebase,在这种模式下,您可以选择如何应用不在您所基于的历史记录中的每个单独的提交。

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

以上(或其他)命令的更多细节和示例,请使用帮助git command --help

这不会修复已经有你不想要的代码的分支(参见下面如何做),但如果他们已经拉了一些分支,现在想要它是干净的(而不是“在原点/一些分支之前”),那么你只需:

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:弗洛里安在评论中提到了这一点,但谁会在寻找答案时阅读评论呢?

注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

现在feature-new是没有额外(可能是坏的)提交的分支!

用rebase拉

常规的pull是fetch + merge,但你想要的是fetch + rebase。这是pull命令的一个选项:

git pull --rebase

在您的特定情况下,您不希望重新应用的提交已被删除。这必须手动完成。因此,rebase需要是交互式的,这样可以跳过这些提交:

git pull --rebase=interactive

或者从Git 2.26开始可以缩写为:

git pull --rebase=i

从远程存储库获取更改到本地repo:

git fetch

重命名跟踪分支:

git branch -m <old-branch-name> <new-name>

创建一个新的本地分支跟踪远程分支:

git checkout -b <old-branch-name>