Git 我如何看待与未跟踪、未分级、分阶段和提交的更改之间的差异?所有这些都是针对远程的更改?
所以我有Git 我如何看待与未跟踪、未分级、分阶段和提交的更改之间的差异?所有这些都是针对远程的更改?,git,Git,所以我有master,这是基线,我在开发人员的机器上有一个任意的情况,包括: 未跟踪的文件 未老化的变化 阶段性变化 本地提交 有没有一种方法可以将上述所有内容与远程内容进行比较?不是作为一个命令,而是只要您可以访问开发人员的机器,并且它可以访问其他存储库,就可以了。让我们调用开发人员的机器M,并假设在M上,通过origin访问“主”存储库,即开发人员最初运行git clone来创建现在在M上的存储库 第一步是确保M上的存储库与其他系统上的存储库是最新的。假设M$是机器M在克隆中时的提示:
master
,这是基线,我在开发人员的机器上有一个任意的情况,包括:
- 未跟踪的文件
- 未老化的变化
- 阶段性变化
- 本地提交
有没有一种方法可以将上述所有内容与远程内容进行比较?不是作为一个命令,而是只要您可以访问开发人员的机器,并且它可以访问其他存储库,就可以了。让我们调用开发人员的机器M,并假设在M上,通过
origin
访问“主”存储库,即开发人员最初运行git clone
来创建现在在M上的存储库
第一步是确保M上的存储库与其他系统上的存储库是最新的。假设M$
是机器M在克隆中时的提示:
M$ git fetch origin
M上的存储库现在有:
- 其所有本地承诺李>
- 索引中的暂存文件李>
- 工作树中的未分级文件李>
- 工作树中任何未跟踪的文件李>
- 所有提交都可在
上进行origin
- 本地分支
上不在B
上的任何提交:origin/B
...--o--o--*--G--H <-- B \ J--K--L <-- origin/B
- 分支
(提交B
)的尖端与索引/暂存区域中的内容之间的差异。让我们再次假设H
names分支HEAD
,以简化此操作:B
这会将差异写入标准输出git diff --cached > /tmp/tip-to-staged
- 索引中的内容与工作树中的内容之间的差异:
这会将差异写入标准输出git diff > /tmp/staged-to-work-tree
- “nothing”(空树)和每个未跟踪文件之间的区别。这是从Git中最难获得的,从某种意义上说也是最愚蠢的,因为“无”和“某些文件集”之间的区别只是“某些文件集”。没有一个Git命令可以生成这个文件,但是您可以使用
来获取这些文件的列表,然后根据需要将它们打包。或者,您可以将它们写入commit;见下文gitls文件--other
- 不仅未跟踪而且被忽略的文件。(请注意,将被跟踪的文件列为“已忽略”对被跟踪的文件没有影响:这样的文件是被跟踪的,而不是被忽略的。“已忽略”是一种仅适用于已未跟踪的文件的状态。在任何情况下,“未跟踪”仅表示“不在索引中”。)这与前一点中的未跟踪文件相同:我们只是将它们分为“未跟踪且忽略”和“未跟踪且未忽略”。事实上,如果您选择使用
,则会得到所有未跟踪的文件,包括被忽略的文件,除非添加gitls文件--other
选项--exclude standard
git stash save
获取未跟踪或所有文件
请注意,我们必须使用至少三个Git命令:
git format-patch
git diff --cached
git diff
我们仍然没有未跟踪和/或忽略的文件。如果我们使用git stash save
,我们可以得到最后一个。我们甚至可以删除一个(但只有一个)git-diff
,同时添加至少一个git-diff
。然而,其他事情变得更加复杂。特别是,git stash save
如果没有任何内容可隐藏,则不会执行任何操作,我们必须检查以下内容:
M$ old_stash=$(git rev-parse -q --verify refs/stash)
M$ git stash save --untracked # assuming you do not want ignored files
M$ new_stash=$(git rev-parse -q --verify refs/stash)
M$ [ "$new_stash" != "$old_stash" ] && have_stash=true || have_stash=false
如果需要所有文件(未跟踪+忽略),请使用--all
而不是--untracked
我们还需要以下文件的哈希ID:
现在,我们可以从空树获取到包含未跟踪减去已忽略(--未跟踪
)或未跟踪包括已忽略(--所有
)文件的提交的差异:
现在可以安全地生成其他差异,或者您也可以在存储保存和可能弹出之前执行这些操作。(如果将上述内容转换为脚本,那么编写脚本的方式就不会那么笨拙了。)
如果你只想要一个差异
如果您对保存单个提交不感兴趣,您可以从上面原始图表中的commit
*
或commitL
运行单个git diff
。(如果origin/branch
上没有新的提交,这些都是相同的提交。)当然,这不会显示索引(暂存)或工作树(未暂存)中的内容。与前面一样,您可以使用git stash save
玩一些技巧,从索引和工作树以及(可选的)--未跟踪的
或--所有
文件进行提交。由于此操作的工作树提交在内部是合并提交,因此必须手动将其与感兴趣的父级区分开来。和以前一样,未跟踪的文件应该与空树进行区分。这就是我发现的解决方案
git add --all -N :/
git --no-pager diff origin/master
只是“如果你想要一个单独的差异”案例的一个补充,如果你git diff origin/master…
(是的,三个点),它有一个特殊的含义,它指出了git merge base
,即*
和与之相对的差异。
M$ empty_tree=$(git hash-object -t tree /dev/null)
M$ ($have_stash && git diff $empty_tree ${new_stash}^3) > /tmp/extra
M$ $have_stash && git stash pop
git add --all -N :/
git --no-pager diff origin/master