threads / discuss / 20509

fatal: bad revision 'HEAD'

Subject: fatal: bad revision 'HEAD'

## tl;dr

11 messages between Aug 9, 2009 and Aug 13, 2009.

replies: 10people: 3as markdown or json

Joel Mahoney· Aug 9, 2009, 21:15 UTC · lore
Hello,

I am having trouble installing Ruby on Rails plugins from github. when I run e.g. script/install plugin git://github.com/thoughtbot/ paperclip.git I get:

 > Initialized empty Git repository in /path/to/my/project/vendor/ 
plugins/paperclip/.git/
 > fatal: bad revision 'HEAD'
 > refusing to pull with rebase: your working tree is not up-to-date

I don't have any problems with git in general, but this error happens every time I try to install from github - even when it's a brand new rails app.

the github support team tells me it looks like a git issue - any suggestions would be appreciated!

thanks, Joel

Jeff King· Aug 10, 2009, 01:18 UTC · re: Joel Mahoney · lore

Re: fatal: bad revision 'HEAD'

On Sun, Aug 09, 2009 at 03:15:46PM -0600, Joel Mahoney wrote:
Show 8 quoted lines
> I am having trouble installing Ruby on Rails plugins from github.
> when I run e.g. script/install plugin git://github.com/thoughtbot/
> paperclip.git I get:
> 
> > Initialized empty Git repository in /path/to/my/project/vendor/
> plugins/paperclip/.git/
> > fatal: bad revision 'HEAD'
> > refusing to pull with rebase: your working tree is not up-to-date

I can "git clone" that repository just fine. What is it exactly that installing a Rails plugin does with git? Can you try setting GIT_TRACE=1 in the environment and running your script to show us what git commands it is executing?

-Peff
Jeff King· Aug 12, 2009, 03:27 UTC · lore

Re: fatal: bad revision 'HEAD'

[re-adding git@vger, since this discussion really belongs on the list]
On Tue, Aug 11, 2009 at 10:30:49AM -0600, Joel Mahoney wrote:
Show 19 quoted lines
> here's what I get now:
> 
> trace: built-in: git 'init'
> Initialized empty Git repository in /path/to/project/vendor/plugins/
> paperclip/.git/
> trace: exec: 'git-pull' '--depth' '1' 'git://github.com/thoughtbot/
> paperclip.git'
> trace: built-in: git 'rev-parse' '--git-dir'
> trace: built-in: git 'rev-parse' '--is-inside-work-tree'
> trace: built-in: git 'rev-parse' '--show-cdup'
> trace: built-in: git 'ls-files' '-u'
> trace: built-in: git 'symbolic-ref' '-q' 'HEAD'
> trace: built-in: git 'config' '--bool' 'branch.master.rebase'
> trace: built-in: git 'update-index' '--ignore-submodules' '--refresh'
> trace: built-in: git 'diff-files' '--ignore-submodules' '--quiet'
> trace: built-in: git 'diff-index' '--ignore-submodules' '--cached'
> '--quiet' 'HEAD' '--'
> fatal: bad revision 'HEAD'
> refusing to pull with rebase: your working tree is not up-to-date

I was able to replicate your problem, but only if I set branch.master.rebase to "true" in my user-wide git config (i.e., ~/.gitconfig). It looks like "git pull" is not capable of handling a rebase when you have no commits yet.

I'm slightly dubious that such a configuration is sane, but probably "git pull" should handle this case anyway, as you can easily replicate it without config by doing:

  git init && git pull --rebase /any/git/repo
Patch is below.
-- >8 --
Subject: [PATCH] allow pull --rebase on branch yet to be born

When doing a "pull --rebase", we check to make sure that the index and working tree are clean. The index-clean check compares the index against HEAD. The test erroneously reports dirtiness if we don't have a HEAD yet.

In the case that we don't have a HEAD, we should just check if the index has anything in it, which we can do by comparing to the empty tree.

Signed-off-by: Jeff King <peff@peff.net>
---
Actually, this test is slightly more strict than the "index dirty" check
in git-rebase.sh itself. That test does "git diff-index HEAD", but
doesn't check the return code. It actually looks at whether it generates
output. So it would consider an index with something in it on a branch
yet-to-be-born to be clean, which is perhaps wrong.

Such a thing seems pretty unlikely in practice, though. I don't know if it is worth making the two tests the same (maybe it is worth refactoring into an index_is_clean function in git-sh-setup).

 git-pull.sh     |    8 +++++++-
 t/t5520-pull.sh |   11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/git-pull.sh b/git-pull.sh
index 0f24182..427b5c6 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -119,9 +119,15 @@ error_on_no_merge_candidates () {
 }
 
 test true = "$rebase" && {
+	if git rev-parse -q --verify HEAD >/dev/null; then
+		parent_tree=HEAD
+	else # empty tree
+		parent_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+	fi
+
 	git update-index --ignore-submodules --refresh &&
 	git diff-files --ignore-submodules --quiet &&
-	git diff-index --ignore-submodules --cached --quiet HEAD -- ||
+	git diff-index --ignore-submodules --cached --quiet $parent_tree -- ||
 	die "refusing to pull with rebase: your working tree is not up-to-date"
 
 	oldremoteref= &&
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index e78d402..dd2ee84 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -149,4 +149,15 @@ test_expect_success 'pull --rebase dies early with dirty working directory' '
 
 '
 
+test_expect_success 'pull --rebase works on branch yet to be born' '
+	git rev-parse master >expect &&
+	mkdir empty_repo &&
+	(cd empty_repo &&
+	 git init &&
+	 git pull --rebase .. master &&
+	 git rev-parse HEAD >../actual
+	) &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.6.4.228.g9ab2.dirty
Junio C Hamano· Aug 12, 2009, 07:37 UTC · re: Jeff King · lore

Re: fatal: bad revision 'HEAD'

Jeff King <peff@peff.net> writes:
> I was able to replicate your problem, but only if I set
> branch.master.rebase to "true" in my user-wide git config (i.e.,
> ~/.gitconfig). It looks like "git pull" is not capable of handling a
> rebase when you have no commits yet.

It does sound sick to store such a setting in $HOME/.gitconfig file, when the variable is clearly per-repository. As you wrote, you can easily trigger it with an explicit --rebase, but again, it is insane to ask "rebase" when you clearly do not have anything.

But just like we twisted the definition of merge to mean "merging something into nothing yields that something", we could twist the definition of rebase to mean "rebasing nothing on top of something result in that something". It sort of makes sense in a twisted way.

Show 19 quoted lines
> diff --git a/git-pull.sh b/git-pull.sh
> index 0f24182..427b5c6 100755
> --- a/git-pull.sh
> +++ b/git-pull.sh
> @@ -119,9 +119,15 @@ error_on_no_merge_candidates () {
>  }
>  
>  test true = "$rebase" && {
> +	if git rev-parse -q --verify HEAD >/dev/null; then
> +		parent_tree=HEAD
> +	else # empty tree
> +		parent_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
> +	fi
> +
>  	git update-index --ignore-submodules --refresh &&
>  	git diff-files --ignore-submodules --quiet &&
> -	git diff-index --ignore-submodules --cached --quiet HEAD -- ||
> +	git diff-index --ignore-submodules --cached --quiet $parent_tree -- ||
>  	die "refusing to pull with rebase: your working tree is not up-to-date"
Two comments.
 * Is "rev-parse -q --verify" a safe test to guarantee that HEAD is
   unborn?  Shouldn't we be checking with "symbolic-ref" or something?
 * In such an "unborn branch" case, by definition, a non-empty index won't
   be based on whatever we are pulling down from the remote.  So how about
   doing something like the following instead?
	if on unborn branch
	then
		if test -f "$GIT_DIR/index"
                then
			die "refusing to update; you have a non-empty index"
		fi
	else
		... existing tests against HEAD ...
	fi
Jeff King· Aug 12, 2009, 07:58 UTC · re: Junio C Hamano · lore

Re: fatal: bad revision 'HEAD'

On Wed, Aug 12, 2009 at 12:37:44AM -0700, Junio C Hamano wrote:
> But just like we twisted the definition of merge to mean "merging
> something into nothing yields that something", we could twist the
> definition of rebase to mean "rebasing nothing on top of something result
> in that something".  It sort of makes sense in a twisted way.
I dunno. It doesn't seem all that twisted to me.

But like many of the "branch to be born" and "initial commit" edge cases we have dealt with, it is not so much about somebody intentionally triggering this as it is about doing something sane when some script _does_ trigger it. And I think the sane thing is obvious and easy to do here, so why not?

>  * Is "rev-parse -q --verify" a safe test to guarantee that HEAD is
>    unborn?  Shouldn't we be checking with "symbolic-ref" or something?

I'm not sure. The test in git-checkout, for example, seems to basically just be looking up HEAD as a commit. If it doesn't work, then the branch is to-be-born (see switch_branches in builtin-checkout.c).

Which is more or less what's happening here (except we don't check that the type is a commit).

With symbolic-ref, I guess we could find out what the ref is, and check to see if _that_ exists. But I can't think of a situation where that would be meaningfully different than just resolving HEAD. Obviously detached HEADs come to mind, but wouldn't you then by definition not be a branch-to-be-born, which is what this rev-parse test would tell you?

Show 13 quoted lines
>  * In such an "unborn branch" case, by definition, a non-empty index won't
>    be based on whatever we are pulling down from the remote.  So how about
>    doing something like the following instead?
> 
> 	if on unborn branch
> 	then
> 		if test -f "$GIT_DIR/index"
>                 then
> 			die "refusing to update; you have a non-empty index"
> 		fi
> 	else
> 		... existing tests against HEAD ...
> 	fi

Yeah, I think that is a better idea. Do you want to tweak the patch, or should I re-submit?

-Peff
Junio C Hamano· Aug 12, 2009, 22:49 UTC · re: Jeff King · lore

Re: fatal: bad revision 'HEAD'

Jeff King <peff@peff.net> writes:
> Yeah, I think that is a better idea. Do you want to tweak the patch, or
> should I re-submit?
I'll do this then.
-- >8 --
From: Jeff King <peff@peff.net>
Date: Tue, 11 Aug 2009 23:27:40 -0400
Subject: [PATCH] Subject: [PATCH] allow pull --rebase on branch yet to be born

When doing a "pull --rebase", we check to make sure that the index and working tree are clean. The index-clean check compares the index against HEAD. The test erroneously reports dirtiness if we don't have a HEAD yet.

In such an "unborn branch" case, by definition, a non-empty index won't be based on whatever we are pulling down from the remote, and will lose the local change. Just check if $GIT_DIR/index exists and error out.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-pull.sh     |   18 +++++++++++++-----
 t/t5520-pull.sh |   11 +++++++++++
 2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/git-pull.sh b/git-pull.sh
index 0f24182..0bbd5bf 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -119,11 +119,19 @@ error_on_no_merge_candidates () {
 }
 
 test true = "$rebase" && {
-	git update-index --ignore-submodules --refresh &&
-	git diff-files --ignore-submodules --quiet &&
-	git diff-index --ignore-submodules --cached --quiet HEAD -- ||
-	die "refusing to pull with rebase: your working tree is not up-to-date"
-
+	if ! git rev-parse -q --verify HEAD >/dev/null
+	then
+		# On an unborn branch
+		if test -f "$GIT_DIR/index"
+		then
+			die "updating an unborn branch with changes added to the index"
+		fi
+	else
+		git update-index --ignore-submodules --refresh &&
+		git diff-files --ignore-submodules --quiet &&
+		git diff-index --ignore-submodules --cached --quiet HEAD -- ||
+		die "refusing to pull with rebase: your working tree is not up-to-date"
+	fi
 	oldremoteref= &&
 	. git-parse-remote &&
 	remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index e78d402..dd2ee84 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -149,4 +149,15 @@ test_expect_success 'pull --rebase dies early with dirty working directory' '
 
 '
 
+test_expect_success 'pull --rebase works on branch yet to be born' '
+	git rev-parse master >expect &&
+	mkdir empty_repo &&
+	(cd empty_repo &&
+	 git init &&
+	 git pull --rebase .. master &&
+	 git rev-parse HEAD >../actual
+	) &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.6.4.196.gd1fd8
Jeff King· Aug 13, 2009, 02:31 UTC · re: Junio C Hamano · lore

Re: fatal: bad revision 'HEAD'

On Wed, Aug 12, 2009 at 03:49:56PM -0700, Junio C Hamano wrote:
Show 10 quoted lines
> When doing a "pull --rebase", we check to make sure that the index and
> working tree are clean. The index-clean check compares the index against
> HEAD. The test erroneously reports dirtiness if we don't have a HEAD yet.
> 
> In such an "unborn branch" case, by definition, a non-empty index won't
> be based on whatever we are pulling down from the remote, and will lose
> the local change.  Just check if $GIT_DIR/index exists and error out.
> 
> Signed-off-by: Jeff King <peff@peff.net>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Looks sane to me, but see below.
Show 5 quoted lines
> +		# On an unborn branch
> +		if test -f "$GIT_DIR/index"
> +		then
> +			die "updating an unborn branch with changes added to the index"
> +		fi

I had a brief moment where I thought this might not actually be sufficient. That is, can somebody create an unborn branch in an existing repo (e.g., because they want an alternate project root) in such a way that they have an index, but it is empty? In which case we should be actually checking for index emptiness instead of existence.

I.e., I have done in the past (but not frequently):
  git symbolic-ref HEAD refs/heads/to-be-born

in an existing repository to create a new root. But I don't think we really need to worry about that case:

  1. It is somewhat crazy and rare in the first place. Even more crazy
     and rare would be to "git pull --rebase" immediately afterwards.
  2. If you _did_ have an index, either:
     2a. You want to keep it, in which case your check is sane.
     2b. You want to start fresh, in which case your next step would be
         be "rm -f .git/index".
The only way this check would not be OK is is if you did something like:
  git symbolic-ref HEAD refs/heads/new-branch
  git ls-files | xargs git rm --cached
  git pull --rebase ...
which just seems crazy.

So I think I have convinced myself that what you have is fine, but I just wanted a sanity check.

-Peff
Junio C Hamano· Aug 13, 2009, 04:36 UTC · re: Jeff King · lore

Re: fatal: bad revision 'HEAD'

Jeff King <peff@peff.net> writes:
Show 5 quoted lines
> I.e., I have done in the past (but not frequently):
>
>   git symbolic-ref HEAD refs/heads/to-be-born
>
> in an existing repository to create a new root.

I honestly do not know of a sane reason (other than "because I can") anybody would want to _start_ a new root in a repository with an existing history. And doing a "pull" with or without --rebase immediately after starting a new root is doubly insane, as you say.

I do not think _ending up to_ have more than one root in your repository is necessarily insane. You may find a related project that earlier started independently but later turned out to be better off managed together with your project, and at that point you may perform Linus's "coolest merge ever" to bind the two histories together, resulting in a history with more than one root.

But that is the kind of "ending up to have" I am talking about; it is not something you _aim to_ create on purpose. If you want to _start_ a separate history, and if you are sane, you would start the separate history in a separate repository.

Jeff King· Aug 13, 2009, 04:38 UTC · re: Junio C Hamano · lore

Re: fatal: bad revision 'HEAD'

On Wed, Aug 12, 2009 at 09:36:04PM -0700, Junio C Hamano wrote:
> I honestly do not know of a sane reason (other than "because I can")
> anybody would want to _start_ a new root in a repository with an existing
> history.  And doing a "pull" with or without --rebase immediately after
> starting a new root is doubly insane, as you say.

IIRC, the reason I did it was to throw away history, starting a new root at the current state. Which is at least a little bit sane, though I think I might just do it with a graft and filter-branch these days.

> But that is the kind of "ending up to have" I am talking about; it is not
> something you _aim to_ create on purpose.  If you want to _start_ a
> separate history, and if you are sane, you would start the separate
> history in a separate repository.
Agreed. Let's not worry about it, then.
-Peff
Joel Mahoney· Aug 13, 2009, 05:02 UTC · re: Jeff King · lore

Re: fatal: bad revision 'HEAD'

Hello,

I'm not sure I completely understand where you guys are at with this thread : - ) but I thought I would mention that the question arose from my inability to install a plugin into a Ruby on Rails project based on my having (unknowingly) set branch.master.rebase = true.

I bring this up because a lot of people are getting their first exposure to git through Rails/github, and installing plugins in Rails is (I think) a good example of brining an existing history (the plugin) into a separate repository (your project). and because this maneuver is built into the "./script/plugin install" action, it is not something that cannot be easily customized.

again, I may be a little off track here, but I thought I would remind you of the original context for what that is worth : - )

thanks again for your help!
Joel
On Aug 12, 2009, at 10:38 PM, Jeff King wrote:
Show 23 quoted lines
> On Wed, Aug 12, 2009 at 09:36:04PM -0700, Junio C Hamano wrote:
>
>> I honestly do not know of a sane reason (other than "because I can")
>> anybody would want to _start_ a new root in a repository with an  
>> existing
>> history.  And doing a "pull" with or without --rebase immediately  
>> after
>> starting a new root is doubly insane, as you say.
>
> IIRC, the reason I did it was to throw away history, starting a new  
> root
> at the current state. Which is at least a little bit sane, though I
> think I might just do it with a graft and filter-branch these days.
>
>> But that is the kind of "ending up to have" I am talking about; it  
>> is not
>> something you _aim to_ create on purpose.  If you want to _start_ a
>> separate history, and if you are sane, you would start the separate
>> history in a separate repository.
>
> Agreed. Let's not worry about it, then.
>
> -Peff
Jeff King· Aug 13, 2009, 05:10 UTC · re: Joel Mahoney · lore

Re: fatal: bad revision 'HEAD'

On Wed, Aug 12, 2009 at 11:02:45PM -0600, Joel Mahoney wrote:
Show 11 quoted lines
> I'm not sure I completely understand where you guys are at with this
> thread : - ) but I thought I would mention that the question arose
> from my inability to install a plugin into a Ruby on Rails project
> based on my having (unknowingly) set branch.master.rebase = true.
>
> I bring this up because a lot of people are getting their first
> exposure to git through Rails/github, and installing plugins in Rails
> is (I think) a good example of brining an existing history (the
> plugin) into a separate repository (your project).  and because this
> maneuver is built into the "./script/plugin install" action, it is
> not something that cannot be easily customized.

Yes, the discussion moved away bit from your original issue. To summarize what is happening:

  - Setting branch.master.rebase in your ~/.gitconfig is probably not a
    good idea, as that tends to be a per-repository property, anyway.
    You can work around the problem for now by removing it.
  - Junio has committed a patch to fix the bug. It will definitely be in
    v1.6.5. If this is a common setup for Rails people, maybe we should
    consider putting it into 'maint' for v1.6.4.1.
-Peff

← back to recent threads