【问题标题】:Is there a quick way to "git diff" from the point or branch origin?有没有一种从点或分支原点“git diff”的快速方法?
【发布时间】:2015-06-30 20:44:56
【问题描述】:

我查看了有关使用 git diff 和 git 修订版(HEAD、ORIG_HEAD、FETCH_HEAD 等)的各种 SO 答案,但我仍然没有找到一种简单的方法来列出自本地分支,或自上次变基以来。

简单我的意思是不必查找和粘贴提交 SHA,也不必计算我想回顾多少次提交。

git diff origin/master 很接近,但它指的是远程,因为我从中签出新分支后可能已经分歧。

我希望像 git diff BASE_HEAD 这样的东西可用。

...除非已经有办法做到这一点。有人知道答案吗?

【问题讨论】:

  • 您想与上游的合并库进行比较,请使用 @{u} 和三点语法。试试git diff @{u}...HEAD
  • stackoverflow.com/questions/1527234/…,林德斯回答。您可能也对其他答案感兴趣。

标签: git git-diff


【解决方案1】:

使用git diff @{u}...HEAD,三个点。

使用两个点,或省略HEAD,它将显示两侧更改的差异。

用三个点,它只会显示你身边的变化差异。

编辑:对于需求略有不同的人,您可能对git merge-base 感兴趣(请注意,它比其他答案使用的选项多得多)。

【讨论】:

  • @o11c 在哪里使用您的解决方案指定分支名称?
  • 我认为使用上游可能会令人困惑。为什么不只是git diff master...HEAD
  • @{u} 中的u 是什么意思?
  • @TorKlingberg 是@{upstream}的缩写,这一切都记录在git rev-parse --help
  • @TaylorEdmiston 我试过这个,但我没有看到问题。 git diff 手册页还表明,由于 merge-base,您不应该看到在分支点之后对 master 所做的更改: "git diff A...B" 相当于 " git diff $(git-merge-base AB) B".您确定您使用的是 3 个点吗?
【解决方案2】:

您可以使用git merge-base 找到分支点。考虑master 主线和dev 您对其历史感兴趣的分支。要找到devmaster 分支的点,请运行:

git merge-base --fork-point master dev

我们现在可以在此基础上区分dev

git diff $(git merge-base --fork-point master dev)..dev

如果dev当前分支,则简化为:

git diff $(git merge-base --fork-point master)

有关详细信息,请参阅git-merge-base documentation

【讨论】:

  • 请注意,一旦dev 分支合并到mastergit merge-base 将不会返回任何输出。为此,请参阅:stackoverflow.com/questions/30560256/…
  • 如果您的基地不是master,这将不起作用。如果你不记得哪个分支是基地,那又是什么?
  • @PatrickParker,git 不存储“哪个分支来自哪个分支”,因此它无法自行推断。
【解决方案3】:

您可以使用以下方法从分支起点区分当前分支:

git diff (start point)...

其中(起点)是分支名称、提交 ID 或标签。

例如,如果您正在处理从 develop 分支的功能分支,您可以使用:

git diff develop...

对于当前分支自分支点以来的所有更改。

这已经在评论中提到,但我认为它值得回答。我不知道自上次 rebase 以来它会做什么。

【讨论】:

    【解决方案4】:

    对于差异,您需要三点表示法。如果您的分支称为dev 并且它从master 分支:

    % git diff master...dev
    

    对于日志,您需要两点符号:

    % git log master..dev
    

    修订语法r1..r2(带两个点)表示“从r2(含)可访问的所有内容,但不能从r1(含)访问”。使用它的正常方法是将r1r2 视为指定提交序列中的范围(r1 独占,r2 包括),因此如果您有 10 个修订版,3..7 将显示您更改了 4、5、6 和 7。它是 {1, 2, 3, 4, 5, 6, 7} 减去 {1, 2, 3}。但是r1 不一定是r2 的祖先。把它想象成一个集合操作,其中r1 表示从r1 向后的整个祖先,r2 表示从r2 向后的整个祖先,并且你从第二组中减去第一组。

    那么:

    git log master..dev
    

    是分支的全部历史减去 master 的全部历史。换句话说,只是分支。

    【讨论】:

      【解决方案5】:

      在 Visual Studio 2017 中,有一种显示差异的舒适方式:

      1. Team Explorer -> Branches 中右键单击分支并选择 View History

      1. History - branch 控件中选择您想要比较的提交并选择 Compare Commits

      你会得到一个很好的差异概览,你可以在比较模式下打开文件。

      【讨论】:

        【解决方案6】:

        对比远程主分支:

        git diff $(git merge-base HEAD origin/master)..
        

        【讨论】:

          【解决方案7】:

          current solution 提及

          使用git diff @{u}...HEAD,带有三个点。

          但是...最好使用 Git 2.28(2020 年第三季度)来完成。
          之前,“git diff”用于接受随机和无意义范围表示法的参数,例如“git diff A..B C”、“git diff A..B C...D”等,已清理完毕。

          参见Chris Torek (chris3torek)@commit b7e10b2commit 8bfcb3a(2020 年 6 月 12 日)和 commit bafa2d7(2020 年 6 月 9 日)。
          (由 Junio C Hamano -- gitster -- 合并于 commit 1457886,6 月 25 日2020)

          git diff:改进范围处理

          签字人:Chris Torek

          git diff 被赋予对称差异A...B 时,它会从两个指定的提交中选择一些合并基础(如文档所述)。

          但是,如果 没有 合并基础,这将失败:相反,您会看到 A 和 B 之间的差异,这肯定不是预期的。

          此外,如果在命令行(“git diff A...B C”)上指定了额外的修订,结果会有点奇怪:

          • 如果存在对称的差异合并基,则将其用作差异的左侧。
            最后一个最终的 ref 用作右侧。

          • 如果没有合并基,则完全失去对称状态。
            我们将生成一个组合差异。

          如果您使用例如“git diff C A...B D”,也会出现类似的奇怪现象。同样,使用多个两点范围,或者将额外的修订说明符扔到带有两点范围的命令行中,或者混合使用两个和三个点范围,都会产生废话。

          为避免这一切,请添加一个例程来捕获范围情况并验证参数是否有意义。

          作为一个副作用,当有多个选择时,产生一个警告,显示 which 正在使用合并基础;没有合并基础就死。

          The documentation 现在包括:

          'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...]:

          此表单用于查看合并提交的结果。

          第一个列出的必须是合并本身;剩下的两个或更多提交应该是它的父母。
          生成所需修订集的一种便捷方法是使用 {caret}@ 后缀。
          例如,如果master 命名一个合并提交,git diff master master^@ 给出与git show master 相同的组合差异。

          【讨论】:

            【解决方案8】:

            我在.gitconfig 中写了一个别名来解决这个任务:

            [alias]
                # See changes since branching off of main branch
                changes = "!f() { \
                    current=$(git rev-parse --abbrev-ref HEAD); \
                    main=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'); \
                    commit=$(git merge-base --fork-point \"$main\" \"$current\"); \
                    git diff \"$commit\"...; \
                }; f"
            

            逐行,这个别名:

            1. 定义一个shell函数f,它
            2. 计算当前分支名称,
            3. 计算主分支名称(可以是 main、master、develop 等),
            4. 计算这两个分支分歧的提交,并且
            5. 运行 git diff 以查看自此提交以来的更改

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-26
              • 2021-06-11
              • 2016-03-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多