Answers:
使用最新的git版本,您可以git add -N
使用文件(或--intent-to-add
),该文件会在该位置的索引中添加零长度的blob。结果是您的“未跟踪”文件现在变为修改,以将所有内容添加到此零长度文件中,并显示在“ git diff”输出中。
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
不幸的是,正如所指出的那样,git stash
当您有一个--intent-to-add
待处理的文件时无法这样做。尽管如果需要隐藏,则只需添加新文件,然后隐藏它们。或者,您可以使用仿真解决方法:
git update-index --add --cacheinfo \
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
(在这里设置别名是您的朋友)。
git add -N .
我相信您只需提供两个文件的路径,就可以与索引文件和未跟踪文件进行比较。
git diff --no-index tracked_file untracked_file
git diff --no-index untracked_file_1 untracked_file_2
得到git diff
语法着色等上的diff ......美丽。
/dev/null
改用:git diff --no-index -- /dev/null <untracked_file>
。
cat untracked_file_1
,或者printf '\e[1;32m%s\e[0m\n' "$(cat untracked_file_1)"
如果您确实需要绿色输出。:)(尽管请注意,命令替换会删除文件中的尾随换行符。)
对于我的日常交互gitting(我一直将工作树与HEAD进行比较,并希望在diff中包含未跟踪的文件)add -N/--intent-to-add
是无法使用的,因为它会中断 git stash
。
所以这是我的git diff
替代品。这不是一个特别干净的解决方案,但是由于我实际上只以交互方式使用它,因此可以接受一些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
}
键入只会d
将未跟踪的文件包含在diff中(这是我在工作流程中关心的内容),并且d args...
表现得与常规一样git diff
。
笔记:
git diff
实际上只是各个差异的连接,因此不可能说出d
“真实差异” 的输出-除了所有未跟踪的文件都最后排序的事实。git diff
。如果有人知道如何执行此操作,或者git
将来某个时候可能添加了功能,请在此处留下注释!git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
建议对较早的gits 使用的变通方法可与一起使用git stash
,假设您已经在数据库中添加了e69de29bb,例如,尝试使用add -N
以前的方法。因此,显然它git add -N
在某些方面并不完全等同:tbh我不确定如何。
test
顺便说一句,您正在通过命令执行字符串比较,而不是数字相等性检查。不应该有任何影响,但test "$#" -eq 0
更确切地说是预期的。
less
因此您不必按q
每个文件,并且感觉完全一样git diff
,通过删除每个文件的分页(-P
),然后将其添加回去(| less
),保留颜色(--color=always
)并将其解释为颜色(less -r
或less -R
)。总而言之:do git -P diff --color=always -- /dev/null "$i"; done | less -r
test -t 1
(例如if [ -t 1 ]; then color_arg=--color; fi
,诸如此类)是外壳检查其输出是否为终端的一种方法,这是决定颜色的有用方法。并xargs
可能提供摆脱while循环的方法。您仍然需-n 1
要这样做,因此它仍然会多次启动git,并且仍然需要以这种方式成对运行,但是...它摆脱了while
and read
,所以也许更好?!?我把它留给读者。
到目前为止还不是100%,但是如果由于某种原因您不想按照已接受的答案建议将文件添加到索引中,则可以使用另一种选择:
如果文件未跟踪,则差异显然是整个文件,因此您可以使用更少的内容查看它们:
less $(git ls-files --others --exclude-standard)
用:n
和:p
在下一个和上一个之间导航。
更新评论:如果您需要补丁格式,也可以将其与结合使用git diff
:
git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff /dev/null | less
在这种情况下,您也可以将输出重定向到文件或使用其他diff命令。
git diff /dev/null <untracked_tile>
并以补丁程序格式获取补丁程序,而不是“仅”一个文件
git add -A
git diff HEAD
如果需要,生成补丁,然后:
git reset HEAD
git add -p
经常使用(顺便提一下,我通常建议这样做)的情况……这确实提供了一种做基本事情的方法,只是……应该注意的是,它可能会产生不必要的一面效果。
这对我有用:
git add my_file.txt
git diff --cached my_file.txt
git reset my_file.txt
最后一步是可选的,它将使文件保持先前的状态(未跟踪)
如果您也要创建补丁,则很有用:
git diff --cached my_file.txt > my_file-patch.patch
对于一个文件:
git diff --no-index /dev/null new_file
对于所有新文件:
for next in $( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null $next; done;
作为别名:
alias gdnew="for next in \$( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null \$next; done;"
对于所有修改和新文件合并为一个命令:
{ git --no-pager diff; gdnew }
通常,当我与远程团队合作时,对我来说很重要的一点是,我必须先了解其他团队在同一文件中所做的更改,然后再执行git stage untrack-> staged-> commit那个我写了一个bash脚本,帮助我避免不必要的解决与远程团队合并冲突或建立新的本地分支并在主分支上进行比较和合并
#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
在上面的脚本中,我将远程主分支(不一定是其主分支)获取到FETCH_HEAD,它们仅列出我的修改文件,并将修改后的文件与git difftool进行比较
这里有很多git支持的difftool,我配置了'Meld Diff Viewer'以获得很好的GUI比较。
假设您没有本地提交,
git diff origin/master
git diff
包含未跟踪文件的命令。此命令不包括它们。而且,是否存在本地提交与该问题绝对无关。
git merge --squash mybranch
和git diff master
我展示了在未跟踪文件的变化。
git diff
不会在未跟踪的文件中显示差异:因为它们是未跟踪的,所以根据定义,永远不会显示任何差异。这就是Git的工作方式。:)