git日志有什么诀窍吗--跟踪一个已重命名的目录?
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 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日志,并通过更少的管道传递它
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/*