Can I use git diff on untracked files?

回眸只為那壹抹淺笑 提交于 2019-11-26 19:26:10
araqnid

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).

Harold

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

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:

  • We're using the fact here that 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.
  • The only problem with this function is that the output is colored even if redirected; but I can't be bothered to add logic for that.
  • I couldn't find any way to get untracked files included by just assembling a slick argument list for 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!

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 | xargs -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.

Amol Pujari
git add -A
git diff HEAD

Generate patch if required, and then:

git reset HEAD

Changes work when staged and non-staged with this command. New files work when staged:

$ git diff HEAD

If they are not staged, you will only see file differences.

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

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 }

usually when i work with remote location teams it is important for me that i have prior knowledge what change done by other teams in same file, before i follow git stages untrack-->staged-->commit for that i wrote an bash script which help 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 above script i fetch remote main branch (not necessary its master branch)to FETCH_HEAD them make a list of my modified file only and compare modified files to git difftool

here many difftool supported by git, i configure 'Meld Diff Viewer' for good GUI comparison .

Assuming you do not have local commits,

git diff origin/master
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!