174

How do I create a patch with full context?

I tried --unified=2000, which gives 2000 lines of context:

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

How do I include all the lines in the file without having to specify the maximum number of lines?

1

7 Answers 7

147

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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?
@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.
Thanks for this, it also works great with git show!
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?”
The --no-prefix option gets rid of the “/a/” and “/b/” destination prefixes that show up by default. (linked page)
88

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.

7 Comments

< is not necessary. git diff -U$(wc -l MYFILE) MYFILE
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.
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?
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.
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.
|
13

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.

3 Comments

Yet that doesn't have an option to say 'All lines in the file'
I suspect that putting a large number, that would simulate "all the lines"
"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.
9

I simply use

git diff -W Git.md 

to list the full patch to a file. From man git diff:

-W, --function-context
Show whole function as context lines for each change.

1 Comment

That's a relevant switch to know about, however it doesn't necessarily include the whole file (most files will have more than one function).
5

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 in 2023:

Just found git df does not work sometimes, due to directory change when executing git alias. (See git aliases operate in the wrong directory). Also @Moises Soto mentioned on macOS the wc command works differently (6 spaces at the front of the wc -l output) and suggested to use awk. 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}" | awk '{print $1}') "${FILE}" done exit 0 

Update on 2024/12/12:

This is the one-liner version I am currently using, which supports multiple files: (Still, add the following into the [alias] section in your .gitconfig)

 df = !"diff_one() { cd ${GIT_PREFIX:-.}; git diff --no-ext-diff -U$(wc -l \"$1\" | awk '{print $1}') \"$1\"; cd -; }; f() { for FILE in \"$@\"; do diff_one \"${FILE}\"; done }; f" 

you can use it with git df <file1> <file2> ....

2 Comments

For a single line alias: df = "!cd -- ${GIT_PREFIX:-.}; git diff -U$(wc -l \"$1\" | cut -d ' ' -f 1) \"$1\""
@fizzyh2o yes your version also works if git df only 1 file, however my version supports git df multiple files.
2

This worked for me on macOS:

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

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

Comments

-1

Previously accepted solutions don't work for me when viewing a specific file/commit (the -U option seems to mess with rev/path parsing), but --inter-hunk-context= works in this case on git version 2.24.0:

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

If you don't know the file size, you can of course find it with wc -l instead of hard-coding it:

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

3 Comments

For me, this only shows three lines of context before the first change and three lines of context after the last change.
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.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.