【问题标题】:Unable to get deleted/added same files list from GIT无法从 GIT 中删除/添加相同的文件列表
【发布时间】:2020-03-13 17:24:55
【问题描述】:

问题陈述:

尝试通过运行以下命令在 Git 中获取已删除/添加的文件列表

  1. 首先我们删除了一个文件(提交 ID:9d0XXXX)
  2. 再次添加相同的文件(提交 ID:6e0XXXX)
  3. 修改了其他文件(提交ID:7d9XXXX)
  4. 试图获取相同的数据,但输出显示为空:

git diff-tree -r --no-commit-id --name-only 9d0XXXX 7d9XXXX

输出:空。

或者

git diff --diff-filter=DAR  9d0XXXX 7d9XXXX

输出:空。

我应该运行什么来获得这个列表?


编辑(来自下面的评论):在 GITHUB 中创建了 Repo,URL:https://github.com/vikramdevops123/insert-delete

  • 添加了几个文件并删除了相同的文件。
  • 正在尝试获取添加和删除文件列表的列表

场景:我删除并添加了同一个文件,但我没有得到那个输出。 git diff-tree -r --no-commit-id --name-only 9e627f fbe54a9git diff --diff-filter=D --name-only 9e627f fbe54a9

【问题讨论】:

  • 要清楚,是否提交9d0XXXX 缺少 文件,并提交7d9XXXX 文件?还是从删除之前提交9d0XXXX 确实拥有该文件?
  • Step1 : 删除文件 -- 9d0XXXX , Step2 : 添加相同文件(已删除文件) -- 6e0XXXX , Step3: 修改新文件 -- 7d9XXXX ### 我正在尝试删除和修改files list ,但输出为“空”
  • 创建一个新的空存储库。将一些文件放入其中(只是虚拟文件)。提交删除,提交恢复,提交修改。尝试差异。将整个(文本)会话剪切并粘贴为复制器。有人可以从那里弄清楚。
  • 在 GITHUB 中创建了 Repo,URL:github.com/vikramdevops123/insert-delete,添加了几个文件并删除了相同的文件。试图获取添加和删除的文件列表,场景:我已经删除并添加了相同的文件,但我没有得到那个输出。 git diff-tree -r --no-commit-id --name-only 9e627f fbe54a9 或 git diff --diff-filter=D --name-only 9e627f fbe54a9

标签: git github gitlab bitbucket


【解决方案1】:

现在你在 GitHub 上有了你的测试仓库,我可以克隆它。

这是git log --all --decorate --oneline --graph的输出:

+ * fbe54a9 (HEAD -> master, origin/master, origin/HEAD) adding deleted file
  * aaf2163 deleting D file
  * 32c853b deleting file
  * 836a3f2 adding test file
+ * 9e627fd adding test file
  * 4a06e68 adding test file
  * 4844174 adding test file
  * 41cd5e7 deleting testc file
  * 6a92b1a adding 3rd file
  * 83fe860 adding testB file
  * 145f2ad added 1st file

我标记了(用加号 +)您在示例 git diff-tree -rgit diff --diff-filter=D 命令中指定的两个提交哈希 ID,以便我们可以查看和/或特别调查这些提交。

您选择了提交 9e627fd adding test file 作为差异的左侧,并提交了 fbe54a9 adding deleted file 作为提交的右侧。让我们看看这两个提交中实际包含哪些文件:

$ git ls-tree -r 9e627fd
100644 blob 9d8a4e73e4f8897352d20eda060a812dab709fc9    file-A.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testB.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testD.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testE.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testc.txt
$ git ls-tree -r fbe54a9
100644 blob 9d8a4e73e4f8897352d20eda060a812dab709fc9    file-A.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testB.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testD.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testE.txt
100644 blob 5e92c1b25f72158c2378b31d29bc443ee327af81    testF.txt

这些提交确实有一些不同的文件名称。请注意,所有四个 test?.txt 文件都具有相同的文件 content(相同的 blob 哈希 ID)。对于git diff-tree,这并不重要:

$ git diff-tree -r --no-commit-id --name-only 9e627f fbe54a9
testF.txt
testc.txt

这看起来很有希望。让我们使用--name-status 而不是--name-only 来获取每个文件的状态

$ git diff-tree -r --no-commit-id --name-status 9e627f fbe54a9
A       testF.txt
D       testc.txt

所以git diff-tree 似乎在这里工作得很好。

现在让我们看看git diff——但在我们添加--diff-filter=D之前,让我们运行它而不使用--diff-filter,然后再次使用--name-status,这样我们就可以看到git diff对这两个特定提交的比较:

$ git diff --name-status 9e627f fbe54a9
R100    testc.txt       testF.txt

这里我们解释了为什么--diff-filter=D 什么都不打印:根据this diff,没有删除文件!但是,有一个 重命名 文件,其名称在左侧提交中为 testc.txt,在右侧提交中为 testF.txtR100 表示旧testc.txt 的内容与新testF.txt 的内容100% 匹配。

如果我们不想让 Git 检测重命名,我们必须告诉它不要检测重命名。 (此配置在 2.9 之前的 Git 版本中是默认配置,但在 2.9 及更高版本中不是。)因此,如果我们的 Git 版本是 2.9 或更高版本,或者如果我们已将 diff.renames 配置为 true 或以其他方式启用它,我们需要稍微改变一下命令行命令:

$ git diff --diff-filter=D --name-only 9e627f fbe54a9
$ git -c diff.renames=false diff --diff-filter=D --name-only 9e627f fbe54a9
testc.txt

使用默认的 diff.renames=true 设置,git diff 使用重命名检测来声明名为 testc.txt 的文件已重命名为名为 testF.txt 的文件,正如我们在未过滤的 --name-status 输出中看到的那样。因此过滤以仅显示D 状态文件失败。但是对于-c diff.renames=falsegit diff 不会尝试重命名检测,并且会像git diff-tree -r 那样行事:它表明文件testc.txt 已被删除。同时,--diff-filter=D 告诉 Git 不要告诉我们新添加的testF.txt

瓷器与管道

git diff-tree 命令属于 Git 称为 plumbing 的命令类别,而 git diff 属于 Git 称为 porcelain 的类别。这里的主要区别在于它们的使用方式:管道命令旨在以简单且可预测的方式运行,并具有适合其他命令使用的输出。 Porcelain 命令旨在以对每个用户最有用的方式运行,因此它们的输出可能是彩色的,而且——这是这个特定问题的关键——可能取决于用户配置。本例中,用户配置项为diff.renames的设置。 git diff-tree 命令不使用 diff.renames,但 git diff 命令使用,因此其输出会根据您的特定配置(在本例中为 Git 年份)而变化。

【讨论】:

    【解决方案2】:
    thanks for the information!!
    
    deleted two files i.e. testc(ID: 32c853b) and testD(ID:aaf2163e) files and 
    added testD file again(Commit ID: fbe54a9)
    git diff-tree -r --no-commit-id --name-status 9e627f fbe54a9
    
    Expected OUTPUT:
    
    A       testF.txt
    D       testc.txt
    TestD.txt
    
    Current Output:  -- Missing TestD .txt file information.
    A       testF.txt
    D       testc.txt
    

    【讨论】:

    • --name-status 输出中,您为什么希望TestD.txt 显示时没有状态码?注意,commit 32c853b 的内容是完全不相关的;您正在比较提交 9e627ffbe54a9
    • 请记住,每个提交都是一个快照。这不是一组变化!它只是保存所有文件的快照。要查找更改,您必须选择 两个 提交,提取它们,然后进行比较。
    猜你喜欢
    • 2014-02-05
    • 2019-12-30
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多