如何从Git获取文件名列表和上次修改日期

时间:2016-05-11 09:22:21

标签: git git-diff

所以我对Git相当新。主要是我一直使用Sourcetree作为视觉辅助。在一系列项目中,我希望获得一个文件列表及其最近的修改日期,从给定日期开始。

我看到我可以从命令行使用“git diff --name-only”,但可能我得到的东西除了(-only)之外,这似乎是针对单个项目的。

所以我正在寻找的是与单个项目无关的问题here而是我试图在活动项目中进行审核,以便我可以看到重点放在多个项目上的能源不完整的临时项目。我知道Ad-Hoc对某些人来说是一个肮脏的场景,但这种情况不太可能很快改变,不是我所做的发展选择,而是持续的商业现状。

因此,根据下面对@torek的回复,我使用共享源库,有多个简单的,基本上不可用的克隆。我想手动合并,如果需要的话,将那些有利的变化反馈到MasterLibraryRepo(这是一个单独的源代码库的集合),并且需要一种快速的方法来审查我的工作重点。

  • ProjectA.LibA LastCommitDate(可能会修改File LibA MasterLibRepo等)
  • ProjectA.LibB LastCommitDate
  • ProjectB.LibF LastCommitDate
  • ProjectZ.LibQ LastChnageDate

1 个答案:

答案 0 :(得分:0)

关于问题编辑的编辑:Git没有用于处理多个项目的内置工具。您可以使用多个远程创建自己的存储库,并维护(在该存储库中) N 单独的提交图子集,从而运行 N 单独的git diff s N 单独的回购单上的单个回购而不是一个git diff,但不清楚如果有的话,你会从中获得更多。

TL; DR回答:尝试git log -1 --pretty=format:%cd $sha..HEAD -- <filename>,为每个有趣的<filename>尝试一次并使用您的起始哈希$sha。但请参阅下面的众多警告。

您可能需要首先更准确地定义问题;这是一个为什么的例子。请注意,我假设&#34;修改日期&#34;一个文件实际上是&#34;附加到提交的日期,其中该提交根据您标识的起始点提交修改文件。&#34;

假设我们有以下提交图:

                C--D--G--H     <-- xyz-branch
               /    \
...--o--S--A--B--E---F--I--J   <-- etc-branch

这里提交S是我们选择的起始点提交(您选择的用于寻找&#34;修改自&#34;案例)。假设该提交中有30个文件,并且提交AS相同,只是文件a.a已被修改(因此提交A具有29个相同的文件和一个不同的文件,即a.a)。

现在,如果a.a在每次后续提交中完全没有变化,显然我们想要a.a的日期是附加到提交A的作者或提交者日期。但是,如果该文件也在提交J中进行了修改,则您可能希望其中一个日期附加到J

但是如果在提交a.a中修改了文件H,该怎么办? HJ都是A的后代:我们应选择哪一个&#34;最后修改&#34;?如果您有xyz-branch等特定目标分支,那么即使H上的日期较新,最新的分支也是J,而不是J,因为提交J仅在etc-branch上。如果特定分支是etc-branch,那么我们关注J而非H

即使使用此etc-branch)约束,如果在a.aC中同时修改E,您可能需要采取策略来选择其中一个< em>除非您想将这些更改分配给提交FF是一个合并提交,因此从分支的两端获取更改 - 但是一些git命令,特别是包括git loggit rev-list,将倾向于跳过F各种情况,可能会将其隐藏起来。然后,这可能是您想要的:您可能希望忽略合并提交,并且只关注非合并,在正常情况下, 1 是引入合并的所有更改的来源。

如果某些提交完全删除a.a,您还必须决定它意味着什么。这是改变吗?如果后续提交恢复a.a会发生什么?如果它在一侧&#34;中发生了变化怎么办?内部分支(例如,提交C)然后改回(例如,在DF中)?

(我猜不出你想要什么;你必须自己决定这些事情。)

无论如何,值得指出git diff只是简单地比较两个提交。例如,如果您运行git diff --name-status etc-branch~6 etc-branch,Git会将提交S与提交J进行比较。 (S来自etc-branch~6:算回六个第一父母。我假设合并的第一个父F在这里提交E,尽管这是不可能的从这个图形图中告诉。如果F的第一个父实际上是D而不是E,则会将提交A与提交F进行比较。)这会告诉您从SJ的更改内容,但如何改变:您可能会看到a.a已更改,但您不知道如果它已在BE和/或I中更改,或者甚至可能已在I中删除,并在J中重新生成。

根据您想要的约束类型,可以通过相对快速的方式查找触及任何特定文件的提交。 git loggit rev-list命令 - 这些命令几乎完全相同,并且由单个顶级文件实现 - 可以告诉&#34;简化&#34;提交历史记录,包括过滤除一些列出的文件以外的所有文件。例如,如果您想了解builtin/log.c(同时实现git loggit rev-list),您可以运行:

git log -p -- builtin/log.c

打印出修改文件的提交(包括一些合并),然后显示一个补丁,看看该文件中究竟发生了什么变化(通常不显示这些相同的合并,因为git log -p跳过合并:这个特殊的命令有点精神错乱,或者至少是混淆,我们是否想要看到合并?!):

$ git log --format=short -p -- builtin/log.c | sed 's/@pobox/ pobox/'
commit cafef3d7ad3ed58d9c976bdeb604cff6b4c1f82b
Merge: 7c137bb 915c96d
Author: Junio C Hamano <gitster pobox.com>

    Merge branch 'lt/pretty-expand-tabs'

commit 0893eec85fca0f76039a96cbbcd3592ff8571c24
Author: Junio C Hamano <gitster pobox.com>

    pretty: enable --expand-tabs by default for selected pretty formats

diff --git a/builtin/log.c b/builtin/log.c
index e00cea7..e5775ae 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1281,6 +1281,7 @@ int cmd_format_patch(int argc, const char **argv, const ch
        git_config(git_format_config, NULL);
        init_revisions(&rev, prefix);
        rev.commit_format = CMIT_FMT_EMAIL;
+       rev.expand_tabs_in_log_default = 0;
        rev.verbose_header = 1;
        rev.diff = 1;
        rev.max_parents = 1;

(还有更多;我只是在这一点上剪掉了它 - 但请注意它记录了合并,然后在合并之前记录了一个非合并提交,显示了最终进入合并的部分内容。)

使用--pretty=format:...--format=...并跳过-p,您只能从git log获取作者或提交者日期。这将包括合并;要跳过它们,请添加--no-merges。要限制检查的提交范围,请添加您的起点和终点,我猜这是您选择的哈希值(单行答案中为$sha)和HEAD。添加-1(这是一个数字一),使Git在打印一次提交后停止。选择和打印的提交是具有最新提交者日期的提交:git log总是按照默认情况下使用提交者日期对其打印的内容进行排序。格式指令%cd打印提交者日期。

如果您想要作者日期,请使用%ad代替%cd,但请注意您可能还希望使用--author-date-order让Git按作者日期而不是提交者排序日期。这种排序符合图形拓扑,这意味着即使提交J比提交I更早, 2 Git也会在J之前对I进行排序。这与默认(提交者日期)排序不同,后者忽略拓扑:它将显示提交I,因为它比J更新(嗯,只要显示I它就会显示F有问题的文件已从I修改为--topo-order:请注意比较符合图形拓扑,它是按提交日期比较排序,忽略拓扑)。

(您可以通过添加{{1}}来强制提交日期排序以遵守拓扑。)

1 正如这句话所暗示的那样,合并可以包含其父类中没有出现的变化。这种合并有时被称为&#34;邪恶的合并&#34;并且很难找到以这种方式滑落的变化。

2 这看起来似乎不可能,但想象一下,我们启动计算机并将日期设置为明年,进行提交,重新启动并将日期设置回现在,并再次提交。 (实际上并不需要重新启动 - 它只是为了使这种可视化更容易。)我们首先提交的提交比我们刚刚提交的提交更新,事实上,它将比每个新提交更新直到另一年过去了。