使用 Pygit2 实现拉取
Implementing Pull with Pygit2
我正在尝试使用 pygit2 实现一些 'porcelain' 命令。看来我在实施拉动时遇到了一些障碍。特别是最简单的 pull case,快进。
设置:
我有两个 git 回购协议。一个 'remote' 和一个 'local'。我对远程仓库进行了一次提交,然后使用 pygit2 的 clone_repository()
创建本地仓库。我在遥控器上进行了后续提交,然后尝试运行下面概述的 pull()
函数。
我的实现:
def pull(repo, remote_name='origin'):
for remote in repo.remotes:
if remote.name == remote_name:
remote.fetch()
remote_master_id = repo.lookup_reference('refs/remotes/origin/master').target
merge_result, _ = repo.merge_analysis(remote_master_id)
# Up to date, do nothing
if merge_result & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE:
return
# We can just fastforward
elif merge_result & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD:
print repo.head.target
print repo.status()
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
repo.head.set_target(master_ref)
repo.checkout_head()
print repo.status()
elif merge_result & pygit2.GIT_MERGE_ANALYSIS_NORMAL:
repo.merge(remote_master_id)
print repo.index.conflicts
assert repo.index.conflicts is None, 'Conflicts, ahhhh!'
user = repo.default_signature
tree = repo.index.write_tree()
commit = repo.create_commit('HEAD',
user,
user,
'Merge!',
tree,
[repo.head.target, remote_master_id])
repo.state_cleanup()
else:
raise AssertionError('Unknown merge analysis result')
在我的代码的快进位执行后,我的索引不再干净,我不知道为什么。查看git-log,看起来成功了。我的头和主分支现在指向远程仓库上的最新提交。但是,为什么在运行set_target()
的过程中修改了remote_repo_test.txt
。
输出:
拉打印语句:
abfe58ce5098e106a14263df725247bc1f4b22d2
{}
{'remote_repo_test.txt': 2}
Git 日志:
* commit b1842f03efe959e93ebad197f36d50ee658e71a4
| Author: Michael Boselowitz <xxx>
| Date: Fri Jan 2 17:21:45 2015 -0500
|
| Version 2 of test.txt on remote_repo
|
| diff --git a/remote_repo_test.txt b/remote_repo_test.txt
| index a1665f0..13f7f3f 100644
| --- a/remote_repo_test.txt
| +++ b/remote_repo_test.txt
| @@ -1,2 +1,4 @@
| Version 1.
|
| +Version 2.
| +
|
* commit abfe58ce5098e106a14263df725247bc1f4b22d2
Author: Michael Boselowitz <xxx>
Date: Fri Jan 2 17:21:45 2015 -0500
Version 1 of test.txt on remote_repo
diff --git a/remote_repo_test.txt b/remote_repo_test.txt
new file mode 100644
index 0000000..a1665f0
--- /dev/null
+++ b/remote_repo_test.txt
@@ -0,0 +1,2 @@
+Version 1.
+
Git 状态:
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: remote_repo_test.txt
remote_repo_test.txt内容:
Version 1.
没有答案的相关问题:
- pulling and integrating remote changes with pygit2
- Implementing 'git pull' with libgit2?
- Performing a “fast-forward” merge with Rugged
想法?
第一个方案(不推荐):
你应该不这样做。这样可能会丢失工作。然而,它作为一个 hacky 解决方案。
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
# Terrible hack to fix set_target() screwing with the index
repo.reset(master_ref.target, pygit2.GIT_RESET_HARD)
第二种解法:
这个看起来很有前途。经过反复试验,我可能找到了解决方案。如果您在 之前签出要定位的树对象,然后 更新它的引用。当 运行 a git pull
或 git merge
时,索引是干净的
repo.checkout_tree(repo.get(remote_master_id))
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
repo.head.set_target(remote_master_id)
我正在尝试使用 pygit2 实现一些 'porcelain' 命令。看来我在实施拉动时遇到了一些障碍。特别是最简单的 pull case,快进。
设置:
我有两个 git 回购协议。一个 'remote' 和一个 'local'。我对远程仓库进行了一次提交,然后使用 pygit2 的 clone_repository()
创建本地仓库。我在遥控器上进行了后续提交,然后尝试运行下面概述的 pull()
函数。
我的实现:
def pull(repo, remote_name='origin'):
for remote in repo.remotes:
if remote.name == remote_name:
remote.fetch()
remote_master_id = repo.lookup_reference('refs/remotes/origin/master').target
merge_result, _ = repo.merge_analysis(remote_master_id)
# Up to date, do nothing
if merge_result & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE:
return
# We can just fastforward
elif merge_result & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD:
print repo.head.target
print repo.status()
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
repo.head.set_target(master_ref)
repo.checkout_head()
print repo.status()
elif merge_result & pygit2.GIT_MERGE_ANALYSIS_NORMAL:
repo.merge(remote_master_id)
print repo.index.conflicts
assert repo.index.conflicts is None, 'Conflicts, ahhhh!'
user = repo.default_signature
tree = repo.index.write_tree()
commit = repo.create_commit('HEAD',
user,
user,
'Merge!',
tree,
[repo.head.target, remote_master_id])
repo.state_cleanup()
else:
raise AssertionError('Unknown merge analysis result')
在我的代码的快进位执行后,我的索引不再干净,我不知道为什么。查看git-log,看起来成功了。我的头和主分支现在指向远程仓库上的最新提交。但是,为什么在运行set_target()
的过程中修改了remote_repo_test.txt
。
输出:
拉打印语句:
abfe58ce5098e106a14263df725247bc1f4b22d2
{}
{'remote_repo_test.txt': 2}
Git 日志:
* commit b1842f03efe959e93ebad197f36d50ee658e71a4
| Author: Michael Boselowitz <xxx>
| Date: Fri Jan 2 17:21:45 2015 -0500
|
| Version 2 of test.txt on remote_repo
|
| diff --git a/remote_repo_test.txt b/remote_repo_test.txt
| index a1665f0..13f7f3f 100644
| --- a/remote_repo_test.txt
| +++ b/remote_repo_test.txt
| @@ -1,2 +1,4 @@
| Version 1.
|
| +Version 2.
| +
|
* commit abfe58ce5098e106a14263df725247bc1f4b22d2
Author: Michael Boselowitz <xxx>
Date: Fri Jan 2 17:21:45 2015 -0500
Version 1 of test.txt on remote_repo
diff --git a/remote_repo_test.txt b/remote_repo_test.txt
new file mode 100644
index 0000000..a1665f0
--- /dev/null
+++ b/remote_repo_test.txt
@@ -0,0 +1,2 @@
+Version 1.
+
Git 状态:
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: remote_repo_test.txt
remote_repo_test.txt内容:
Version 1.
没有答案的相关问题:
- pulling and integrating remote changes with pygit2
- Implementing 'git pull' with libgit2?
- Performing a “fast-forward” merge with Rugged
想法?
第一个方案(不推荐):
你应该不这样做。这样可能会丢失工作。然而,它作为一个 hacky 解决方案。
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
# Terrible hack to fix set_target() screwing with the index
repo.reset(master_ref.target, pygit2.GIT_RESET_HARD)
第二种解法:
这个看起来很有前途。经过反复试验,我可能找到了解决方案。如果您在 之前签出要定位的树对象,然后 更新它的引用。当 运行 a git pull
或 git merge
repo.checkout_tree(repo.get(remote_master_id))
master_ref = repo.lookup_reference('refs/heads/master')
master_ref.set_target(remote_master_id)
repo.head.set_target(remote_master_id)