首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用GitPython查找分支上的第一个提交

使用GitPython查找分支上的第一个提交
EN

Stack Overflow用户
提问于 2013-08-29 13:11:17
回答 3查看 4.8K关注 0票数 5

我正在使用Python和Git-Python编写一个git post-receive钩子,它收集关于推送中包含的提交的信息,然后用摘要更新我们的bug跟踪器和IM。在推送创建分支(即post-receive的fromrev参数为全零)并在该分支上跨越多个提交的情况下,我遇到了麻烦。我从torev提交开始向后遍历父级列表,但是我不知道如何辨别哪个提交是分支中的第一个提交,即何时停止查找。

在命令行上,我可以执行以下操作

代码语言:javascript
复制
git rev-list this-branch ^not-that-branch ^master

它会给出this-branch中的提交列表,而不是其他的。我曾尝试使用Commit.iter_parents方法复制此方法,该方法的文档中使用了与git-rev-list相同的参数,但据我所知它不喜欢位置参数,并且我找不到一组有效的关键字参数。

我读了Dulwich的文档,但不清楚它的功能是否会与Git-Python有很大的不同。

我的(简化)代码如下所示。当推送启动一个新的分支时,它当前只会查看第一次提交,然后停止:

代码语言:javascript
复制
import git
repo = git.Repo('.')
for line in input:
    (fromrev, torev, refname) = line.rstrip().split(' ')
    commit = repo.commit(torev)
    maxdepth = 25    # just so we don't go too far back in the tree
    if fromrev == ('0' * 40):
        maxdepth = 1
    depth = 0
    while depth < maxdepth:
        if commit.hexsha == fromrev:
            # Reached the start of the push
            break
        print '{sha} by {name}: {msg}'.format(
            sha = commit.hexsha[:7], user = commit.author.name, commit.summary)
        commit = commit.parents[0]
        depth += 1
EN

回答 3

Stack Overflow用户

发布于 2013-09-03 17:18:31

使用纯Git-Python也可以做到。我也没有找到一种方法来识别一组可以一气呵成的kwarg。但是可以简单地构造主分支的一组shas,然后在要检查的分支上使用iter_commits,以便找到第一个没有出现在父分支中的shas:

代码语言:javascript
复制
from git import *

repo_path = '.'
repo = Repo(repo_path)
parent_branch = repo.branches.master
examine_branch = repo.branches.test_feature_branch

other_shas = set()
for parent_commit in repo.iter_commits(rev=parent_branch):
    other_shas.add(parent_commit.hexsha)
for commit in repo.iter_commits(rev=examine_branch):
    if commit.hexsha not in other_shas:
        first_commit = commit

print '%s by %s: %s' % (first_commit.hexsha[:7],
        first_commit.author.name, first_commit.summary)

如果您真的想确保排除所有其他分支上的所有提交,您可以将第一个for循环包装在repo.branches上的另一个for循环中:

代码语言:javascript
复制
other_shas = set()
for branch in repo.branches:
    if branch != examine_branch:
        for commit in repo.iter_commits(rev=branch):
            other_shas.add(commit.hexsha)

  • 警告1:第二种方法显示了没有出现在任何其他分支上的第一次提交,这不一定是该分支上的第一次提交。如果feat_b是从feat_a分支出来的,那么这将在feat_b分支之后显示feat_a上的第一个提交:feat_a的其余提交已经在feat_b上了。
  • 警告2: git rev-list,这两种解决方案只有在分支还没有合并回master的情况下才有效。你实际上是在要求它列出这个分支上的所有提交,而不是另一个分支上的所有提交。
  • 备注:第二种方法过于夸张,需要更多的时间才能完成。一种更好的方法是将其他分支限制在已知合并分支的列表中,如果您拥有的不仅仅是主分支。
票数 5
EN

Stack Overflow用户

发布于 2013-08-30 00:50:26

我只是玩玩了一下达利奇,也许有更好的方法(使用内置步行器?)假设只有一个新分支(或多个没有任何共同之处的新分支):

代码语言:javascript
复制
#!/usr/bin/env python
import sys
from dulwich.repo import Repo
from dulwich.objects import ZERO_SHA


def walk(repo, sha, shas, callback=None, depth=100):
    if not sha in shas and depth > 0:
        shas.add(sha)

        if callback:
            callback(sha)

        for parent in repo.commit(sha).parents:
            walk(repo, parent, shas, callback, depth - 1)


def reachable_from_other_branches(repo, this_branch):
    shas = set()

    for branch in repo.refs.keys():
        if branch.startswith("refs/heads") and branch != this_branch:
            walk(repo, repo.refs[branch], shas)

    return shas


def branch_commits(repo, fromrev, torev, branchname):
    if fromrev == ZERO_SHA:
        ends = reachable_from_other_branches(repo, branchname)
    else:
        ends = set([fromrev])

    def print_callback(sha):
        commit = repo.commit(sha)
        msg = commit.message.split("\n")[0]
        print('{sha} by {author}: {msg}'
              .format(sha=sha[:7], author=commit.author, msg=msg))

    print(branchname)
    walk(repo, torev, ends, print_callback)


repo = Repo(".")
for line in sys.stdin:
    fromrev, torev, refname = line.rstrip().split(' ')
    branch_commits(repo, fromrev, torev, refname)
票数 2
EN

Stack Overflow用户

发布于 2013-10-27 16:38:48

下面这样的代码将会找到第一个提交:

代码语言:javascript
复制
x = Repo('.')
print list(x.get_walker(include=[x.head()]))[-1].commit

(请注意,对于大型存储库,这将使用O(n)内存,使用迭代器来解决此问题)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18502729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档