17

Got 3 commits - one proper, and then two silly cleanup ones, typos etc. So I want to squash them. Fire away:

git rebase -i HEAD~3

Sounds simple, and it should work - I've tried it after running into a problem, in a brand new repo, and it works as expected. Editor shows 3 commits, pick the top, squash the other two, save and quit, done. If I run in verbose mode, I see more details - git enters the detached HEAD state by checking out the 1st commit I 'picked', then does 'Rebasing 2/3' and 'Rebasing 3/3', apparently creating some temp commits along the way -- and then a success message; editor pops up again at some point, offering me to change the commit message. All's good.

But same command dies in a work repo! 3 commits in an editor, pick-squash-squash.. but this time, I don't see 'Rebasing 2/3', instead the very first line after 'HEAD is now at my-SHA-1', it runs into a fatal!

HEAD is now at 48a6c3d... <commit message>
fatal: ref HEAD is not a symbolic ref

But why would git expect HEAD to be a symbolic ref? Rebase process does detach HEAD - same as I see in my exploratory example - so why then the fatal in this second example, but not in the first one? cat .git/HEAD give me the SHA1 of the commit I've 'picked'...

I've spend several hours reading and researching, but something's just not right here, and I can't find what it is! I suspect that maybe some hooks are responsible (know little about them, and know the problematic repo does have some). Thank you for your consideration in answering this!

alexakarpov
  • 1,848
  • 2
  • 21
  • 39
  • 3
    If you think that the hooks might be a problem, did you try turning off the hooks? They're located under `.git/hooks/`, just rename them to `.off`. There one pre-rebase hook in particular, `pre-rebase.sample`. –  Aug 07 '13 at 14:28
  • thanks for suggestion - hooks are now somewhat demystified.. it didn't have any effect on the problem, but at least that killed a red herring ) – alexakarpov Aug 07 '13 at 15:22
  • 2
    "symbolic ref" in Git has nothing to do with symbolic links on a filesystem: "the ref" in the Git parlance is an entity pointing to a commit -- a branch or a tag; this is short for "reference". A ref might point directly to the SHA-1 name of a commit (and it's then direct) or to *another* ref, and then it's "symbolic". For instance, `HEAD` typically points to something like `refs/heads/master`, not to the master's tip commit. – kostix Aug 07 '13 at 16:13
  • 1
    thanks @kostix , I didn't even notice how I misquoted git, using 'symbolic link' in place of 'symbolic ref'. So, when in detached HEAD due to 'git checkout some_commit_SHA1', cat .git/HEAD prints exactly that SHA1; if I checkout a branch, it prints something like `ref: refs/heads/master'. So my understanding is, the latter IS a symbolic REF -- but is the SHA-1 of a commit a symbolic REF? It's a REF alright -- looks like, to quote you, it's a 'direct' REF. If so, then it clears up some confusion -- but doesn't explain what causes the fatal in one case, but not in other... – alexakarpov Aug 07 '13 at 17:17
  • 1
    ran this: `$ git symbolic-ref 48a6c3d62b81d94ac79c3f039bfe9b924b6744f0` got this `fatal: ref 48a6c3d62b81d94ac79c3f039bfe9b924b6744f0 is not a symbolic ref`. So ok, the SHA-1 of a commit indeed is not a symbolic ref. Looks like that's the reason for the fatal - but that still doesn't explain why the dummy example, which looks the same, works. – alexakarpov Aug 07 '13 at 18:11

3 Answers3

6

Your "work" repo is probably broken somehow. See I can't git rebase --interactive anymore for details.

I'd try running git status in your work repo to figure out what is going on. Then e.g. git rebase --abort, git merge --abort or something like that may be required.

I'd run git fsck, too.

After your repo and working directory is good to go, interactive rebase should work fine. Also note that you may need git rebase --root --preserve-merges ... in case you want to touch the first commit in the repo.

Mikko Rantalainen
  • 14,132
  • 10
  • 74
  • 112
3

there is also a possibility that git commit was executed instead of git rebase --skip or git rebase --continue

this might have added the unwanted commit.

You may run git reset HEAD~1 and then execute git rebase --continue to fix the issue

Samdeesh
  • 905
  • 11
  • 23
0

I got this error while trying to push a tag while on detached head.

@❯ git push origin 1.1.1
fatal: ref HEAD is not a symbolic ref
error: failed to push some refs to '<repo>'

Detached head since the main branch was one commit ahead of the commit with the tag.

I was allowed to push the tag by temporarily resetting the main branch to commit that the tag was on:

@❯ git checkout develop
@❯ git reset --hard @~
@❯ git push origin 1.1.1
@❯ git reset --hard origin/develop
Guildenstern
  • 2,179
  • 1
  • 17
  • 39