【发布时间】:2010-10-25 17:47:00
【问题描述】:
是否可以要求git diff 在其差异输出中包含未跟踪的文件,或者我最好在新创建的文件和我编辑的现有文件上使用git add,然后使用:
git diff --cached
?
【问题讨论】:
是否可以要求git diff 在其差异输出中包含未跟踪的文件,或者我最好在新创建的文件和我编辑的现有文件上使用git add,然后使用:
git diff --cached
?
【问题讨论】:
使用最新的 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
遗憾的是,正如所指出的,当您有一个像这样的 --intent-to-add 文件挂起时,您不能 git stash。虽然如果您需要存储,您只需添加新文件然后存储它们。或者您可以使用仿真解决方法:
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 语法着色等...漂亮。
/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 不可用,因为它breaks git stash.
这是我的git diff 替代品。这不是一个特别干净的解决方案,但由于我真的只以交互方式使用它,我可以接受黑客攻击:
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 解决方法确实 与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和read,所以也许这样更好?!?我把它留给读者。
不是 100%,但如果由于某种原因您不想按照接受的答案的建议将文件添加到索引中,这里是另一种选择:
如果文件未被跟踪,显然差异是整个文件,所以你可以用 less 查看它们:
less $(git ls-files --others --exclude-standard)
使用:n 和:p 在它们之间导航以获取下一个和上一个..
来自 cmets 的更新:如果您需要补丁格式,您也可以将其与 git diff 结合使用:
git ls-files --others --exclude-standard -z | xargs -0 -n 1 git --no-pager diff /dev/null | less
在这种情况下,您还可以将输出重定向到文件或使用其他 diff 命令。
【讨论】:
git diff /dev/null <untracked_tile> 并以补丁格式获取补丁,而不是“只是”一个文件
--color=always放在了diff之后,用更少的-R。所以大家一起:git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff --color=always /dev/null | diff-so-fancy | less -R.
-z 和 -0 到 xargs。尽可能使用空终止符,以避免出现错误(和安全漏洞!),例如包含回车符或其他奇怪字符的文件名。
git add -A
git diff HEAD
根据需要生成补丁,然后:
git reset HEAD
【讨论】:
git add -p(顺便说一句,我通常推荐)......这确实提供了一种做基本事情的方法,它只是......应该注意它有潜力避免不必要的副作用。
对于一个文件:
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 }
【讨论】:
alias gdall="git --no-pager diff; gdnew"
这对我有用:
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
如果您想要分阶段和非分阶段的更改,请将HEAD 添加到命令中:
$ git diff HEAD
【讨论】:
HEAD 是default value,所以这与git diff 相同,但不能解决问题。
git add
git add,这是最简单的如果您的用例是检查您刚刚添加/想要添加的内容
git diff 将仅显示未暂存的更改,git diff HEAD 将显示未暂存和暂存的更改。
通常当我与远程位置团队合作时,在我遵循 git 阶段 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 比较。
【讨论】:
使用您可以暂存新文件并且可以对暂存文件进行比较的想法,您可以将这两者结合起来查看差异。我觉得使用起来很简单。
添加您想要查看差异的文件。在您的情况下,add only untracked files。您可以选择仅添加您希望查看差异的那些文件。
git stash && git add . && git stash pop
区分分期
git diff --staged
如果需要,重置暂存文件
git reset
综合以上几点,
git stash && git add . && git stash pop && git diff --staged && git reset
【讨论】:
如果您碰巧在使用 git stash(即预提交 git 挂钩)的脚本上下文中需要此功能,那么这对我来说在 macOS Big Sur 上使用 git v2.34.1 效果很好:
# 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}
}
【讨论】:
假设您没有本地提交,
git diff origin/master
【讨论】:
git diff 命令。此命令不包括它们。此外,是否存在本地提交与问题完全无关。
git merge --squash mybranch 和 git diff master 向我展示了未跟踪文件中的更改。
git diff 不显示未跟踪文件的差异:因为它们未跟踪,根据定义,永远不会显示任何差异。这就是 Git 的工作方式。 :)