【问题标题】:How to get git diff with full context?如何获得完整上下文的 git diff?
【发布时间】:2012-11-17 15:12:38
【问题描述】:

如何创建适合在坩埚中查看的补丁?

git diff branch master --no-prefix > patch

这只会生成 3 行上下文。所以我做了以下

git diff --unified=2000 branch master --no-prefix > patch

希望所有文件的行数少于 2000 行。有没有办法告诉 git 将文件中的所有行都包含在补丁中,而不必指定最大行数?

【问题讨论】:

标签: git diff git-diff


【解决方案1】:

这在 macOS 上对我有用:

git diff -U$(wc -l main.htm | xargs)

"How to trim whitespace from a Bash variable?"

【讨论】:

    【解决方案2】:

    在查看特定文件/提交时,以前接受的解决方案对我不起作用(-U 选项似乎与 rev/path 解析混淆),但 --inter-hunk-context= 在这种情况下有效在git version 2.24.0:

    git diff \
        --no-prefix \
        --inter-hunk-context=2000 \
        master -- \
            path/to/file.py
    

    如果您不知道文件大小,当然可以使用wc -l 找到它,而不是硬编码:

    git diff \
        --no-prefix \
        --inter-hunk-context=$(wc -l path/to/file.py) \
        master -- \
            path/to/file.py
    

    【讨论】:

    • 对我来说,这只显示了第一次更改前的三行上下文和最后一次更改后的三行上下文。
    • 你使用的是什么版本的 git?您是否将“path/to/file.py”替换为您自己的文件路径?刚刚在 Windows 上的 git 2.12.1 上再次测试(第一个变体 2000 硬编码),它工作得很好。
    • 版本 2.24.3。是的,我做到了。但抱歉,让我澄清一下我的最后一条评论:您的解决方案(当然)还显示了(包括)更改的行之间的所有行,但我认为@Machavity 想要“包括文件中的所有行”。例如,在至少有五行的文件上尝试您的解决方案,并且在前四行之后对其进行所有更改。如果显示的内容包括文件的第一行,那么可能您将 Git 配置文件中的 diff.context 变量设置为大于默认值 3 的数字。
    【解决方案3】:

    得到灵感,所以我添加了一个 git 别名。

    $ cat ~/.gitconfig | fgrep diff
            df = "!git diff -U$(wc -l \"$1\" | cut -d ' ' -f 1) \"$1\""
    $ git df <file>
    

    更新:

    刚发现“git df”有时不起作用,由于执行 git alias 时目录更改。 (见git aliases operate in the wrong directory)。 所以这是更新版本:

    $ cat ~/.gitconfig | fgrep df
            df = "! [ \"$GIT_PREFIX\" != \"\" ] && cd \"$GIT_PREFIX\"; ~/bin/git_df.sh"
    $ 
    $ cat ~/bin/git_df.sh
    #!/bin/bash
    for FILE in $@; do
        git diff -U$(wc -l "${FILE}" | cut -d ' ' -f 1) "${FILE}"
    done
    exit 0
    

    【讨论】:

    • 对于单行别名:df = "!cd -- ${GIT_PREFIX:-.}; git diff -U$(wc -l \"$1\" | cut -d ' ' - f 1) \"$1\""
    【解决方案4】:

    我知道这是旧的,但我也不喜欢硬编码的解决方案,所以我测试了这个:

    git diff -U$(wc -l MYFILE)
    

    使用 -U 似乎是解决该问题的唯一方法,但使用行数可以保证即使在非常大的文件中进行很小的更改也可以工作。

    【讨论】:

    • &lt; 不是必需的。 git diff -U$(wc -l MYFILE) MYFILE
    • 谢谢@balki,我尝试了你的建议并注意到
      $(wc -l MYFILE)
      扩展为行数后跟文件名,所以第二次使用文件名也可以省略。我正在更新我的答案以反映这一点。
    • 这是一个差异,文件有两个版本。如果不在磁盘上的版本是原来的两倍怎么办?数字很​​大的 -U 不是更安全吗?
    • @Eloff,这是真的,最好的方法是最大化长度,因为真正的大数字仍然有相反的问题。此解决方案假定没有进行大于磁盘上当前文件大小的连续删除。
    • git diff -U$(wc -l MYFILE | awk '{print $1}') MYFILE 是一个更好的答案,它仅通过获取不带空格的行数,而不是依赖子shell 的未引用输出来创建两个参数,从而正确解析wc 的输出,并且可以正常工作在 macOS/BSD 上。
    【解决方案5】:

    This 似乎工作得很好:

    git diff --no-prefix -U1000
    

    需要注意的是:

    -U 标志指定上下文行。如果更改之间的行数超过 1000 行,则可能需要增加此值。

    【讨论】:

    • 您建议的-U 选项与提问者使用的--unified= 选项相同。唯一的区别是您指定的上下文行数 1000 比询问者使用的 2000 行数少。@balki 想知道如何将数字增加到无穷大,但您建议将数字减半。为什么?
    • @LS:是的,我现在意识到了,但几年前忽略了这一点。尽管如此,发生的事情比问题更明显,并且似乎对降落在这里的奇怪人有所帮助。
    • 感谢您,它也适用于 git show
    • @c24w 同意,仍然可以获得我想在屏幕上看到的内容。
    • --no-prefix 选项去掉了默认显示的“/a/”和“/b/”目标前缀。 (链接页面)
    【解决方案6】:

    注意:git1.8.1rc1 announce (December 8th, 2012) 包括:

    一个新的配置变量“diff.context”可用于在补丁输出中提供默认的上下文行数,以覆盖硬编码的默认值 3 行。

    这样可以帮助生成更完整的上下文。

    【讨论】:

    • 但没有选项说“文件中的所有行”
    • 我怀疑放一个大数字会模拟“所有的行”
    • “我怀疑放一个很大的数字,这会模拟“所有的线条””......除非它没有,然后事情就坏了。一切都是无限的同义词,一个非常大的数字就是这样——一个数字,而不是无限。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2012-05-14
    • 2011-12-01
    • 1970-01-01
    • 2015-11-10
    • 2011-11-12
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多