我们正在尝试获取 Gitlab 存储库中每个文件的提交。我们正在使用 Python Gitlab 模块。我们可以获取存储库的提交,但无法获取存储库中单个文件的提交。有人可以帮助我们吗?
问问题
150 次
1 回答
3
单个文件的提交历史不会直接通过 GitLab API 公开。因此,python-gitlabgitlab
模块中没有直接的功能。
但是,您可以通过使用可用的 API 有效地获取相同的信息。具体来说,您可以使用存储库提交 API和差异 API 或文件责备 API。
使用提交 API
例如,使用提交 API,您可以列出所有提交及其差异,然后为每个提交关联文件更改。
import gitlab
from collections import defaultdict
TOKEN = 'Your API Token'
gl = gitlab.Gitlab('https://gitlab.example.com', private_token=TOKEN)
project = gl.projects.get(1234)
commits = project.commits.list(all=True)
# file paths and a list of commits which create/modify/delete the file
file_map = defaultdict(list)
for c in commits:
diff = c.diff()
files_changed = set()
for change in diff:
files_changed.add(change['old_path'])
files_changed.add(change['new_path'])
for path in files_changed:
file_map[path].append(c)
# show list of commits which modified README.md
print(file_map['README.md'])
使用责备 API
使用提交 API 需要获取每个提交的差异,这在大型存储库上可能需要很长时间。
如果您只对更改单个文件的提交感兴趣,那么遍历责备树可能会更有效。但是,请注意,您也可能会错过使用此方法的提交(例如,其他分支或分支树中的提交)。
def search_blame(project, filename, base_ref=None):
if base_ref is None:
base_ref = project.default_branch
commits = set()
refs_to_check = [base_ref,]
seen = set()
while refs_to_check:
ref = refs_to_check.pop()
if ref in seen:
continue
seen.add(ref)
blame = project.files.blame(filename, ref)
for change in blame:
commit_id = change['commit']['id']
if commit_id not in seen:
refs_to_check.append(commit_id)
refs_to_check.extend(change['commit']['parent_ids'])
for c in change['commit']['parent_ids']:
commits.add(c)
commits.add(commit_id)
return commits
# show commits in blame tree for README.md
# only includes commits in the default branch
print(search_blame(project, 'README.md'))
于 2022-01-19T19:45:10.250 回答