如何在git中列出目录树的更改历史记录

Uwe*_*der 15 git

Git不会跟踪目录.它只跟踪某些目录中的文件.(请参阅如何将空目录添加到Git存储库?)

但是,如果我有一定的提交历史,我隐含地也有目录树的更改历史记录.

那么我该如何回答以下问题:

  1. 何时创建了目录foo/bar(在git术语中:何时是该目录中创建的第一个文件).如果在历史记录中删除了foo/bar并稍后重新创建,则可能会有多个限定提交.
  2. 何时删除了目录foo/bar(在git术语中:何时从该目录中删除了最后一个文件).如上所述,可能会有多个符合条件的提交.
  3. foo/bar的子目录在历史的任何时间点都存在

我能想出的最接近的是伪代码:

loop over all commits (git rev-list --all)
  start from repo root directory
  do recursively on the directory tree rebuilt so far
    call git ls-tree and grep the tree lines
    rebuild next level of directory tree
  end
end
Run Code Online (Sandbox Code Playgroud)

显然,这可以用您最喜欢的脚本语言编写.

然后我有所有目录树,我仍然需要以聪明的方式搜索它们,以便回答类型1 - 3的问题.再次,可行,但可能不会在几分钟内.

问题是:

  1. 有没有更简单的方法?
  2. 如果没有:是否适合网上已有的脚本?(我的谷歌搜索没有透露任何,但我也没有提出完美的搜索词)

eck*_*kes 10

对于问题1和2,这很容易:

  • 什么时候创建了目录foo/bar?
    git log --oneline -- foo/bar | tail -n 1

  • 什么时候目录foo/bar被删除了?
    git log --oneline -- foo/bar | head -n 1

但是,第三部分有点棘手,我无法完全回答.

上面的两个命令为您提供$FIRST_REV(创建)和$LAST_REV(删除).

以下代码段为您提供修改树的所有提交:

for rev in $(git rev-list FIRST_REV..LAST_REV)
do
  git ls-tree -r -t $rev | grep tree | cut -f 2
done
Run Code Online (Sandbox Code Playgroud)

然后,您有一个存在的目录列表.但仍有重复.将该列表传递给a sort -u,您就完成了:

#!/bin/sh
for r in $(git rev-list FIRST_REV..LAST_REV) 
do 
    git ls-tree -r -t $r | grep tree | cut -f 2
done | sort -u
Run Code Online (Sandbox Code Playgroud)

但是,您丢失了这些目录受影响的提交信息.这是缺点.

并且,这假定foo/bar仅创建一次并且不再存在.


wad*_*dim 5

gitk foo/bar为您提供一个用户界面,用于浏览仅限于触及 .git 的提交的 git 历史记录foo/bar