如何为 "pull --rebase" 冲突重新启动合并

How to restart merge for a "pull --rebase" conflict

我正在开发基于 Eclipse Foundation 的 JGit 的 Git 插件,我已经实现了“Restart merge”由一位同事在尝试执行默认拉取(使用合并)时发生冲突。

现在我正在执行“拉动(变基)”操作。当发生冲突并且用户在冲突文件中进行了一些更改时,我想让他们能够重新开始合并。我注意到一些 Git 客户端没有这个选项(Eclipse 的 EGit,GitKraken Free),而有些有(SourceTree)。

我当前的代码如下所示:

public void restartMerge() {
    try {
      RepositoryState repositoryState = getRepository().getRepositoryState();
      String revision = repositoryState == RepositoryState.REBASING_MERGE ? "HEAD" : "MERGE_HEAD";
      AnyObjectId commitToMerge = getRepository().resolve(revision);
      git.clean().call();
      git.reset().setMode(ResetType.HARD).call();

      if (repositoryState == RepositoryState.REBASING_MERGE) {
        // TODO: regenerate the conflict
      } else {
        git.merge().include(commitToMerge).setStrategy(MergeStrategy.RECURSIVE).call();
      }

      fireFileStateChanged(new ChangeEvent(GitCommand.MERGE_RESTART, Collections.<String> emptyList()));
    } catch (IOException | NoRepositorySelected | GitAPIException e) {
        if (logger.isDebugEnabled()) {
            logger.debug(e, e);
        }
    }
}

我想我必须再次做一个变基,或者类似的东西,重新产生冲突,就像我的同事做了一个新的 merge() 一样。但是此时我处于一个分离的 HEAD ...我尝试移动到 master 分支并再次重新设置 origin/master 作为上游,但它没有用...

Git 命令用于重新启动变基冲突是什么?也许我可以使用 JGit...

执行它们

您可以尝试 运行 git rebase --abort,然后根据您的情况使用 git pull --rebase 重新启动 rebase。

如您所见,git pull 基本上是:

  • 运行 git fetch
  • 然后 运行 第二个 Git 命令,通常但不总是 git merge

合并可能因冲突而停止。您可以允许用户修复冲突并继续,或者中止合并并将所有内容恢复到合并开始前的状态:

  • 要允许用户在手动修复冲突后继续,您只需调用 git merge --continuegit commitgit merge --continue 本身会验证是否存在正在进行的合并,其中解决冲突,然后调用 git commit.
  • 要在获取之后但合并之前中止并恢复原状,您可以使用 git merge --abortgit reset --merge(它们做同样的事情)。

虽然第二个命令可以是git rebase,它也可以因冲突而停止。在某些极端情况下,它甚至可以是 git read-tree。因为在使用 git pull 时你几乎没有控制权,我建议 永远不要 以编程方式使用它:如果你正在编写 运行s Git 命令,总是 将您的操作拆分为 git fetch 和您自己以编程方式选择的第二个 Git 命令,以便您知道您 运行.

不过,rebase 的问题在于它本质上是由一系列 git cherry-pick 操作构建的。 (取决于你调用 git rebase 的方式,这实际上可能是 git apply --3way 而不是 git cherry-pick,或者它可能是 运行 git cherry-pick。) Each cherry-pick 操作可以因合并冲突而停止。所以你不只是有一个冲突,而是 M 个冲突,M ≤ N,其中 N是 rebase 复制到新位置的提交数。

要在用户修复冲突后恢复变基,请调用 git rebase --continue。这将验证是否存在正在进行的变基并且冲突已修复,并提交它们并继续进行下一个 cherry-pick 操作。变基一直持续到它遇到另一个合并冲突,或者已经完成所有的 cherry-picks;完成最后一次 cherry-pick 后,rebase 将分支名称的值重新分配给最后复制的提交,并将 HEAD 重新附加到分支名称。

如果你使用 git rebase --abort,你告诉 Git 停止 cherry-picking 操作(包括所有尚未开始的操作)并回到你之前的状态 他们中的任何一个开始了。如果您允许用户解决合并冲突,请注意,这会丢弃 所有 目前已解决的精选,包括用户为解决冲突所做的所有工作。如果用户启用了 git rerere,则到目前为止已解决的合并结果会记录在重用缓存中,因此这并不总是太糟糕。

合并冲突没有很好的解决方案。如果有一种可靠的自动化方法,Git 早就做到了。