{"thread":{"id":"12412","subject":"Some issues working with empty/bare repositories...","startedAt":"2008-03-01T19:40:39Z","lastAt":"2008-03-05T09:25:56Z","messageCount":9,"participants":["Reece Dunn","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"70548","messageId":"3f4fd2640803011140o38ba0830l7775c8528f812779@mail.gmail.com","threadId":"12412","inReplyTo":null,"subject":"Some issues working with empty/bare repositories...","fromName":"Reece Dunn","fromEmail":"msclrhd@googlemail.com","sentAt":"2008-03-01T19:40:39Z","receivedAt":"2008-03-01T19:40:39Z","isPatch":false,"sender":{"key":"msclrhd@googlemail.com","avatar":null},"body":"Hi,\n\nSome git operations -- only tried clone and log -- require a\nrepository to contain at least one commit.\n\n    $ git --version\n    git version 1.5.3.1\n\nWhile this is fine when working with existing projects, it can be\nconfusing/problematic when setting up a new repository.\n\nConsider the following workflow:\n\n    $ mkdir foo\n    $ cd foo\n    $ git --bare init\n\n    $ git log\n    fatal: bad default revision 'HEAD'\n\nThis message is confusing for a newbie. Displaying \"no commits\" would\nmake more sense here.\n\n    $ cat HEAD\n    ref: refs/heads/master\n    $ find refs/heads/master\n    find: refs/heads/master: No such file or directory\n\nIf the user wants to use the bare repository as the main location of\nthe project, but make changes to it elsewhere (e.g. when setting up a\nsuperproject for adding submodules to), they might want to do\nsomething like:\n\n    $ git clone foo bar\n    Initialized empty Git repository in /home/reece/bar/.git/\n    $ ls -a /home/reece\n    . .. foo\n\nIt appears from the git output (with the inconsistently capitalized\ngit - see --version output above) that the clone succeeded, but it\ndoes not create bar/.git/, even though it said that it did.\n\n- Reece\n"},{"id":"70762","messageId":"20080303081021.GA6578@sigill.intra.peff.net","threadId":"12412","inReplyTo":"3f4fd2640803011140o38ba0830l7775c8528f812779@mail.gmail.com","subject":"Re: Some issues working with empty/bare repositories...","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-03T08:10:21Z","receivedAt":"2008-03-03T08:10:21Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Mar 01, 2008 at 07:40:39PM +0000, Reece Dunn wrote:\n\n> Consider the following workflow:\n> \n>     $ mkdir foo\n>     $ cd foo\n>     $ git --bare init\n> \n>     $ git log\n>     fatal: bad default revision 'HEAD'\n> \n> This message is confusing for a newbie. Displaying \"no commits\" would\n> make more sense here.\n\nThe tricky thing here is that \"git log\" doesn't know we have no\ncommits in the repo; it only knows that HEAD is bogus. But it may be\nthat we can just say something like:\n\n  fatal: unable to resolve HEAD; do you have any commits?\n\n>     $ git clone foo bar\n>     Initialized empty Git repository in /home/reece/bar/.git/\n>     $ ls -a /home/reece\n>     . .. foo\n\nAs of 1.5.4, this now says \"fatal: cannot clone empty repository\". There\nhas been work recently on a C version of clone which tries to match the\nsequence of \"init && remote add && fetch && checkout\" more closely. I\nhaven't looked closely, but I suspect it may just work (by which I mean\ncreate an empty repo with origin config pointing to the parent repo).\n\n> It appears from the git output (with the inconsistently capitalized\n> git - see --version output above) that the clone succeeded, but it\n> does not create bar/.git/, even though it said that it did.\n\nIt did create it...it just deleted it afterwards without telling you. :)\n\n-Peff\n"},{"id":"70999","messageId":"3f4fd2640803041351k6debe788xbf5e818951f70146@mail.gmail.com","threadId":"12412","inReplyTo":"20080303081021.GA6578@sigill.intra.peff.net","subject":"Re: Some issues working with empty/bare repositories...","fromName":"Reece Dunn","fromEmail":"msclrhd@googlemail.com","sentAt":"2008-03-04T21:51:02Z","receivedAt":"2008-03-04T21:51:02Z","isPatch":false,"sender":{"key":"msclrhd@googlemail.com","avatar":null},"body":"On 03/03/2008, Jeff King <peff@peff.net> wrote:\n> On Sat, Mar 01, 2008 at 07:40:39PM +0000, Reece Dunn wrote:\n>\n>  > Consider the following workflow:\n>  >\n>  >     $ mkdir foo\n>  >     $ cd foo\n>  >     $ git --bare init\n>  >\n>  >     $ git log\n>  >     fatal: bad default revision 'HEAD'\n>  >\n>  > This message is confusing for a newbie. Displaying \"no commits\" would\n>  > make more sense here.\n>\n> The tricky thing here is that \"git log\" doesn't know we have no\n>  commits in the repo; it only knows that HEAD is bogus. But it may be\n>  that we can just say something like:\n>\n>   fatal: unable to resolve HEAD; do you have any commits?\n\nThat would be better. The current message would indicate something\nlike a corrupt repository (or at least the metadata to the\nrepository).\n\n>  >     $ git clone foo bar\n>  >     Initialized empty Git repository in /home/reece/bar/.git/\n>  >     $ ls -a /home/reece\n>  >     . .. foo\n>\n> As of 1.5.4, this now says \"fatal: cannot clone empty repository\". There\n>  has been work recently on a C version of clone which tries to match the\n>  sequence of \"init && remote add && fetch && checkout\" more closely. I\n>  haven't looked closely, but I suspect it may just work (by which I mean\n>  create an empty repo with origin config pointing to the parent repo).\n\nI have verified that behaviour with 1.5.4. Having an empty repository\n(possibly with a warning issued about cloning an empty repository)\nwith the origin pointing to the parent repository is what I would\nexpect to happen.\n\n>  > It appears from the git output (with the inconsistently capitalized\n>  > git - see --version output above) that the clone succeeded, but it\n>  > does not create bar/.git/, even though it said that it did.\n>\n> It did create it...it just deleted it afterwards without telling you. :)\n\n:)\n\nThanks,\n- Reece\n"},{"id":"71019","messageId":"20080305010701.GB20007@sigill.intra.peff.net","threadId":"12412","inReplyTo":"3f4fd2640803041351k6debe788xbf5e818951f70146@mail.gmail.com","subject":"[RFC] improve 'bad default revision' message for empty repo","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-05T01:07:02Z","receivedAt":"2008-03-05T01:07:02Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 04, 2008 at 09:51:02PM +0000, Reece Dunn wrote:\n\n> >  > Consider the following workflow:\n> >  >\n> >  >     $ mkdir foo\n> >  >     $ cd foo\n> >  >     $ git --bare init\n> >  >\n> >  >     $ git log\n> >  >     fatal: bad default revision 'HEAD'\n> >  >\n> >  > This message is confusing for a newbie. Displaying \"no commits\" would\n> >  > make more sense here.\n\nWhat do people think of this patch? It feels a little hack-ish to make\nguesses as to the reasons for a failure, but in my experience an empty\nrepo is the cause of this message in 99% of cases.\n\nWe could special-case it to HEAD and make a better message, perhaps, but\nthat feels even more hack-ish.\n\n---\n revision.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 63bf2c5..847dbc8 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1324,7 +1324,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\tstruct object *object;\n \t\tunsigned mode;\n \t\tif (get_sha1_with_mode(def, sha1, &mode))\n-\t\t\tdie(\"bad default revision '%s'\", def);\n+\t\t\tdie(\"unable to resolve '%s'; do you have any commits on this branch?\", def);\n \t\tobject = get_reference(revs, def, sha1, 0);\n \t\tadd_pending_object_with_mode(revs, object, def, mode);\n \t}\n-- \n1.5.4.3.531.ga940.dirty\n"},{"id":"71022","messageId":"7v7igh51rm.fsf@gitster.siamese.dyndns.org","threadId":"12412","inReplyTo":"20080305010701.GB20007@sigill.intra.peff.net","subject":"Re: [RFC] improve 'bad default revision' message for empty repo","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-05T02:43:25Z","receivedAt":"2008-03-05T02:43:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Tue, Mar 04, 2008 at 09:51:02PM +0000, Reece Dunn wrote:\n>\n>> >  > Consider the following workflow:\n>> >  >\n>> >  >     $ mkdir foo\n>> >  >     $ cd foo\n>> >  >     $ git --bare init\n>> >  >\n>> >  >     $ git log\n>> >  >     fatal: bad default revision 'HEAD'\n>> >  >\n>> >  > This message is confusing for a newbie. Displaying \"no commits\" would\n>> >  > make more sense here.\n>\n> What do people think of this patch? It feels a little hack-ish to make\n> guesses as to the reasons for a failure, but in my experience an empty\n> repo is the cause of this message in 99% of cases.\n\n>\n> We could special-case it to HEAD and make a better message, perhaps, but\n> that feels even more hack-ish.\n\nHow about doing it this way instead, then?\n\nSaying \"fatal: You haven't made a commit?\" is like saying \"How stupid do\nyou have to be to realize that you are not allowed to run git-log before\nmaking a commit, dummy?\", but that is not the message we need to be\nsending.  Asking for log is fine.  If you are on an unborn branch and say\n\"git log\", you deserve to get nothing.  Not even an error message.\n\nNot that I haven't thought through the ramifications of this yet; some\ncallers may need to be adjusted, but they should be prepared for a case\nwhere no rev was given from the command line anyway.\n\n---\n\n revision.c |    8 ++++----\n 1 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 63bf2c5..cdd5ad2 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1323,10 +1323,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\tunsigned char sha1[20];\n \t\tstruct object *object;\n \t\tunsigned mode;\n-\t\tif (get_sha1_with_mode(def, sha1, &mode))\n-\t\t\tdie(\"bad default revision '%s'\", def);\n-\t\tobject = get_reference(revs, def, sha1, 0);\n-\t\tadd_pending_object_with_mode(revs, object, def, mode);\n+\t\tif (!get_sha1_with_mode(def, sha1, &mode)) {\n+\t\t\tobject = get_reference(revs, def, sha1, 0);\n+\t\t\tadd_pending_object_with_mode(revs, object, def, mode);\n+\t\t}\n \t}\n \n \t/* Did the user ask for any diff output? Run the diff! */\n"},{"id":"71023","messageId":"20080305043319.GA9074@sigill.intra.peff.net","threadId":"12412","inReplyTo":"7v7igh51rm.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC] improve 'bad default revision' message for empty repo","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-05T04:33:19Z","receivedAt":"2008-03-05T04:33:19Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 04, 2008 at 06:43:25PM -0800, Junio C Hamano wrote:\n\n> Saying \"fatal: You haven't made a commit?\" is like saying \"How stupid do\n> you have to be to realize that you are not allowed to run git-log before\n> making a commit, dummy?\", but that is not the message we need to be\n> sending.  Asking for log is fine.  If you are on an unborn branch and say\n> \"git log\", you deserve to get nothing.  Not even an error message.\n\nI like that behavior much better, but...\n\n> diff --git a/revision.c b/revision.c\n> index 63bf2c5..cdd5ad2 100644\n> --- a/revision.c\n> +++ b/revision.c\n> @@ -1323,10 +1323,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n>  \t\tunsigned char sha1[20];\n>  \t\tstruct object *object;\n>  \t\tunsigned mode;\n> -\t\tif (get_sha1_with_mode(def, sha1, &mode))\n> -\t\t\tdie(\"bad default revision '%s'\", def);\n> -\t\tobject = get_reference(revs, def, sha1, 0);\n> -\t\tadd_pending_object_with_mode(revs, object, def, mode);\n> +\t\tif (!get_sha1_with_mode(def, sha1, &mode)) {\n> +\t\t\tobject = get_reference(revs, def, sha1, 0);\n> +\t\t\tadd_pending_object_with_mode(revs, object, def, mode);\n> +\t\t}\n>  \t}\n>  \n\nI'm not sure it's this easy. We're basically just ignoring the error\nreturn from get_sha1_with_mode, but do we really want to ignore _all_\nerrors? Specifically, should \"git log --default foobar\" silently produce\nno commits?\n\nI think a tighter rule that would accomplish the same thing is \"if we\nresolve to a ref that is yet-to-be-born, then ignore.\" But unfortunately\nthat information is lost deep within the bowels of get_sha1_with_mode.\n\nBut maybe this is good enough. It is, after all, just the \"default\" so\nperhaps it makes sense to treat all errors as soft errors. And it will\nalmost always be HEAD, I think. The only script which seems to use\n--default is git-svn. I'm not clear on why you would want to use\n--default rather than simply specifying the refs you want.\n\n-Peff\n"},{"id":"71053","messageId":"7vwsoho8t4.fsf@gitster.siamese.dyndns.org","threadId":"12412","inReplyTo":"20080305043319.GA9074@sigill.intra.peff.net","subject":"Re: [RFC] improve 'bad default revision' message for empty repo","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-05T08:48:39Z","receivedAt":"2008-03-05T08:48:39Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I'm not sure it's this easy. We're basically just ignoring the error\n> return from get_sha1_with_mode, but do we really want to ignore _all_\n> errors? Specifically, should \"git log --default foobar\" silently produce\n> no commits?\n\nSure.\n\nThe thing is, nobody uses \"--default\" with random crap (i.e. risk of typo\nrunning from the command line).  It is really about scripted use, and I can\nguarantee majority of --default argument is HEAD, and in people's custom\nscripts that are specially tailored for specific workflows, they would\nuse concrete commit object names that their workflow is built around as\nconvention (e.g. \"alias.recent = git log --since=1.day --default master\").\n\nWe could enhance the --default mechanism to say that its argument is\noptional when it begins with a '?', and change our internal callers to\npass the equivalent of \"--default ?HEAD\", and keep the traditional die()\nbehaviour for non-optional defaults to catch breakages in end-user\nscripts.\n\n> I think a tighter rule that would accomplish the same thing is \"if we\n> resolve to a ref that is yet-to-be-born, then ignore.\" But unfortunately\n> that information is lost deep within the bowels of get_sha1_with_mode.\n\nYes and no.  It is in the error path, so you can afford to redo resolving\nthe symref _after_ seeing get_sha1_with_mode() fail.  \n"},{"id":"71055","messageId":"20080305091051.GA18377@sigill.intra.peff.net","threadId":"12412","inReplyTo":"7vwsoho8t4.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC] improve 'bad default revision' message for empty repo","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-05T09:10:52Z","receivedAt":"2008-03-05T09:10:52Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 05, 2008 at 12:48:39AM -0800, Junio C Hamano wrote:\n\n> The thing is, nobody uses \"--default\" with random crap (i.e. risk of typo\n> running from the command line).  It is really about scripted use, and I can\n> guarantee majority of --default argument is HEAD, and in people's custom\n> scripts that are specially tailored for specific workflows, they would\n> use concrete commit object names that their workflow is built around as\n> convention (e.g. \"alias.recent = git log --since=1.day --default master\").\n\nWell, if you are comfortable, then I have no real objection. I just\nwanted to raise the point since I didn't really know how widely and in\nwhat way --default was being used.\n\n> We could enhance the --default mechanism to say that its argument is\n> optional when it begins with a '?', and change our internal callers to\n> pass the equivalent of \"--default ?HEAD\", and keep the traditional die()\n> behaviour for non-optional defaults to catch breakages in end-user\n> scripts.\n\nSure, that is reasonable. The syntax is a bit ugly. Maybe just set an\nignore_default_errors flag to '1', and then if --default is specified on\nthe commandline, set it to '0'. The behavior should be identical for all\nexternal scripts, and we can audit the internal uses.\n\nBut given your 'master' example above, I think you would actually want\nit to be treated in the same way; if master doesn't exist, it is empty.\nIOW, it is the \"defaultness\" which makes one want to ignore errors.\n\n> > I think a tighter rule that would accomplish the same thing is \"if we\n> > resolve to a ref that is yet-to-be-born, then ignore.\" But unfortunately\n> > that information is lost deep within the bowels of get_sha1_with_mode.\n> \n> Yes and no.  It is in the error path, so you can afford to redo resolving\n> the symref _after_ seeing get_sha1_with_mode() fail.\n\nTrue. Although considering your 'master' example above, it is not just\n\"symref whose target doesn't exist\", but \"ref does not exist\". In either\ncase (internal HEAD or explicit --default) I think something like \"ref\nexists but is corrupted\" is something you would expect git to note.\n\nHrm. Thinking about it a bit more, what should be done with a --default\nlike \"HEAD^^\"? It currently works fine, but parsing it down to \"HEAD\"\nrequires the magic of get_sha1_with_mode. I think anyone using anything\nbut an unadorned refname for --default is probably insane, though. Would\nit be acceptable to formally disallow it?\n\n-Peff\n"},{"id":"71060","messageId":"20080305092555.GA18591@sigill.intra.peff.net","threadId":"12412","inReplyTo":"20080305091051.GA18377@sigill.intra.peff.net","subject":"Re: [RFC] improve 'bad default revision' message for empty repo","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-05T09:25:56Z","receivedAt":"2008-03-05T09:25:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 05, 2008 at 04:10:51AM -0500, Jeff King wrote:\n\n> Hrm. Thinking about it a bit more, what should be done with a --default\n> like \"HEAD^^\"? It currently works fine, but parsing it down to \"HEAD\"\n> requires the magic of get_sha1_with_mode. I think anyone using anything\n> but an unadorned refname for --default is probably insane, though. Would\n> it be acceptable to formally disallow it?\n\nHrm. Even if we took this down to the level of resolve_ref(), there\nstill is no distinction being made between \"does not exist\" and other\nerrors. So restricting what is allowed in --default doesn't solve\nanything anyway (though it does make the call stack much smaller, which\nmakes a modifiction to pass an error/not-found condition back a less\npainful change).\n\nBut given that no distinction is made currently for something like \"git\nshow foobar\" between \"you don't have foobar\" and \"foobar is somehow\ncorrupt\", I am inclined to just say \"any errors in default lookup are\nignored.\"\n\n-Peff\n"}]}