如何使用python(dulwich)获取指定文件的最后提交



我需要作者的名字和最后提交时间为指定的文件与python。目前,我正在尝试使用dulwich。

有很多api可以检索特定SHA的对象,例如:

repo = Repo("myrepo")
head = repo.head()
object = repo.get_object(head)
author = object.author
time = object.commit_time

但是,我怎么知道最近提交的特定文件?是否有一种方法来检索它,如:

repo = Repo("myrepo")
commit = repo.get_commit('a.txt')
author = commit.author
time = commit.commit_time

repo = Repo("myrepo")
sha = repo.get_sha_for('a.txt')
object = repo.get_object(sha)
author = object.author
time = object.commit_time

谢谢。

一个更短的例子,使用Repo.get_walker:

r = Repo(".")
p = b"the/file/to/look/for"
w = r.get_walker(paths=[p], max_entries=1)
try:
    c = next(iter(w)).commit
except StopIteration:
     print "No file %s anywhere in history." % p
else:
    print "%s was last changed at %s by %s (commit %s)" % (
        p, time.ctime(c.author_time), c.author, c.id)

像这样的东西似乎可以工作:

from dulwich import repo, diff_tree
fn = 'a.txt'
r = repo.Repo('.')
prev = None
walker = r.get_graph_walker()
cset = walker.next()
while cset is not None:
    commit = r.get_object(cset)
    if prev is None:
        prev = commit.tree
        cset = walker.next()
        continue

    res = None
    delta = diff_tree.tree_changes(r, prev, commit.tree)
    for x in diff_tree.tree_changes(r, prev, commit.tree):
        if x.new.path == fn:
            res = cset
            break
    if res:
        break
    prev = commit.tree
    cset = walker.next()
print fn, res

python 3.10和Dulwich 0.20.32或更高版本基于@jelmer here的答案更新。

from dulwich import repo
import datetime
r = repo.Repo("path/to/repo")
p = b"relative/path/to/file/in/repo" # Must be bytes not string
w = r.get_walker(paths=[p], max_entries=1)
l = list(w)
if l:
    c = l[0].commit
    when = datetime.datetime.fromtimestamp(c.author_time)
    print(f"{p} last modified {when} by {c.author} in {c.id}")
else:
    print(f"No file called {p} found in repo")

然而,我发现这非常慢(在我的测试repo 0.688秒)等效使用GitPython更快(0.453秒)对我来说:

import git # import of GitPython
repo = git.repo.Repo("path/to/repo")
p = "relative/path/to/file/in/repo" # Note string rather than bytes
walker = repo.iter_commits(paths=[p, ], max_count=1)
l = list(walker)
if l:
    c = l[0]
    print(f"{p} last modified {c.authored_datetime} by {c.author} in {c}")
else:
    print(f"No file called {p} found in repo")

相关内容

  • 没有找到相关文章

最新更新