python - 如何使用 GitPython 进行 pull ?

标签 python git gitpython

我正在使用 GitPython 从 Gitlab 服务器克隆存储库。

git.Repo.clone_from(gitlab_ssh_URL, local_path)

稍后我有另一个脚本试图更新这个 repo。

try:
    my_repo = git.Repo(local_path)
    my_repo .remotes.origin.pull()

except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
    print("Invalid repository: {}".format(local_path)

这很好用,除非我在中间 checkout 这样的标签:

tag_id = choose_tag()    # Return the position of an existing tag in my_repo.tags
my_repo .head.reference = my_repo.tags[tag_id]
my_repo .head.reset(index=True, working_tree=True)

在这种情况下,我在 pull 时收到 GitCommandError:

git.exc.GitCommandError: 'git pull -v origin' returned with exit code 1

我已经阅读了两次文档,但我看不出问题出在哪里。特别是因为如果我尝试使用像 SourceTree 这样的专用工具 Pull 这个 repo,它可以正常工作而没有错误或警告。 我不明白我 checkout 带标签版本的事实是如何阻止我 pull 的。

  1. 在这种情况下我应该怎么做?
  2. 这里发生了什么,我错过了什么?

编辑:作为建议,我尝试查看 exception.stdout 和 exception.sterr,但这里没有任何用处(分别是 b'' 和 None)。这就是为什么我很难理解哪里出了问题。

最佳答案

我认为最好先详细了解正在发生的事情(问题 2:发生了什么?),这应该会引导您找到问题 1 的答案(如何解决这个问题?)。

要了解更多有关问题的信息,您可以打印出 stdoutstderr从异常(exception)。 Git 通常会将错误详细信息打印到控制台,因此应该在 stdout 中或 stderr .

try:
    git.Repo.clone_from(gitlab_ssh_URL, local_path)
except git.GitCommandError as exception:
    print(exception)
    if exception.stdout:
        print('!! stdout was:')
        print(exception.stdout)
    if exception.stderr:
        print('!! stderr was:')
        print(exception.stderr)

附带说明一下,我自己在对 git.Repo 进行多次操作时遇到了一些问题。对象在使用它与后端交互之前(即 git 本身)。在我看来,GitPython 端有时似乎存在一些数据缓存问题,并且存储库(.git 目录)中的数据与 git.Repo 中的数据结构之间缺乏同步。对象。

编辑:

好吧,问题似乎出在 pull 分离的头上——这可能不是你想要做的。

不过,您可以解决您的问题。因为你是独立的头git checkout master只是为了做git pull然后你回到分离的头,你可以跳过 pull ,而是使用 git fetch <remote> <source>:<destination>像这样:git fetch origin master:master .这将获取远程并 merge 您的本地 master带有跟踪分支的分支而不检查它,因此您可以一直保持分离的头部状态而不会出现任何问题。有关非常规使用 fetch 命令的更多详细信息,请参阅此 SO 答案:https://stackoverflow.com/a/23941734/4973698

使用 GitPython,代码可能如下所示:

my_repo = git.Repo(local_path)
tag_id = choose_tag() # Return the position of an existing tag in my_repo.tags
my_repo.head.reference = my_repo.tags[tag_id]
my_repo.head.reset(index=True, working_tree=True)
fetch_info = my_repo.remotes.origin.fetch('master:master')
for info in fetch_info:
    print('{} {} {}'.format(info.ref, info.old_commit, info.flags))

它会打印出这样的东西:

master 11249124f123a394132523513 64 

... 所以标志等于 64 .这是什么意思?当你做 print(git.FetchInfo.FAST_FORWARD)结果是 64所以这意味着 fetch 是 Fast-Forward 类型的,因此你的本地分支成功地与远程跟踪分支 merge ,即你已经执行了 git pull origin master不检查主人。

重要说明:只有当您的分支可以使用快进 merge 与远程分支 merge 时,这种提取才有效。

关于python - 如何使用 GitPython 进行 pull ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36891470/

相关文章:

python - 为 arm 交叉编译 py-spidev

python - 将时间四舍五入到最后 30 分钟间隔

python - Selenium 错误 : element not visible (different behaviour on two computers)

git - 如何在git中实现 "first-parent"merge ?

ios - 我应该提交 ios/Runner.xcworkspace/xcshareddata/吗?

python - 推送到远程仓库

python - git-clean 与 GitPython

python - 谷歌 BigQuery : creating a view via Python google-cloud-bigquery version 0. 27.0 与 0.28.0

LFS 的 Git 到 BitBucket 迁移问题

python - 为什么 Windows 上的 gitpython 总是出现文件未找到的错误?