我如何看到远程未跟踪,未分级,暂存和已提交更改的差异?

时间:2017-10-28 20:46:56

标签: git

所以我有master这是基线,我在开发人员的机器上有任意情况,包括:

  • 未跟踪文件
  • 非分期更改
  • 分阶段更改
  • 本地提交

有没有办法在遥控器上看到以上所有的差异?

2 个答案:

答案 0 :(得分:1)

不是单个命令,只要您可以访问开发人员的计算机并且可以访问其他存储库,是的。我们只需要调用开发人员的机器 M ,并假设在 M 上,访问“主”存储库是通过origin完成的,即开发人员运行git clone <url> 1}}最初用于创建现在位于 M 上的存储库。

第一步是确保 M 上的存储库与其他系统上的存储库保持同步。假设M$是克隆时 M 上的提示:

M$ git fetch origin

M 上的存储库现在具有:

  • 所有本地提交;
  • 索引中的暂存文件;
  • 工作树中的未分段文件;
  • 工作树中任何未跟踪的文件;
  • origin上提供的所有提交。

现在 M 拥有生成你喜欢的任何差异所需的一切,问题就变成了:您希望如何生成和呈现这些差异?

让我们进一步假设我们感兴趣:

  • 本地分支B上未在origin/B上的任何提交:

    ...--o--o--*--G--H   <-- B
                \
                 J--K--L   <-- origin/B
    

    此处有两个此类提交,其中包含哈希GH

    您可以git show每次这样的提交,以获取日志消息和补丁。或者,您可以运行git format-patch <options> origin/B..B,以生成包含每个提交作为补丁的单个补丁文件(默认值)或stdout流(--stdout)。请注意,format-patch不会显示合并提交,并且合并提交的差异很难实现,因此我们将忽略它们。

    如果存储库当前位于分支B上(以便BHEAD),则只需运行git format-patch <options> origin/Bformat-patch的默认值为将单个参数视为<argument>..HEAD的含义。因此:

    M$ git format-patch --stdout origin/B > /tmp/commits
    
  • 分支B(提交H)的提示与索引/暂存区域中的内容之间的差异。让我们再次假设HEAD名称分支B,以使这更容易:

    git diff --cached > /tmp/tip-to-staged
    

    这会将diff写入标准输出。

  • 索引中的内容与工作树中的内容之间的区别:

    git diff > /tmp/staged-to-work-tree
    

    这会将diff写入标准输出。

  • “无”(空树)与每个未跟踪文件之间的区别。这是最难从Git获得的,并且在某种意义上也是最愚蠢的,因为“无”和“某些文件集”之间的区别只是“一些文件集”。没有单一的Git命令来生成它,但您可以使用git ls-files --other来获取此类文件的列表,然后根据需要将它们包装起来。或者,您可以将它们写入提交;见下文。

  • 不仅未跟踪,也会被忽略的文件。 (请注意,将跟踪文件列为已忽略对跟踪文件没有影响:跟踪此类文件但不会被忽略。“忽略”状态仅适用于 的文件,已经在任何情况下,“未跟踪”仅仅意味着“不在索引中”。)这与前一点中未跟踪的文件相同:我们只是将它们分为“未跟踪和忽略”与“未跟踪且未被忽略” 。实际上,如果您选择使用git ls-files --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

我们还需要empty tree的哈希ID:

M$ empty_tree=$(git hash-object -t tree /dev/null)

我们现在可以从空树中获取包含untracked-minus-ignored(--untracked)或untracked-included-ignored(--all)文件的提交:

M$ ($have_stash && git diff $empty_tree ${new_stash}^3) > /tmp/extra
M$ $have_stash && git stash pop

现在可以安全地生成其他差异,或者您可以在存储保存和可能弹出之前执行这些差异。 (如果你将上面的内容变成一个脚本,那么编写它的方式会有些不那么笨拙。)

如果你只想要一个差异

如果您对保留单个提交不感兴趣,可以在上面的原始图表中从提交git diff或提交*运行单个L。 (如果origin/branch上没有新的提交,那么相同的提交。)当然,这不会显示索引(暂存)或工作树(未分阶段)中的内容。和以前一样,您可以使用git stash save进行一些技巧来从索引和工作树以及(可选)--untracked--all文件进行提交。由于此操作的工作树提交在内部是合并提交,因此您必须手动将其与有趣的父项进行区分。和以前一样,未跟踪的文件应该针对空树进行区分。

答案 1 :(得分:0)

他是我发现的解决方案

git add --all -N :/
git --no-pager diff origin/master