Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GIT pull conflict: how come not on any branch?

Tags:

git

I have a branch checked out and I edit and commited a file. In the meanwhile, someone else pushed changed to the same file.

When I do a git pull, I see

First, rewinding head to replay your work on top of it...
Applying: add new line
Applying: create 1 conf
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging <filename>
CONFLICT (add/add): Merge conflict in <filename>
Recorded preimage for '<filename>'
Failed to merge in the changes.
Patch failed at 0002 create 1 conf
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

I tried to manually resolve the conflict in the file, however I see that I am not on any branch. I am wondering why this is happening.

git status
# Not currently on any branch.
# Untracked files:
like image 929
user1801669 Avatar asked May 04 '13 22:05

user1801669


2 Answers

This is normal. You just need to fix the file and then follow the rebase instructions - generally with --continue.

You resolve the issue by

  1. edit the files to resolve the conflict
  2. perform git checkout --ours -- <filenames> if you know your version to be good
  3. perform git checkout --theirs -- <filenames> if theirs is good.

Follow all of these up with git add <filenames>. Note that --ours and --theirs can be swapped in some cases from what you might expect; so check the file that is actually checked-out if you use options 2 or 3.

Conclude with git rebase --continue (which will do the commit for you). If you do decide to abort be sure to use git rebase --abort so that git can get you out of the 'not on any branch' condition.

like image 145
GoZoner Avatar answered Sep 23 '22 21:09

GoZoner


I am not on any branch. I am wondering why this is happening?

Trying to answer this and help understand what's going on -- rather than just a recipe to 'stick your head back on' from the headless state:

  • you seem to be using a git config setting (pull.rebase or branch.*rebase) which directs git pull to do a fetch+rebase rather than a fetch+merge
  • rebase is basically replaying your local commits on top of the remote branches' head (ie whatever the latest commit there is).. this involves the following:

    1. git retrieves the list of local commits since your last fetch/pull, and the commits the other guys did on the remote branch
    2. in your case it finds out the above 2 have diverged (so not a fast-forward case)
    3. it checks out the latest revision of the remote branch. Note: it doesn't checkout the remote branch itself, that is: doesn't set the HEAD reference to remote/yourbranch as it's forbidden (because it's a readonly mirror of the remote repo, so you cannot update it directly by a commit). That's what it means to be in headless state.
    4. it attempts to cherry-pick(replay) your commits one-by-one onto that point, building up a similar history to what you have done(with the same sequence of diffs/patches), except now it's based on the latest and greatest

      4.1. In case any patch results in a conflict during step 4, the process will pause to let you resolve it. That's when you realise you're in a strange state: status says "not on any branch", gitk will show no head label on the latest commit. So just follow the advice git is suggesting: resolve conflicts, stage the changes(git add), then just ..

      4.2. git rebase --continue to resume the process (no commit required, git will do it for you). Goto 4. Alternatively, you may want drop you change by --skip or if you're too confused, --abort will reset everything to where it was before the rebase part.

    5. after all commits are done (that is: patches applied), it moves(resets) yours original branch reference to this to tip of rebased history(btw,abandoning the original sequence of commits in favour of the replayed history).. So now, you automatically get a brand new HEAD (your branch ref). Headlessness is over, you wouldn't notice have been in that state for a moment

If you happened to use git config pull.rebase=false or (branch.*rebase), you would have avoided this scary state (and potentially more conflicts) - however you may get noisier history with a lot of merges instead. (Personally It's also possible to switch this off for a single pull by passing --no-rebase.

More in depth about rebase: http://git-scm.com/book/en/Git-Branching-Rebasing .

hope this helps.

like image 41
inger Avatar answered Sep 25 '22 21:09

inger