我目前正在运行Pygit 0.24.1(以及libgit 0.24.1),在一个存储库中工作,我有两个分支(比如prod
和dev
)。
每次更改都首先提交到dev
分支并推送到远程存储库。为此,我有这段代码:
repo = Repository('/foo/bar')
repo.checkout('refs/heads/dev')
index = repo.index
index.add('any_file')
index.write()
tree = index.write_tree()
author = Signature('foo', 'foo@bar')
committer = Signature('foo', 'foo@bar')
repo.create_commit('refs/heads/dev', author, committer, 'Just another commit', tree, [repo.head.get_object().hex])
up = UserPass('foo', '***')
rc = RemoteCallbacks(credentials=up)
repo.remotes['origin'].push(['refs/heads/dev'], rc)
这很好用,我可以看到本地提交和远程提交,并且本地仓库保持清洁:
无需提交,工作目录清理
接下来,我签出prod
分支,我想合并dev
上的HEAD提交。为此,我使用另一段代码(假设我总是开始签出dev
分支):
head_commit = repo.head
repo.checkout('refs/heads/prod')
prod_branch_tip = repo.lookup_reference('HEAD').resolve()
prod_branch_tip.set_target(head_commit.target)
rc = RemoteCallbacks(credentials=up)
repo.remotes['origin'].push(['refs/heads/prod'], rc)
repo.checkout('refs/heads/dev')
我实际上可以看到分支在本地和远程合并,但在这段代码运行后,提交的文件始终保持在分支上的修改状态{ {1}}。
在分支开发
上要提交的更改: (使用" git reset HEAD ..."取消暂停)
修改:any_file
我完全确定没有人正在修改该文件。实际上,dev
没有显示任何内容。此问题仅在已提交的文件(即先前至少提交过一次的文件)中发生。当文件是新文件时,这样可以完美地工作并使文件处于干净状态。
我确定我错过了一些细节,但我无法找出它是什么。为什么文件保留为修改?
编辑:为了澄清,我的目标是进行FF(快进)合并。我知道有关于在Pygit2文档中进行非FF合并的一些文档,但是我更喜欢第一种方法,因为它通过分支保持提交哈希值。
编辑2 :在@Leon的评论之后,我进行了双重检查,确实git diff
显示没有输出,git diff
显示文件的内容< em>在提交之前。这是奇怪的,因为我可以看到更改成功提交到本地和远程存储库,但看起来之后文件再次更改为以前的内容...
一个例子:
git diff --cached
显示正确提交的文件,在远程仓库中我看到包含内容的文件&#39; 54321&#39;,而本地git log
显示:
git diff --cached
答案 0 :(得分:3)
我会解释观察到的问题如下:
head_commit = repo.head
# This resets the index and the working tree to the old state
# and records that we are in a state corresponding to the commit
# pointed to by refs/heads/prod
repo.checkout('refs/heads/prod')
prod_branch_tip = repo.lookup_reference('HEAD').resolve()
# This changes where refs/heads/prod points. The index and
# the working tree are not updated, but (probably due to a bug in pygit2)
# they are not marked as gone-out-of-sync with refs/heads/prod
prod_branch_tip.set_target(head_commit.target)
rc = RemoteCallbacks(credentials=up)
repo.remotes['origin'].push(['refs/heads/prod'], rc)
# Now we must switch to a state corresponding to refs/heads/dev. It turns
# out that refs/heads/dev points to the same commit as refs/heads/prod.
# But we are already in the (clean) state corresponding to refs/heads/prod!
# Therefore there is no need to update the index and/or the working tree.
# So this simply changes HEAD to refs/heads/prod
repo.checkout('refs/heads/dev')
解决方案是快速转发分支而不检查它。以下代码没有描述的问题:
head_commit = repo.head
prod_branch_tip = repo.lookup_branch('prod')
prod_branch_tip.set_target(head_commit.target)
rc = RemoteCallbacks(credentials=up)
repo.remotes['origin'].push(['refs/heads/prod'], rc)