提交中所有改变但未删除的文件列表 - git

19

我正在调查git代码库。我希望获取每个提交中更改的文件列表。

因此,我通过命令访问了每个提交:

git reset --hard <commitId>

接着,我使用了

git show --pretty="format:" --name-only #{commitId}

这个方法的问题在于它会返回指定 commitId 中的已删除文件,而我并不需要这些。我也尝试了以下方式:

git ls-files 

它不返回已删除的文件,但会返回所有在之前提交中新建或创建的现有文件列表。

示例:

>commit 1
add "file1"
add "file2"

>commit 2
change "file1"

>commit 3
add "file3"
delete "file2"

因此,在这种情况下,我将访问每个提交。如果我在提交1中,我想获取“file1”和“file2”的列表。如果我在提交2中,我将获取“file1”,如果我在提交3中,则获取“file3”。

有什么想法吗?


3个回答

25

尝试使用此命令:

git show --diff-filter=AM --pretty="format:" --name-only #{commitId}

在你最初的问题中提到过,现在加上一个 --diff-filter 标志来限制只显示添加了 (A) 或修改了 (M) 的文件。要查看可限制的文件类型完整列表,请参阅 git show 文档。

正如 @MauricioTrajano 在他的回答中所提到的,你不需要重置为提交状态来使用 git show 进行调查。你只需要知道提交的 SHA-1 哈希值,你可以通过在相关分支上使用 git log 命令来查找。


1
我重置的原因是我想在那个时候看到这些文件。 - Arwa
也许您想将 R 作为 --diff-filter 的选项之一,以便您也可以获取重命名的文件。 - chringel21

10

为达到此目的,您无需将HEAD重置为较早的提交,即您不必失去本地更改。只要提供提交哈希值,git diff允许您在任意两个提交之间进行比较。在您的情况下,您可以执行以下操作:

git diff {COMMIT_1_HASH} {COMMIT_2_HASH} --name-only --diff-filter=AM

这可用于查看在任意数量的提交之间添加和更改的文件。

如果您只想获取一个提交中添加和修改的文件,请使用紧接在您要查看的提交后面的提交哈希值。


6

如何使用--diff-filter=通过git diff过滤器

要获取所有已更改文件的列表,排除所有已删除(通过小写d过滤器)的文件,请使用--diff-filter=d,像这样:

# 1. see list of changed, but NOT 'd'eleted files since `from_commit_hash` to
# now
git diff --name-only --diff-filter=d from_commit_hash

# 2. specifying a range of commits:
git diff --name-only --diff-filter=d from_commit_hash to_commit_hash
# or (same thing)
git diff --name-only --diff-filter=d from_commit_hash..to_commit_hash

# 3. use the 3-dot syntax to look at just the changes since the common ancestor
# between `from_commit_hash` and `to_commit_hash`
# See: https://dev59.com/fmw05IYBdhLWcg3wahNN#7252067
git diff --name-only --diff-filter=d from_commit_hash...to_commit_hash
# or (same thing)
git diff --name-only --diff-filter=d \
    $(git merge-base from_commit_hash to_commit_hash) to_commit_hash

# 4. looking at all changes in `commit2` which are NOT in `commit1`
git diff --name-only --diff-filter=d ^commit1 commit2

您可以通过查看文件名以及使用--name-status查看它们的更改状态,来确认此事是否属实:

# 1. 
git diff --name-status from_commit_hash

# 2. specifying a range of commits
git diff --name-status from_commit_hash to_commit_hash
# or (same thing)
git diff --name-status from_commit_hash..to_commit_hash

# etc. etc.

请注意,我认为--diff-filter=d--diff-filter=AM更好,因为前者包含除“d”删除的文件之外的所有内容,而后者排除除“A”添加和“M”修改的文件之外的所有内容(包括已删除的文件)。前者因此更具包容性,只排除您真正想要排除的内容,这在我看来更好。

--diff-filter=中,大写字母过滤器字母表示包含,而小写字母则表示排除

使用大写字母,如DAM等,来包含该类型的文件,而使用相应的小写字母,如dam等,则排除该类型的文件。

因此,以下是正确的:

--diff-filter=AM  # INCLUDE only Added and Modified files
# vs
--diff-filter=am  # EXCLUDE all added and modified files

man git diff(加粗为我所加):
--diff-filter = [(A|C|D|M|R|T|U|X|B)...[*]] 仅选择被添加(A),复制(C),删除(D),修改(M),重命名(R),类型更改(即常规文件、符号链接、子模块等)(T),未合并(U),未知(X)或已中断配对关系(B)的文件。可使用过滤器字符的任意组合(包括无)。如果在比较中有与其他标准匹配的任何文件,则会选择所有路径,如果没有文件与其他标准匹配,则不会选择任何路径。当添加*(全部或无)到组合中时,如果有任何文件与其他标准相匹配,则选择所有路径;如果没有文件与其他标准匹配,则不选择任何路径。这里的大写字母也可以转换为小写字母以排除。例如,--diff-filter=ad排除添加和删除的路径。请注意,并非所有差异都可以包含所有类型。例如,如果禁用这些类型的检测,复制和重命名条目就不会出现。
参考资料:
1. 请看此处或使用 man git diff 查看git diff --diff-filter=的文档。
2. 参见此特定答案:如何获取在两个 Git 提交之间更改的所有文件的列表?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接