title: Implementing Pull with Pygit2
body: <p>I am trying to implement some 'porcelain' commands using pygit2. It seems that I have run into a bit of road block while implementing pull. Specifically the easiest pull case, a fast forward.</p>
  
  <p><strong>Setup:</strong></p>
  
  <p>I have two git repos. One 'remote' and one 'local'. I make one commit on the remote repo and then create the local repo using pygit2's <code>clone_repository()</code>. I make a subsequent commit on the remote and then attempt to run the <code>pull()</code> function outlined below.</p>
  
  <p><strong>My implementation:</strong></p>
  
  <pre><code>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 &amp; pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE:
                  return
              # We can just fastforward
              elif merge_result &amp; 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 &amp; 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')
  </code></pre>
  
  <p><a href="https://github.com/MichaelBoselowitz/pygit2-examples/blob/master/examples.py" rel="nofollow noreferrer">Full Source</a></p>
  
  <p>After the fast forward bit of my code executes, my index is no longer clean and I have no idea why. Looking at the git-log, it looks successful. My head and the master branch are now pointing at the most recent commit on the remote repo. However, why was <code>remote_repo_test.txt</code> modified in the process of running <code>set_target()</code>. </p>
  
  <p><strong>The Outputs:</strong></p>
  
  <p>The pull print statements:</p>
  
  <pre><code>abfe58ce5098e106a14263df725247bc1f4b22d2
  {}
  {'remote_repo_test.txt': 2} 
  </code></pre>
  
  <p>Git log:</p>
  
  <pre><code>* commit b1842f03efe959e93ebad197f36d50ee658e71a4
  | Author: Michael Boselowitz &lt;xxx&gt;
  | 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 &lt;xxx&gt;
    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.
    +
  </code></pre>
  
  <p>Git status:</p>
  
  <pre><code>On branch master
  Your branch is up-to-date with 'origin/master'.
  
  Changes to be committed:
    (use "git reset HEAD &lt;file&gt;..." to unstage)
  
      modified:   remote_repo_test.txt
  </code></pre>
  
  <p>remote_repo_test.txt content:</p>
  
  <pre><code>Version 1.
  </code></pre>
  
  <p><strong>Related Questions without Answers:</strong></p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/23200789/pulling-and-integrating-remote-changes-with-pygit2">pulling and integrating remote changes with pygit2</a></li>
  <li><a href="https://stackoverflow.com/questions/15492375/implementing-git-pull-with-libgit2">Implementing 'git pull' with libgit2?</a></li>
  <li><a href="https://stackoverflow.com/questions/27072920/performing-a-fast-forward-merge-with-rugged">Performing a “fast-forward” merge with Rugged</a></li>
  </ul>
  
  <p>Thoughts?</p>