【问题标题】:How can I get a side-by-side diff when I do "git diff"?执行“git diff”时如何获得并排差异?
【发布时间】:2011-12-01 23:13:39
【问题描述】:

当我输入“git diff”时,我希望看到一个并排的差异,例如“diff -y”,或者希望在交互式差异工具中显示差异,例如“kdiff3”。如何做到这一点?

【问题讨论】:

标签: git git-diff code-visualization


【解决方案1】:

试试 git difftool

使用git difftool 而不是git diff。你永远不会回去。

更新添加示例用法:

这是另一个讨论 git difftool 的 stackoverflow 的链接:How do I view 'git diff' output with my preferred diff tool/ viewer?

对于较新版本的gitdifftool 命令支持许多开箱即用的外部差异工具。例如vimdiff 是自动支持的,可以通过以下方式从命令行打开:

cd /path/to/git/repo
git difftool --tool=vimdiff

其他受支持的外部差异工具通过git difftool --tool-help 列出,这是一个示例输出:

'git difftool --tool=<tool>' may be set to one of the following:
        araxis
        kompare
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        bc3
        codecompare
        deltawalker
        diffuse
        ecmerge
        emerge
        gvimdiff
        gvimdiff2
        kdiff3
        meld
        opendiff
        tkdiff
        xxdiff

【讨论】:

  • 或者如果你得到This message is displayed because 'diff.tool' is not configured.,你可能会回去。也许用最少的如何配置这个东西来更新答案,以便它在终端中并排显示差异,这是 OP 要求的? GUI 工具在您使用 ssh 连接的远程服务器上毫无用处。
  • 有趣的一点,虽然我认为我个人不需要在 SSH 时使用 git。 DVCS 的优点之一是分布式部分:至少在我的环境中,本地克隆我想要探索的任何 repo 从来都不是一件麻烦事。
  • 至少在我的配置中,git difftoolvimdiff 并不总是正确地排列两个文件/缓冲区。
  • 很好,所以在答案列表下面:O 我使用git difftool -y 来防止 tkdiff 提示
  • 相关:在 Windows 和 Linux 中融合您的 git difftoolstackoverflow.com/a/48979939/4561887
【解决方案2】:

虽然 Git 有一个 diff 的内部实现,但您可以设置一个外部工具来代替。

指定外部差异工具有两种不同的方法:

  1. 设置GIT_EXTERNAL_DIFFGIT_DIFF_OPTS 环境变量。
  2. 通过git config配置外部差异工具

ymattw的回答也很简洁,使用ydiff

另见:

在执行git diff 时,Git 会检查上述环境变量的设置及其.gitconfig 文件。

默认情况下,Git 将以下七个参数传递给 diff 程序:

path  old-file  old-hex old-mode  new-file  new-hex new-mode

您通常只需要 old-file 和 new-file 参数。当然,大多数 diff 工具只接受两个文件名作为参数。这意味着您需要编写一个小的包装脚本,它将 Git 提供给脚本的参数传递给您选择的外部 git 程序。

假设您将包装脚本放在~/scripts/my_diff.sh 下:

#!/bin/bash
# un-comment one diff tool you'd like to use

# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5" 

# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"

# using Meld 
/usr/bin/meld "$2" "$5"

# using VIM
# /usr/bin/vim -d "$2" "$5"

然后您需要使该脚本可执行:

chmod a+x ~/scripts/my_diff.sh

然后您需要告诉 Git 如何以及在哪里找到您的自定义差异包装脚本。 你有三个选择如何做到这一点:(我更喜欢编辑 .gitconfig 文件)

  1. 使用GIT_EXTERNAL_DIFFGIT_DIFF_OPTS

    例如在您的 .bashrc 或 .bash_profile 文件中,您可以设置:

     GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
     export GIT_EXTERNAL_DIFF
    
  2. 使用git config

    使用“git config”来定义你的包装脚本可以在哪里找到:

     git config --global diff.external ~/scripts/my_diff.sh
    
  3. 编辑您的 ~/.gitconfig 文件

    您可以编辑您的 ~/.gitconfig 文件以添加以下行:

     [diff]
       external = ~/scripts/my_diff.sh
    

注意:

与安装自定义 diff 工具类似,您也可以安装自定义合并工具,它可以是一个可视化合并工具,以更好地帮助可视化合并。 (参见 progit.org 页面)

请参阅:http://fredpalma.com/518/visual-diff-and-merge-tool/https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration

【讨论】:

  • 这是否保留了 git 终端着色?
  • 这很棒,但它会为每个文件启动一个新的查看器。有什么方法可以在meld 中创建合并差异?
  • @Tilo 我收到 vim 错误作为 im:警告:输出不是终端
  • 可以将meld 版本配置为执行目录差异,我可以在其中选择要查看差异的文件吗?目前它为每个文件运行一个单独的meld 命令,我必须退出meld 才能查看下一个文件。我宁愿让meld 向我显示更改文件的目录列表,就像在 Mercurial 中使用 meld 时一样。
  • 我不想对这个答案投反对票。但是 ymattw 的答案很容易实现。
【解决方案3】:

你也可以试试git diff --word-diff。 它不完全是并排的,但在某种程度上更好,因此您可能更喜欢它而不是您实际的并排需要。

【讨论】:

  • 这是最简单的方法。更好的是git diff --word-diff=color
  • @Rolf --word-diff=color 给了我一个无效的选项错误。它是在哪个版本中引入的?
  • @Trengot 我从 02/2012 运行 git 1.7.9
  • @Rolf 默认安装的版本是 1.7.1。可以解释差异。 git diff --color-words 确实有效。
  • 是的,git diff --color-words 是现代 git 版本的方式。
【解决方案4】:

ydiff

以前叫cdiff,这个工具可以显示并排增量彩色差异。

不要做git diff,而是做:

ydiff -s -w0

这将为每个有差异的文件以并排显示模式启动ydiff

安装方式:

python3 -m pip install --user ydiff

-或-

brew install ydiff

对于git log,您可以使用:

ydiff -ls -w0

-w0 自动检测您的终端宽度。有关详细信息和演示,请参阅ydiffGitHub repository page

在 Git 2.18.0、ydiff 1.1 中测试。

【讨论】:

  • @RyneEverett:你能解释一下如何用 icdiff 做相当于git diff | cdiff -s 的操作吗?
  • 只需从 git/svn/hg 工作区运行 ydiff -s,您不必输入管道。
  • 如果你想通过 Git 的历史记录限制 diff 到特定文件,cd &lt;git repo&gt; 然后运行ydiff -ls &lt;path/to/file&gt;
【解决方案5】:

您可以使用sdiff 并排使用diff,如下所示:

$ git difftool -y -x sdiff  HEAD^ | less

HEAD^ 是一个示例,您应该将其替换为您想要比较的任何内容。

我在here 找到了这个解决方案,其中还有一些其他建议。但是,这个答案简洁明了地是OP的问题。

请参阅man git-difftool 以获得对参数的解释。


使用 cmets,您可以通过编写以下可执行脚本来创建方便的git sdiff 命令:

#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less

将其另存为/usr/bin/git-sdiffchmod +x。然后你就可以这样做了:

$ git sdiff HEAD^

额外提示

按照 cmets 中的建议,您可以使用 icdiff 来执行 sdiff 对彩色输出所做的操作:

$ more /usr/bin/git-sdiff
#!/bin/sh
git difftool -y -x "icdiff --cols=$(tput cols)" "${@}" | less

【讨论】:

    【解决方案6】:
    export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'
    

    然后简单地说:

    git diff
    

    【讨论】:

    • `融合。'也有效!它会在一个合并的窗口中显示所有更改。
    • @HRJ 完美运行!如此简单实用:)
    【解决方案7】:

    对于 unix,只需结合 git 和内置的 diff

    git show HEAD:path/to/file | diff -y - path/to/file
    

    当然,您可以将 HEAD 替换为任何其他 git 引用,并且您可能希望在 diff 命令中添加类似 -W 170 的内容。

    这假设您只是将目录内容与过去的提交进行比较。比较两个提交更复杂。如果你的 shell 是bash,你可以使用“进程替换”:

    diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)
    

    REF1REF2 是 git 引用——标签、分支或哈希。

    【讨论】:

    • 谢谢——你的命令 'git show HEAD:path/to/file' 是我想出自己的解决方案所需要的,'vimdfiff
    【解决方案8】:

    如果您想在不涉及 GitHub 的情况下在浏览器中查看并排差异,您可能会喜欢 git webdiff,这是 git diff 的直接替代品:

    $ pip install webdiff
    $ git webdiff
    

    tkdiff 等传统 GUI 差异工具相比,它具有许多优势,因为它可以为您提供语法突出显示和显示图像差异。

    阅读更多关于它的信息here

    【讨论】:

      【解决方案9】:

      我使用colordiff

      在 Mac OS X 上,使用

      安装它
      $ sudo port install colordiff
      

      在 Linux 上可能是 apt get install colordiff 或类似的名称,具体取决于您的发行版。

      然后:

      $ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD
      

      或者创建一个别名

      $ git alias diffy "difftool --extcmd=\"colordiff -ydw\""
      

      那你就可以用了

      $ git diffy HEAD^ HEAD
      

      我称它为“diffy”,因为diff -y 是 unix 中的并行 diff。 Colordiff 还添加了更好的颜色。 在选项-ydw 中,y 用于并排,w 用于忽略空格,d 用于产生最小差异(通常您会得到更好的差异结果)

      【讨论】:

      • 添加-y 以跳过Launch 'colordiff' [Y/n]: 提示符。
      • 你确定是git alias diffy "difftool --extcmd=\"colordiff -ydw\""?不应该是git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""吗?
      【解决方案10】:

      我最近实现了一个工具,可以做到这一点:https://github.com/banga/git-split-diffs

      使用方法如下:

      npm install -g git-split-diffs
      
      git config --global core.pager "git-split-diffs --color | less -RFX"
      

      这就是它在您的终端中的外观(使用默认主题):

      如您所见,它还支持语法高亮和高亮行内更改的单词

      【讨论】:

      • 哇。这个工具太棒了。谢谢你的精彩!
      • 但它有点慢,加载一个文件需要 2 秒
      • github.com/banga/git-split-diffs#performance 有一些关于性能的注释,但如果这看起来不同,如果您能提出问题,那就太好了。谢谢!
      【解决方案11】:

      我个人非常喜欢icdiff

      如果您在 Mac OS XHomeBrew 上,只需使用 brew install icdiff

      为了正确获取文件标签,以及其他很酷的功能,我在我的~/.gitconfig

      [pager]
          difftool = true
      [diff]
          tool = icdiff
      [difftool "icdiff"]
          cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"
      

      我像这样使用它:git difftool

      【讨论】:

        【解决方案12】:

        当我在寻找一种使用 git 内置方式来定位差异的快速方法时,出现了这个问题。我的解决方案标准:

        • 快速启动,需要内置选项
        • 可以轻松处理多种格式,xml,不同的编程语言
        • 快速识别大文本文件中的小代码更改

        我找到this answer 在 git 中获取颜色。

        为了获得并排差异而不是行差异,我在这个问题上使用以下参数调整了 mb14 的优秀 answer

        $ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"
        

        如果你不喜欢额外的 [- 或 {+ 选项--word-diff=color 可以使用。

        $ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color
        

        这有助于正确比较 json 和 xml 文本以及 java 代码。

        总之,--word-diff-regex 选项与颜色设置一起具有有用的可见性,与标准行差异相比,在浏览带有小行更改的大文件时,可以获得彩色的并排源代码体验。

        【讨论】:

          【解决方案13】:

          其他几个人已经提到了cdiff 用于 git 并排比较,但没有人给出它的完整实现。

          设置 cdiff:

          git clone https://github.com/ymattw/cdiff.git
          cd cdiff
          ln -s `pwd`/cdiff ~/bin/cdiff
          hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
                  # or just create a new terminal
          

          编辑 ~/.gitconfig 插入这些行:

          [pager]
                  diff = false
                  show = false
          
          [diff]
                  tool = cdiff
                  external = "cdiff -s $2 $5 #"
          
          [difftool "cdiff"]
                  cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"
          
          [alias]
                  showw = show --ext-dif
          

          cdiff 需要关闭寻呼机才能与 Diff 一起使用,无论如何它本质上是一个寻呼机,所以这很好。无论这些设置如何,Difftool 都可以工作。

          需要显示别名,因为 git show 仅通过参数支持外部差异工具。

          diff 外部命令末尾的“#”很重要。 Git 的 diff 命令将 $@(所有可用的 diff 变量)附加到 diff 命令,但我们只需要两个文件名。所以我们用 $2 和 $5 明确地调用这两个,然后将 $@ 隐藏在注释后面,否则会混淆 sdiff。导致如下错误:

          fatal: <FILENAME>: no such path in the working tree
          Use 'git <command> -- <path>...' to specify paths that do not exist locally.
          

          现在产生并排比较的 Git 命令:

          git diff <SHA1> <SHA2> 
          git difftool <SHA1> <SHA2>
          git showw <SHA>
          

          Cdiff 用法:

          'SPACEBAR' - Advances the page of the current file.
          'Q'        - Quits current file, thus advancing you to the next file.
          

          您现在可以通过 git diff 和 difftool 获得并行差异。如果需要,您还有用于高级用户自定义的 cdiff python 源代码。

          【讨论】:

            【解决方案14】:

            这是一种方法。如果你通过更少的管道,xterm 宽度设置为 80,这不是那么热。但是,如果您继续执行命令,例如COLS=210,您可以使用扩展的 xterm。

            gitdiff()
            {
                local width=${COLS:-$(tput cols)}
                GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
            }
            

            【讨论】:

            • 有趣。我用化名签了名,但被忽略了……谢谢你,Stack Overflow。 :(
            【解决方案15】:

            打开Intellij IDEA,在“版本控制”工具窗口中选择单个或多个提交,浏览更改的文件,然后双击它们以并排检查每个文件的更改。

            使用捆绑的命令行启动器,您可以通过简单的idea some/path 在任何地方启动 IDEA

            【讨论】:

              【解决方案16】:

              这可能是一个有限的解决方案,但在没有外部工具的情况下使用系统的diff 命令可以完成这项工作:

              diff -y  <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
              
              • 仅过滤使用--suppress-common-lines 的更改行(如果您的diff 支持该选项)。
              • 在这种情况下没有颜色,只有通常的 diff 标记
              • 可以调整列宽--width=term-width;在 Bash 中可以得到宽度为$COLUMNStput cols

              为了更方便,也可以将其包装到辅助 git-script 中,例如,这样的用法:

              git diffy the/file/path --from rev1 --to rev2
              

              【讨论】:

                【解决方案17】:

                这个帖子上有很多很好的答案。我对这个问题的解决方案是编写一个脚本。

                将此“git-scriptname”命名(并使其可执行并将其放入 PATH 中,就像任何脚本一样),您可以像普通 git 命令一样通过运行来调用它

                $ git scriptname
                

                实际功能只是最后一行。这是来源:

                #!/usr/bin/env zsh
                #
                #   Show a side-by-side diff of a particular file how it currently exists between:
                #       * the file system
                #       * in HEAD (latest committed changes)
                
                function usage() {
                    cat <<-HERE
                    USAGE
                
                    $(basename $1) <file>
                
                    Show a side-by-side diff of a particular file between the current versions:
                
                        * on the file system (latest edited changes)
                        * in HEAD (latest committed changes)
                
                HERE
                }
                
                if [[ $# = 0 ]]; then
                    usage $0
                    exit
                fi
                
                file=$1
                diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-11-25
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-06-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-12-22
                  相关资源
                  最近更新 更多