How to get git diff with full context?

54,062

Solution 1

I know this is old, but I also dislike hard-coded solutions, so I tested this:

git diff -U$(wc -l MYFILE)

Using -U seems to be the only way to approach the issue, but using a line count promises that it will work for even a small change in a very large file.

Solution 2

This seems to work pretty nicely:

git diff --no-prefix -U1000

With the caveat:

The -U flag specifies lines of context. You might need to increase this if there are more than 1000 lines between your changes.

Solution 3

Note: git1.8.1rc1 announce (December 8th, 2012) includes:

A new configuration variable "diff.context" can be used to give the default number of context lines in the patch output, to override the hardcoded default of 3 lines.

so that could help, here, generate a more complete context.

Solution 4

Got inspiration and so I added a git alias.

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

Update:

Just found "git df" does not work sometimes, due to directory change when executing git alias. (See git aliases operate in the wrong directory). So this is the updated version:

$ 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

Solution 5

This worked for me on macOS:

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

see "How to trim whitespace from a Bash variable?"

Share:
54,062
balki
Author by

balki

A computer enthusiast.

Updated on July 30, 2022

Comments

  • balki
    balki over 1 year

    How to create patch suitable for reviewing in crucible?

    git diff branch master --no-prefix > patch
    

    This generates only 3 lines of context. So I do the following

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

    Hopefully all files will have less than 2000 lines. Is there a way to tell git to include all the lines in the file for patch without having to specify maximum lines?

  • balki
    balki over 11 years
    Yet that doesn't have an option to say 'All lines in the file'
  • VonC
    VonC over 11 years
    I suspect that putting a large number, that would simulate "all the lines"
  • Trenton
    Trenton over 8 years
    "I suspect that putting a large number, that would simulate "all the lines"" ... except when it doesn't and then things break. All is synonymous with infinite, and a very large number is just that -- a number, not infinity.
  • Mr. Lance E Sloan
    Mr. Lance E Sloan almost 8 years
    The -U option you suggest is the same as the --unified= option used by the asker. The only difference is that you specify fewer lines of context, 1000, than the asker used, 2000. @balki wanted to know how to increase the number to infinity, yet you suggest cutting the number in half. Why?
  • c24w
    c24w almost 8 years
    @LS: yep, I realise now, but overlooked that a couple of years ago. Still, it's a bit more apparent what's going on than in the question and seems to help the odd person who lands here.
  • Shakeel
    Shakeel almost 8 years
    Thanks for this, it also works great with git show!
  • Chef Pharaoh
    Chef Pharaoh almost 8 years
    @c24w Agreed, still gets me what I want to see on the screen.
  • balki
    balki over 7 years
    < is not necessary. git diff -U$(wc -l MYFILE) MYFILE
  • Ezra
    Ezra over 7 years
    Thanks @balki, I tried your suggestion and noticed that <pre>$(wc -l MYFILE)</pre> expands to the line count followed by the file name, so the second use of the filename can be omitted also. I'm updating my answer to reflect this.
  • flying sheep
    flying sheep over 7 years
    but it doesn’t answer the question at all, which is “Is there a way to tell git to include all the lines in the file for patch without having to specify maximum lines?”
  • luckydonald
    luckydonald over 6 years
    The --no-prefix option gets rid of the “/a/” and “/b/” destination prefixes that show up by default. (linked page)
  • Robino
    Robino over 6 years
    This works even less well than the OP's code for large files!
  • Eloff
    Eloff over 5 years
    It's a diff, there are two version of the file. What if the version not on the disk was twice as long? Isn't -U with a really big number actually safer?
  • Ezra
    Ezra over 5 years
    @Eloff, that's true, the best way would be to max the lengths, since really big numbers still have the opposite problem. This solution assumes that no contiguous deletions larger than the current file size on disk were made.
  • Ezra
    Ezra over 5 years
    We could work something in from this answer to do a shell calculated max: unix.stackexchange.com/a/186703 - in my mind, a user is probably going to put this in their git config as an alias, so it is acceptable to be verbose. Ideally, there would be a --full-context diff option built into git.
  • anishpatel
    anishpatel about 5 years
    git diff -U$(wc -l MYFILE | awk '{print $1}') MYFILE is a better answer that correctly parses the output of wc by only getting the number of lines without whitespace, not relying on the unquoted output of a subshell to create two arguments, and works on macOS/BSD.
  • Dr_Zaszuś
    Dr_Zaszuś about 5 years
    I believe this is a Linux command. What would you replace wc with on Windows?
  • fizzyh2o
    fizzyh2o over 3 years
    For a single line alias: df = "!cd -- ${GIT_PREFIX:-.}; git diff -U$(wc -l \"$1\" | cut -d ' ' -f 1) \"$1\""
  • ma11hew28
    ma11hew28 about 3 years
    For me, this only shows three lines of context before the first change and three lines of context after the last change.
  • stefco
    stefco almost 3 years
    What version of git were you using? Did you replace "path/to/file.py" with your own file path? Just tested (the first variation with 2000 hardcoded) again on git 2.12.1 on windows and it works just fine.
  • ma11hew28
    ma11hew28 almost 3 years
    Version 2.24.3. Yes, I did. But sorry, let me clarify my last comment: Your solution also (of course) shows all the lines between (and including) the changed lines, but I think @Machavity wants to "include all the lines in the file". For example, try your solution on a file with at least five lines and with all its changes after the first four lines. If what that shows you includes the first line of the file, then maybe you have the diff.context variable in your Git configuration file set to a number larger than the default of 3.
  • Yun Wu
    Yun Wu about 2 years
    @fizzyh2o yes your version also works if git df only 1 file, however my version supports git df multiple files.