2015-01-02 57 views
2

我正在尝试使用pygit2来执行一些“瓷器”命令。看起来我在实现pull的时候遇到了一些障碍。特别是最简单的拉动情况,快速前进。使用Pygit2执行Pull

设置:

我有两个混帐回购协议。一个'远程'和一个'本地'。我在远程仓库做了一次提交,然后使用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') 

Full Source

我的代码的快进位执行后,我的指标不再是清白的,我不知道为什么。看着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内容:

​​

相关问题不回答:

的思考?

回答

3

首个解决方案(不推荐):

你应该做到这一点。这样可能会失去工作。但是,它可以作为一个很好的解决方案。

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) 

Full source

二解决方案:

这一次似乎是有前途的。经过多次试验和错误,我可能找到了解决方案。如果您在之前检出您想要定位的目标的树对象,则更新它的工作原理。该指数是干净的就像运行git pullgit 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) 

Full source

时,你会想到什么