0

When pulling and integrating changes from remote with pygit2, the last step is to checkout using Repository.checkout() or Repository.checkout_head(). Which to use?

Both of these take a checking out strategy as an argument. Now there are a couple of strategies for checking out viz GIT_CHECKOUT_SAFE, GIT_CHECKOUT_SAFE_CREATE, GIT_CHECKOUT_FORCE etc.
The problem I am facing is that even after checking out the index file is modified ie there are a couple of files in it that are staged.

r.repo.status()
{'README.md': 2}

When using the strategy GIT_CHECKOUT_FORCE the indexed is empty and the commits are also being stored.

When should GIT_CHECKOUT_FORCE strategy not be used?
Here is the step by step code of the process:
r.repo is Repository object. remo is the remote with name ssh-sansa

>>> r.repo.status()
{}
>>> z = remo.fetch()
>>> remoref = r.repo.lookup_reference('refs/remotes/ssh-sansa/master')
>>> rref = r.repo.lookup_reference(r.ref)
>>> r.ref
'refs/heads/master'
>>> remoref.target.hex
'23aac24f65c775d0524095d422133c63caf3826a'
>>> rref.target.hex
'29f5f99722e9c93a58ec085a55c6a4814c4adffb'
>>> rref.target=remoref.target.hex
>>> rref.target.hex
'23aac24f65c775d0524095d422133c63caf3826a'
>>> r.repo.status()
{'README.md': 2}
>>> r.repo.checkout_head(repo_.pygit2.GIT_CHECKOUT_SAFE_CREATE)
>>> r.repo.status()
{'README.md': 2}
>>> r.repo.checkout('HEAD',strategy=repo_.pygit2.GIT_CHECKOUT_SAFE_CREATE)
>>> r.repo.status()
{'README.md': 2}
>>> r.repo.checkout('HEAD',strategy=repo_.pygit2.GIT_CHECKOUT_FORCE)
>>> r.repo.status()
{}

Note: This is a follow up question to pulling and integrating changes using pygit2 and another question here

Community
  • 1
  • 1
avck
  • 3,535
  • 3
  • 26
  • 38

1 Answers1

0

There is no difference. If you pass a refname of 'HEAD' to Repository.checkout(), it will call Repository.checkout_head().

As to why the file remains modified, it is because you've told the library not to overwrite changes. See the strategy docs for a description of what each strategy does. Specifically,

In between those are GIT_CHECKOUT_SAFE and GIT_CHECKOUT_SAFE_CREATE both of which only make modifications that will not lose changes.

As your file is modified, overwriting it would cause us to lose changes and hence it refuses to. If you want to overwrite it, then use FORCE or cause the file not to be in a modified state.

Carlos Martín Nieto
  • 5,207
  • 1
  • 15
  • 16
  • After `Reference.target= ` The commit history changes, (it now has the new commit too pulled from remote) and the changes that were made at the remote show in the files. So which changes will be lost? – avck Jul 11 '14 at 11:29
  • **In libgit2, checkout is used to update the working directory and index to match a target tree.** What will be the target tree after pulling from remote? – avck Jul 11 '14 at 11:30
  • The changes that would be lost are the ones that the status is telling you, `README.txt`. Changing the current branch is the **last** thing you should be doing, both for sanity (as in this case, in which the status would no longer agree anymore) and for ease of rollback if something fails. – Carlos Martín Nieto Jul 11 '14 at 12:07
  • But despite using GIT_CHECKOUT_FORCE the changes made at the remote README are visible in local README and the modifications are not lost. This is where i am *confused*. Why aint the changes being lost? – avck Jul 11 '14 at 12:25
  • README is updated **because** you passed `FORCE`. The first thing your code is doing is changing the current commit from under the index and workdir, which is why status is reporting it's modified. It has staged contents which are not present in the current commit. Status and checkout have no idea that those changes are stored somewhere else because you removed that information. – Carlos Martín Nieto Jul 11 '14 at 12:48
  • So what do you suggest how to go about it, to make the changes commited ? – avck Jul 11 '14 at 12:52
  • This is the first time you've brought up committing in this whole series of questions. As far as making a branch reflect what was fetched, you should use FORCE and make the reference change the last step, as I stated above. – Carlos Martín Nieto Jul 11 '14 at 15:39
  • My bad, but it was always about committing changes fetched from remote. But reference change should be last step? We need to change the reference before checking out, right? – avck Jul 11 '14 at 19:23
  • Again, updating the reference is the *last* step. The changes from the remote are already committed, otherwise you wouldn't be able to download them. If you want to create a *merge*, then use the merge methods for that. It seems you need to take a step back and go over the Git system concepts; the names for concepts you bring up keep sounding odd for the situation. – Carlos Martín Nieto Jul 12 '14 at 07:49