4

我正在我的存储库中进行一些目录级别的重组。结果提交显示了许多文件级重命名,这掩盖了我在概念上所做的只是一两个git mv dir1/ dir2/命令的事实。

有没有办法git log总结这种操作来表明,从概念上讲,整个目录被移动了?我认为--dirstat或者--summarize至少会让我接近,但他们似乎没有做我想做的事。

(我知道 git 的存储库模型不跟踪有关目录的任何信息,只跟踪文件。但是,文件重命名也是如此,但它能够在事后获得有关文件级重命名的信息。)

这是一个简单的例子:

#setup
git init
mkdir dir1
for f in foo bar baz; do echo $f > dir1/$f; done
git add dir1
git commit -m 'dir1'

#do the directory move
git mv dir1 dir2
git commit -m 'rename dir1 to dir2'

在这一点上,我希望看到这样的事情:

$ git log -1 --what-options-go-here?
b0ba9c9 rename dir1 to dir2
0       0       {dir1 => dir2}/

相反,我似乎只能产生这样的东西:

$ git log -1 --numstat --oneline
b0ba9c9 rename dir1 to dir2
0       0       {dir1 => dir2}/bar
0       0       {dir1 => dir2}/baz
0       0       {dir1 => dir2}/foo
4

1 回答 1

1

Git 动态计算文件重命名(使用“相似性索引”,参见 diff-M选项;也-B-C)。如果给定提交c1c2,路径path1已经从 中消失c1path2出现在 中c2,那就是“重命名候选”。如果 的文件内容与 的文件内容path2足够相似path1,则该文件必须已被重命名(如果-M小于,则还可能被修改100%)。

要确定重命名是“目录重命名”,您需要添加以下形式的代码:

  • 每个文件都dir1消失了(包括未跟踪和忽略的文件)
  • 之前没有文件出现dir2(包括未跟踪和忽略的文件)
  • 鉴于动态检测到的重命名,具有名称的“足够”文件dir1被重命名,以便dir1成为dir2路径,而名称的其余部分保持不变

决定将dir1其重命名为dir2. (最后一点中的“足够”允许一些文件在新的之外被重命名dir2。)

这里真正的关键点是两个括号位,“包括未跟踪和忽略的文件”。显然 git 不能告诉你这些文件的历史。(当然可以假设不存在这样的文件,也许是在选项标志的控制之下。)我不确定这是否是决定不编写该算法的一个因素。但据我所知,它不在那里。

于 2013-11-02T00:05:24.480 回答