1

I am using pygit2 to merge some branches of a project, however whenever I merge them I end up with:

def avoid_walls(directions, board, snake):
<<<<<<< HEAD
return directions
=======
z = 1
moves = []
for direction in directions:
    new_x = snake[0][0] + dirs[direction][0]
    new_y = snake[0][1] + dirs[direction][1]
    if new_x >= 0 and new_x < len(board[0]) and new_y >= 0 and new_y < len(board):
        moves.append(direction)
return moves
>>>>>>> 357f58b6d1682760b2fa9bf7b2418da347ca353c

in my code. When I check the repo with 'git status' I find this:

HEAD detached from origin/master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

As far as I can tell I am doing everything properly, so I cant figure out why the HEAD is detached. From my understanding, the HEAD is detached when you check out a specific commit, rather than a branch, which I am not doing:

# clone repo to local directory
repo = pygit2.clone_repository(my_repo, my_dir)

# checkout master branch (checked out by default, but just to be safe)
repo.checkout('refs/remotes/origin/master')

# merge with other branches
repo.merge(repo.branches['origin/branch1'].target)

# commit changes
index = repo.index
index.add_all()
index.write()
author = pygit2.Signature("ME", "me@domain.com")
commiter = pygit2.Signature("ME", "me@domain.com")
tree = index.write_tree()
oid = repo.create_commit('refs/heads/master', author, commiter, "init commit", tree, [repo.head.target, repo.branches['origin/branch1'].target])

#some tests i tried to fix the issue
repo.head.set_target(oid)
repo.apply(oid)

Am I missing something after the merge that will complete the commit and resolve this issue?

Pottsiex5
  • 487
  • 2
  • 6
  • 19

1 Answers1

2

refs/remotes/origin/master is not a branch. All branches start with refs/heads/:

if name.startswith('refs/heads/'):
    print('{} is a branch name'.format(name))
else
    print('{} is not a branch name'.format(name))

In this case, since it starts with refs/remotes/, it's a remote-tracking name (Git documentation generally calls this a remote-tracking branch name, but I think this is too misleading since that contains the word branch even though it's not a branch name).

When you check out a remote-tracking name, or a tag name, or any name that is not a branch name, you are really checking out a specific commit and will get a detached HEAD.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks for the explanation, that makes sense. None of my branches are showing up in /refs/heads/, even when I check them out (same method as before). How can I get all of my branches cloned locally to refs/heads? – Pottsiex5 Jun 10 '19 at 14:03
  • I managed to get the cloned to /refs/heads using code found here: https://stackoverflow.com/questions/34711540/cloning-only-the-main-branch-using-pygit2 This hasn't resolved the 'you are still merging' issues, but now that the detached head is resolved I feel like looking more at the docs should hopefully sort out the issue of not being able to commit. – Pottsiex5 Jun 10 '19 at 14:56
  • 1
    I'm not sure what pygit2 does in each case. In *Git* in general, `git checkout X` (for any X) will first look to see if `X` is a branch name (exists as `refs/heads/X`) and if so switch to that commit+branch. If not, it then looks to see if `X` is some other existing name, and if it's resolvable as exactly one remote-tracking name such as `origin/X`, will in effect run `git checkout -b X origin/X`, creating X pointing to the same commit hash ID as `origin/X` and then checking out the newly-created X. – torek Jun 10 '19 at 15:25