Is it possible to ask git diff
to include untracked files in its diff output, or is my best bet to use git add
on the newly created files and the existing files I have edited, then use:
git diff --cached
Is it possible to ask git diff
to include untracked files in its diff output, or is my best bet to use git add
on the newly created files and the existing files I have edited, then use:
git diff --cached
With recent git versions you can git add -N
the file (or --intent-to-add
), which adds a zero-length blob to the index at that location. The upshot is that your "untracked" file now becomes a modification to add all the content to this zero-length file, and that shows up in the "git diff" output.
git diff
echo "this is a new file" > new.txt
git diff
git add -N new.txt
git diff
diff --git a/new.txt b/new.txt
index e69de29..3b2aed8 100644
--- a/new.txt
+++ b/new.txt
@@ -0,0 +1 @@
+this is a new file
Sadly, as pointed out, you can't git stash
while you have an --intent-to-add
file pending like this. Although if you need to stash, you just add the new files and then stash them. Or you can use the emulation workaround:
git update-index --add --cacheinfo \
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
(setting up an alias is your friend here).
git add -N .
–
Dyal touch mynewfile && git add -N mynewfile
–
Paradise deleted file mode 100755 index e69de29..0000000
which does not allow for me to obtain git diff
result @Selfinterest –
Penult git restore
that files. This command just truncates all the "intent-to-add"-ed files! –
Impossibly git add -N --no-all .
–
Lynden git add -N
run git reset --mixed
based on this. –
Bettis I believe you can diff against files in your index and untracked files by simply supplying the path to both files.
git diff --no-index tracked_file untracked_file
git diff --no-index untracked_file_1 untracked_file_2
to get git diff
syntax coloring etc. on diffs ... beautiful. –
Pedicab /dev/null
instead: git diff --no-index -- /dev/null <untracked_file>
. –
Granthem cat untracked_file_1
, or perhaps printf '\e[1;32m%s\e[0m\n' "$(cat untracked_file_1)"
if you really need green output. :) (Although on a more serious note, please note that command substitution will remove the trailing newlines from your file.) –
Neumann tracked_file
with. –
Delrio /dev/null
or anything else. As @Neumann pointed out, you can just cat
it if you really want to see one file and you know it's name... The whole point of the question as I understand it is to be able to see all changes (multiple files) by one diff
command, even if part of these changes are changes of previously existing files (so, "diff" has perfect sense) and other part are new files (and you still want to see their contents as "diff" alongside with changes of existing files - just to see the whole picture). –
Fibre $ git diff --no-index -- /dev/null .gitignore
results in error: Could not access 'rx/72nbuild/nul'
–
Amherst diff --color
. –
Tymes Not 100% to the point, but if for some reason you don't want to add your files to the index as suggested by the accepted answer, here is another option:
If the files are untracked, obviously the diff is the whole file, so you can just view them with less:
less $(git ls-files --others --exclude-standard)
Navigate between them with :n
and :p
for next and previous..
Update from the comments: If you need a patch format you can also combine it with git diff
:
git ls-files --others --exclude-standard -z | xargs -0 -n 1 git --no-pager diff /dev/null | less
You can also redirect the output to a file or use an other diff command in this case.
git diff /dev/null <untracked_tile>
and get the patch in patch format rather than "just" a file –
Supply --color=always
after the word diff
, and use -R
with less. So all together: git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff --color=always /dev/null | diff-so-fancy | less -R
. –
Hellebore -z
to the git command and -0
to xargs
. ALWAYS use null-termination when possible, to avoid bugs (and security vulnerabilities!) with things like file names containing carriage returns or other weird characters. –
Arlina git diff
with this method –
Closing For my interactive day-to-day gitting (where I diff the working tree against the HEAD all the time, and would like to have untracked files included in the diff), add -N/--intent-to-add
is unusable, because it breaks git stash
.
So here's my git diff
replacement. It's not a particularly clean solution, but since I really only use it interactively, I'm OK with a hack:
d() {
if test "$#" = 0; then
(
git diff --color
git ls-files --others --exclude-standard |
while read -r i; do git diff --color -- /dev/null "$i"; done
) | `git config --get core.pager`
else
git diff "$@"
fi
}
Typing just d
will include untracked files in the diff (which is what I care about in my workflow), and d args...
will behave like regular git diff
.
Notes:
git diff
is really just individual diffs concatenated, so it's not possible to tell the d
output from a "real diff" -- except for the fact that all untracked files get sorted last.git diff
. If someone figures out how to do this, or if maybe a feature gets added to git
at some point in the future, please leave a note here!git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
workaround I suggested for older gits does work with git stash
, assuming you've already got e69de29bb in your db, e.g. by trying to use add -N
previously. So apparently it's not exactly equivalent to git add -N
in some way: tbh I'm not sure how. –
Selfinterest test
command, by the way. Shouldn't affect anything, but test "$#" -eq 0
is more precisely what's intended. –
Neumann less
so you don't have to press q
for each file and it feels exactly like git diff
, by removing per-file pagination (-P
), adding it back afterwards (| less
), preserving colour (--color=always
) and interpreting it as colour (less -r
or less -R
). So altogether it's: do git -P diff --color=always -- /dev/null "$i"; done | less -r
–
Haywoodhayyim test -t 1
(so e.g. if [ -t 1 ]; then color_arg=--color; fi
or something) is a way for the shell to check if its output is a terminal, which is a useful way to decide on the coloring. And xargs
might give a way to get rid of the while loop. You'll still need -n 1
on that, so it'll still launch git a bunch of times, and still need to be pairwise that way, but... it gets rid of while
and read
, so maybe that's better?!? I leave that to the reader. –
Suddenly git add -A
git diff HEAD
Generate patch if required, and then:
git reset HEAD
git add -p
very often (which I generally recommend, by the way)... This does give a way of doing the basic thing, it just... should be noted that it has the potential for unwanted side effects. –
Suddenly For one file:
git diff --no-index /dev/null new_file
For all new files:
for next in $( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null $next; done;
As alias:
alias gdnew="for next in \$( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null \$next; done;"
For all modified and new files combined as one command:
{ git --no-pager diff; gdnew }
alias gdall="git --no-pager diff; gdnew"
–
Abreu $ git diff --no-index -- /dev/null .gitignore
resulted, in my case, in: error: Could not access 'device_support/oem/renesas/rx72n-envision/e2studio-CCRX/R5F572NN/nul'
–
Amherst this works for me:
git add my_file.txt
git diff --cached my_file.txt
git reset my_file.txt
Last step is optional, it will leave the file in the previous state (untracked)
useful if you are creating a patch too:
git diff --cached my_file.txt > my_file-patch.patch
Update: My answer is for staged and unstaged changes. Not tracked and untracked. See the accepted answer for the tracked/untracked information. Leaving here for posterity.
The following will give you only unstaged changes:
$ git diff
If you want both staged and unstaged changes, add HEAD
to the command:
$ git diff HEAD
HEAD
is the default value, so this is the same as git diff
which doesn't solve the problem. –
Kitchens git add
from every not tracked file –
Lubin git add
it is the simplest if your use case is to check what you just added/want to add –
Caloric git diff
will only show unstaged changes, git diff HEAD
will show unstaged and staged ones. –
Blanket Using the idea that you can stage the new file and you can diff the staged files, you can combine these two to see the diff. I find it simple to use.
Add the files you want to see the diff.In your case, add only untracked files. You can optionally choose to add only those files you want to see the diff for.
git stash && git add . && git stash pop
Diff the staged
git diff --staged
Reset the staged files if needed
git reset
Combining all the above,
git stash && git add . && git stash pop && git diff --staged && git reset
Usually when I work with remote location teams it is important for me that I have prior knowledge of what changes are done by other teams in the same file, before I follow git stages untrack-->staged-->commit for that I wrote a bash script which helps me to avoid unnecessary resolve merge conflict with remote team or make new local branch and compare and merge on main branch
#set -x
branchname=`git branch | grep -F '*' | awk '{print $2}'`
echo $branchname
git fetch origin ${branchname}
for file in `git status | grep "modified" | awk "{print $2}" `
do
echo "PLEASE CHECK OUT GIT DIFF FOR "$file
git difftool FETCH_HEAD $file ;
done
In the above script I fetch remote main branch (not necessary it's master branch) to FETCH_HEAD them make a list of my modified files only and compare modified files to git difftool
Here many difftools are supported by git. I configure 'Meld Diff Viewer' for good GUI comparison.
git add .
to add local changes and untracked files to index,git diff HEAD > diff
to create a patch of all changes with untracked files,git reset
to unstage everythingYour diff patch is in file diff
Hack using git stash
:
# Stash unstaged changes
git stash --keep-index --include-untracked --message="pre-commit auto-stash"
git stash show --only-untracked stash@{0}
git stash pop
I needed this in the context of scripts that use git stash
(i.e. a pre-commit git hook). Here's my full working example:
(written/tested on git v2.34.1 on macOS Big Sur)
# Stash unstaged changes
# NOTE: we always create a stash - possibly even a totally empty one.
git stash --keep-index --include-untracked --message="pre-commit auto-stash"
diffTracked=$(git diff --stat --staged stash@{0})
diffUntracked=$(git stash show --only-untracked stash@{0})
[[ $diffTracked || $diffUntracked ]] && {
echo "Stashed diff:"
# Ensure diffs have standard coloring:
git diff --stat --staged stash@{0}
git stash show --only-untracked stash@{0}
}
Assuming you do not have local commits,
git diff origin/master
git diff
command that includes untracked files. This command does not include them. Also, whether or not local commits exists has absolutely nothing to do with the question. –
Grandiose git merge --squash mybranch
, and git diff master
showed me the changes in untracked files. –
Crosier git diff
doesn't show differences in untracked files: because they are untracked there are never any differences to show, by definition. It's just the way Git works. :) –
Grandiose © 2022 - 2025 — McMap. All rights reserved.