我正在调查git存储库.我想在每次提交中获取已更改文件的列表.
所以,我做的是通过命令访问每个提交
git reset --hard <commitId>
Run Code Online (Sandbox Code Playgroud)
然后,我用了
git show --pretty="format:" --name-only #{commitId}
Run Code Online (Sandbox Code Playgroud)
这个的问题是它提供了我不想要的commitId中的已删除文件.我也尝试过:
git ls-files
Run Code Online (Sandbox Code Playgroud)
它不会返回已删除的文件,但是,它会返回所有现有文件的列表,这些文件是新的或在先前的提交中创建的.
例:
>commit 1
add "file1"
add "file2"
>commit 2
change "file1"
>commit 3
add "file3"
delete "file2"
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下,我将访问每个提交.并且,如果我在提交1中,我想获得"file1"和"file2"的列表.如果我在提交2中,如果我在提交3中,我将获得"file1"和"file3".
任何想法?
Tim*_*sen 11
尝试使用此命令:
git show --diff-filter=AM --pretty="format:" --name-only #{commitId}
Run Code Online (Sandbox Code Playgroud)
这是您在原始问题中提到的,--diff-filter
添加了一个标志,仅限于添加(A
)或修改(M
)的文件.有关您可以限制的文件类型的完整列表,请查看git show的文档.
正如@MauricioTrajano在他的回答中提到的,你不需要重置为提交来使用它进行调查git show
.您需要知道的只是提交的SHA-1哈希,只需git log
在相关分支上使用即可找到.
您不必将 HEAD 重置为较早的提交来执行此操作,即您不必丢失本地更改,git diff
只要您提供提交哈希,就允许您在任何两次提交之间进行比较。在你的情况下,你可以这样做:
git diff {COMMIT_1_HASH} {COMMIT_2_HASH} --name-only --diff-filter=AM
Run Code Online (Sandbox Code Playgroud)
这可用于查看在任意数量的提交之间添加和更改的文件。
如果您只想为一次提交添加和修改文件,那么只需使用您尝试查看的提交后的提交哈希。
git diff
过滤器--diff-filter=
要获取所有已更改文件的列表,不包括所有已删除(通过小写过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://stackoverflow.com/a/7252067/4561887
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
Run Code Online (Sandbox Code Playgroud)
您可以通过查看文件名及其更改状态来根据更改文件的完整列表来确认这一点--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.
Run Code Online (Sandbox Code Playgroud)
请注意,我认为--diff-filter=d
比前者更好,--diff-filter=AM
因为前者包含除“已删除”文件之外的所有内容,而后者则排除除“添加”和“修改”文件之外的所有内容(包括已删除的文件) 。因此,前者更具包容性,仅排除您真正想要排除的内容,在我看来它更好。
--diff-filter=
,大写过滤字母INCLUDE与小写过滤字母except使用大写字母(例如D
、A
或M
等)来包含该类型的文件,使用小写字母(例如d
、a
或m
等)来排除该类型的文件。
因此,以下情况是正确的:
--diff-filter=AM # INCLUDE only Added and Modified files
# vs
--diff-filter=am # EXCLUDE all added and modified files
Run Code Online (Sandbox Code Playgroud)
来自man git diff
(强调):
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
仅选择已添加 (
A
)、已复制 (C
)、已删除 (D
)、已修改 (M
)、已重命名 (R
)、其类型(即常规文件、符号链接、子模块...)已更改 (T
)、未合并 ( ) 的文件U
,未知 (X
),或配对已损坏 (B
)。可以使用过滤字符的任意组合(包括无)。当*
(All-or-none)添加到组合中时,如果有任何文件符合比较中的其他条件,则选择所有路径;如果没有与其他条件匹配的文件,则不会选择任何内容。此外,这些大写字母可以小写以排除。例如,
--diff-filter=ad
排除a
dded 和d
eleted 路径。请注意,并非所有差异都可以包含所有类型。例如,如果禁用对这些类型的检测,则无法显示复制和重命名的条目。
git diff --diff-filter=
文档或使用.man git diff