如何使用GitPython将主分支合并到一个特性分支?

7
我正在尝试自动化一些标准工作流程,其中一个经常做的事情是将远程主分支的更改合并到我的本地分支中并推送结果。
因此,步骤如下:
  1. 切换到主分支
  2. 从远程拉取更改
  3. 切换到原始特性分支
  4. 从主分支合并到特性分支
  5. 将特性分支推送到远程
我一直在尝试编写一个简短的Python脚本来完成这个过程,但我卡在第4步。我无法理解文档以确定如何执行此操作。
使用git.exe本身,我只需执行以下操作:git.exe merge master 使用GitPython模块是否可行?如果可以,应该如何操作?
2个回答

12
除非有非常充分的理由,否则我建议只使用git二进制文件来执行您的任务。但是,如果您想使用GitPython完成此操作,请查看文档中的高级Repo使用部分,其中包括一个合并操作示例。
例如,假设我有一个名为mainfeature的两个分支的存储库。我目前在feature分支上,并且我想将main的更改合并到feature中。
我首先初始化一个Repo对象:
>>> import git
>>> repo = git.Repo('.')

现在我需要获取当前分支的引用;我可以这样做:

>>> current = repo.active_branch
>>> current
<git.Head "refs/heads/feature">

或者我可以通过名称获取分支:

>>> current = repo.branches['feature']
>>> current
<git.Head "refs/heads/feature">

我还需要一个指向main分支的参考:

>>> main = repo.branches['main']
>>> main
<git.Head "refs/heads/main">

现在我需要找到这两个分支的合并基础(也就是它们分开的那个点):

>>> base = repo.merge_base(current, main)
>>> base
[<git.Commit "9007141b5daa35c39afda2d6baf670438d7424a7">]

现在我们进行合并操作:

>>> repo.index.merge_tree(main, base=base)
<git.index.base.IndexFile object at 0x7fa8bb6a9f70>

并将其提交,提供指向两个父提交的链接:

>>> repo.index.commit('Merge main into feature',
... parent_commits=(current.commit, main.commit))
<git.Commit "fb7051d7be36b7998a8f6c480120f84f3f9d9f73">
>>> 

此时,我们已经成功合并了两个分支,但是我们没有修改工作目录。如果我们返回到shell提示符,git status命令将显示file1已被修改(因为它不再与存储库中的内容匹配):

$ git status
On branch feature
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   file1

我们需要对新提交进行结账:

>>> current.checkout(force=True)
<git.Head "refs/heads/feature">

现在:

$ git status
On branch feature
nothing to commit, working directory clean

上述过程是脆弱的;如果存在合并冲突,它只会失败,这就是为什么你最好坚持使用命令行界面。


谢谢,这真的很有用。即使您使用CLI,合并过程中仍可能出现问题,正如您所建议的那样,因此无论如何,您都必须检查和处理合并冲突,对吧?或者您上面提到的方法甚至更加危险? :-) - Jon Cage
我并不认为它有什么危险的必要,但是 git 命令行界面经过了大量测试,并被设计成面向终端用户的工具,因此可能会以更实用的方式响应错误。 - larsks
好的,明白了。我想我可以使用你上面发布的内容,然后通过CLI解决合并问题,最后恢复我的脚本以执行最后几个命令。 - Jon Cage
现在,如果我能想出如何模拟用户解决问题的过程就好了:http://stackoverflow.com/questions/36843061 ;-) - Jon Cage

1
合并 source_branchdest_branch:
def merge(source_branch, dest_branch):
    repo = git.Repo(repository_path)
    repo.git.checkout(dest_branch)
    repo.git.merge(source_branch)
    origin = repo.remote(name='origin')
    origin.push()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接