git日志有什么诀窍吗--跟踪一个已重命名的目录?

git日志有什么诀窍吗--跟踪一个已重命名的目录?,git,Git,git命令有一个有用的命令,可以在重命名后跟踪文件,如git log--follow path/to/some/file。不幸的是,它只适用于单个文件。我希望能够执行与git日志相当的操作——遵循一些/directory 这样做的一种方法可能是对git ls tree的输出进行按摩,并在循环中执行,但问题是影响多个文件的提交不会“合并”到一个提交中 有更好的方法吗?注:使用git 2.7.4 Git不存储目录,只存储文件。当您对查看整个提交的命令(如git log或git diff)使用任何路径

git命令有一个有用的命令,可以在重命名后跟踪文件,如
git log--follow path/to/some/file
。不幸的是,它只适用于单个文件。我希望能够执行与git日志相当的操作——遵循一些/directory

这样做的一种方法可能是对
git ls tree
的输出进行按摩,并在循环中执行,但问题是影响多个文件的提交不会“合并”到一个提交中

有更好的方法吗?注:使用git 2.7.4

Git不存储目录,只存储文件。当您对查看整个提交的命令(如
git log
git diff
)使用任何路径名时,git本质上说是“从整个提交开始,然后将其缩小到与该路径匹配的文件”。这里的目录只是选择目录中的每个文件

--follow
选项只能跟随一个文件。因此,如果您能够设法将其应用到一个目录,Git将首先将该目录转换为一组文件,然后从这些文件中选择一个,然后只执行该文件


(实际的
--follow
代码非常粗糙。它利用了重命名检测代码,但只在将提交按较新的顺序与较旧的顺序进行比较时才起作用:如果添加
--reverse
--follow
根本不起作用。可能整个过程都需要抛出并重新编码。也许通过重新编码,您可以可能会使它处理多个文件名,甚至是满是文件的目录。)

似乎没有一种内置的方法可以做到这一点

可以使用脚本并遵循简单的算法来实现这一点:

  • 为每个文件生成与其关联的提交列表
  • 合并所有列表并对其进行稳定排序(这很棘手,因为确定提交顺序并不简单)
  • 迭代地执行每个提交的git日志,并通过更少的管道传递它
这里有一种使用Python3和
sh
模块的黑客方法,由于各种原因,它无法在Windows上工作

#!/usr/bin/env python3

import os
import shlex
import sys
import tempfile

import sh

def _get_commits(fname):
    # Ask for the commit and the timestamp
    # .. the timestamp doesn't guarantee ordering, but good enough
    for c in sh.git('log', '--follow', '--pretty=%ct %h', fname,
                   _tty_out=False, _iter=True):
        c = c.strip().split()
        yield int(c[0]), c[1]

def git_log_follow_multi(filenames):
    if len(filenames) == 0:
        print("Specify at least one file to log")
    elif len(filenames) <= 1:
        os.system('git log --follow -p %s' % filenames[0])
    else:
        # Use git log to generate lists of commits for each file, sort
        commits = []
        for fname in filenames:
            commits += _get_commits(fname)

        # Sort the lists (python's sort is stable)
        commits.sort(reverse=True)

        # Uniquify (http://www.peterbe.com/plog/uniqifiers-benchmark)
        seen = set()
        seen_add = seen.add
        commits = [c for c in commits if not (c in seen or seen_add(c))]

        # Finally, display them
        tname = None

        try:
            file_list = ' '.join(shlex.quote(fname) for fname in filenames)

            with tempfile.NamedTemporaryFile(mode='w', delete=False) as fp:
                tname = fp.name
                for _, commit in commits:
                    fp.write('git log -p -1 --color %s %s\n' % (commit, file_list))

            # Use os.system to make our lives easier
            os.system('bash %s | less -FRX' % tname)
        finally:
            if tname:
                os.unlink(tname)


if __name__ == '__main__':
    git_log_follow_multi(sys.argv[1:])

我知道只存储文件;我想也许有人已经想出了一个解决方案,甚至是黑客的……谁知道:)这个问题在什么地方出现了漏洞?@JérômePouiller:Git不使用任何常见的问题跟踪软件。如果愿意,您可以提交一个bug报告,但是如果您搜索Git邮件列表存档,您会发现,
--follow
是一个多次出现的黑客行为。还没有人能想出一个令人满意的重写方法……
git log--follow
使用目录时没有任何问题,最简单的例子是:
git log--follow.
我得到了当前目录中所有文件的git日志(git版本2.25.1)。类似地,pathspec选项也可以工作
git log--…
@bloody:目录永远不会重命名;
--follow
选项在这种情况下不起作用。问得好。你找到答案了吗?
./script.py src/*