代码之家  ›  专栏  ›  技术社区  ›  RobM

如何在Git-Rebase期间通过哈希识别冲突提交?

  •  38
  • RobM  · 技术社区  · 15 年前

    当我遇到合并冲突时,使用 git rebase ,我如何确定冲突的根源 在承诺方面 而不仅仅是文件差异?

    我已经知道如何(基本)利用 git mergetool git add 之前 git rebase --continue 但有时文件之间的差异还不够:我想查看提交日志和提交的差异,这些差异未能应用到工作树。

    我读过其他问题 git log --merge 如果我使用 git merge . 当我遇到冲突时,我无论如何都试过了,结果被告知 fatal: --merge without MERGE_HEAD? .

    我如何确定有问题的承诺?

    6 回复  |  直到 6 年前
        1
  •  38
  •   Alex Brown    15 年前

    简短回答

    如果它说

    Patch failed at 0001 commit message for F
    

    然后运行

    $ head -1 .git/rebase-apply/0001
    From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001
    

    得到SHA ad1c77 失败的提交,然后使用 git show ad1c77 来看看。

    长回答

    让我们从这棵树开始:

    A---B---C---D
         \
          E---F---G
    
    $ git checkout G
    $ git rebase D
    

    当发生钢筋冲突时,它是

    • 上游变化( C--D )来自共同的祖先( B ) 加上 已经重新平衡的变化和已经解决的冲突( E' ) 对战
    • 下一次提交的补丁( F )

    让我们看看会发生什么:

    1) A---B---C---D---E'          <- E patched and committed successfully as E'
    2) A---B---C---D---E'---       <- failed to patch F onto E'
    

    以下是错误消息:

    First, rewinding head to replay your work on top of it...
    Applying: commit message for F
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merging 1.txt
    CONFLICT (content): Merge conflict in 1.txt
    Failed to merge in the changes.
    Patch failed at 0001 commit message for F
    

    首先,你可以看到 F ,因为出现提交消息。但是,如果您的提交消息看起来都是“foo”、“documentation”或“some fixes”,那么这将没有帮助,您真的需要sha id AD1C77 或者补丁的内容。

    以下是如何找出 f 以下内容:

    当它列出了钢筋冲突时,它会说:

    F的0001提交消息处修补失败
    

    现在看看 .git/rebase-apply/ ,在那里可以找到补丁文件 0001 :

    $ ls .git/rebase-apply
    0001          head-name     msg           orig-head     sign
    0002          info          msg-clean     patch         threeway
    apply-opt     keep          next          quiet         utf8
    final-commit  last          onto          rebasing
    

    补丁文件包含原始提交ID

    $head-1.git/rebase应用/0001
    AD1C7739C1152502229E3F2AB759EC5323988326 2001年9月17日周一00:00:00
    

    你可以看看那个。

    一定有更简单的方法,但这是可行的。

    请注意,修补程序失败的原因可能是由于不同的提交(如果您正在重新定位到 HEAD 以及Rebase目标)。找到提交要复杂得多,尽管您可以尝试反向执行REBASE来找到它:

    $ git checkout D
    $ git rebase G
    
        2
  •  8
  •   javabrett    8 年前

    在A期间 git rebase 这将停止以解决冲突,以下命令将显示冲突提交(所有提交,而不仅仅是冲突文件),也就是说,您的提交当前正被重放/重新定位到新的基础上,而不管您在哪里:

    git show $(< .git/rebase-apply/original-commit)
    

    如果只想查看特定冲突文件(您正在解决的文件)的冲突,请单独查看:

    git show $(< .git/rebase-apply/original-commit) -- /path/to/conflicting/file
    

    在构建这个答案的过程中没有猫被虐待。

        3
  •  2
  •   Alexander Bird    10 年前
    cat .git/rebase-apply/original-commit
    

    鉴于此:

    A---B---C---D
         \
          E---F---G
    
    $ git checkout G
    $ git rebase D
    

    考虑到合并冲突试图应用f:

    A---B---C---D--E'--!
         \
          E---F---G
    

    然后 original-commit 文件将显示F的哈希值。这是他们的版本。

    此外,在这种情况下,head(.git/head)将是e'。这是我的版本。头^将是“基本”版本。

    至少1.7.9吉特是这样的。

        4
  •  2
  •   redbmk    6 年前

    显示当前/失败的提交

    这可能是一个新功能,但是 REBASE_HEAD 提供当前停止的提交(例如,如果提交未能应用)。如果您希望看到完整的提交,可以使用

    git show REBASE_HEAD
    

    作为一种更详细的选择,您可以使用 git rebase --show-commit-patch .医生说他们是等效的。

    显示您开始工作后发生的更改

    如果你想知道你从哪里重新平衡和从哪里重新平衡之间发生了什么变化,你可以在两个分支之间得到一个差异。例如,如果从 master 到上面 origin/master 你可以使用:

    git diff master..origin/master
    

    或者,如果希望将更改视为单个提交:

    git log -p master..origin/master
    

    如果您希望使用哈希,或者可能在一段时间后返回到一个重新平衡,并且不记得要重新平衡的分支,则可以使用 git status 看看这两个分支。例如:

    您当前正在重新设置“b5284275”上的“master”分支

    然后,要查看更改内容,可以使用:

    git diff master..b5284275
    
        5
  •  1
  •   Justin C    10 年前

    不知道为什么我没有 .git/rebase-apply 在我的情况下。对于同样情况的人,这是我的变化。

    git show $(cat .git/rebase-merge/stopped-sha)
    

    或者化名…

    git config --global alias.sp='!git show $(cat .git/rebase-merge/stopped-sha)'
    
        6
  •  0
  •   Senseful    6 年前

    很多时候,你会处于一个平衡的中间,想要跳过那些不需要的提交。

    不幸的是,虽然 git status 告诉您正在提交,并建议使用 git rebase --continue git rebase --skip git rebase --abort ,它不会告诉您当前正在进行什么提交。

    所以有时候很难知道你是否应该 git-rebase--跳过 或者没有。

    但是,仍然有一种方法可以通过运行以下命令来确定您正在执行的提交:

    git log -1 $(< .git/rebase-apply/original-commit)