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

时间:2011-08-17 13:24:49

标签: git

Git不会跟踪目录。它只跟踪某些目录中的文件。 (见How can I add an empty directory to a Git repository?

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

那么如何回答以下问题:

  1. 当创建目录foo / bar时(在git术语中:何时是在该目录中创建的第一个文件)。如果有foo / bar,可能会有多个符合条件的提交 删除了历史记录并稍后重新创建。
  2. 当目录foo / bar被删除时(在git术语中:何时从该目录中删除了最后一个文件)。如上所述,可能会有多个合格提交。
  3. 历史上任何时间点存在的foo / bar的子目录是什么
  4. 我能想出的最接近的是伪代码:

    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
    

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

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

    问题是:

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

2 个答案:

答案 0 :(得分: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

然后,您有一个目录列表。但仍有重复。将该列表传递给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

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

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

答案 1 :(得分:4)

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