public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Shawn Pearce <spearce@spearce•org>
To: Junio C Hamano <junkio@cox•net>
Cc: git@vger•kernel.org, Johannes Schindelin <Johannes.Schindelin@gmx•de>
Subject: Re: print errors from git-update-ref
Date: Fri, 28 Jul 2006 23:44:51 -0400	[thread overview]
Message-ID: <20060729034451.GB28128@spearce.org> (raw)
In-Reply-To: <7vejw6mbqj.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox•net> wrote:
> Shawn Pearce <spearce@spearce•org> writes:
> 
> > Johannes Schindelin <Johannes.Schindelin@gmx•de> wrote:
> >> Hi,
> >> 
> >> On Wed, 26 Jul 2006, Shawn Pearce wrote:
> >> 
> >> > This change adds a test for trying to create a ref within a directory
> >> > that is actually currently a file, and adds error printing within
> >> > the ref locking routine should the resolve operation fail.
> >> 
> >> Why not just print an error message when the resolve operation fails, 
> >> instead of special casing this obscure corner case? It is way shorter, 
> >> too. The test should stay, though.
> >
> > Did you read the patch?  If resolve_ref returns NULL then this
> > change prints an error (from errno) no matter what.  If errno is
> > ENOTDIR then it tries to figure out what part of the ref path wasn't
> > a directory (but was attempted to be used as such) and prints an
> > ENOTDIR error about that path instead of the one actually given
> > to the ref lock function
> >
> > So I think I'm doing what you are suggesting...
>
[snip]
> But the last step does not take into account what resolve_ref()
> does, doesn't it?  What if orig_path is "HEAD", which is a
> symref, which contained "ref: refs/heads/myhack/one" and
> "refs/heads/myhack" is a file?  Ideally you may want to say
> something like:
> 
>      '''while resolving %s, which points at %s,
>         we found out %s is not a directory''' %
>         ("HEAD", "refs/heads/myhack/one", "refs/heads/myhack")
> 
> So I tend to agree with Johannes's "why bother?" reaction.

OK, that's a bug.  It would be horribly misleading.  So I'm taking
the shortcut here and just telling the user ENOTDIR and orig_path
rather than resolving it and finding that bad directory component.

-->8--
Display an error from update-ref if target ref name is invalid.

Alex Riesen (raa.lkml@gmail•com) recently observed that git branch
would fail with no error message due to unexpected situations with
regards to refs.  For example, if .git/refs/heads/gu is a file but
`git branch -b refs/heads/gu/fixa HEAD` was invoked by the user
it would fail silently due to refs/heads/gu being a file and not
a directory.

This change adds a test for trying to create a ref within a directory
that is actually currently a file, and adds error printing within
the ref locking routine should the resolve operation fail.

The error printing code probably belongs at this level of the library
as other failures within the ref locking, writing and logging code
are also currently at this level of the code.

Signed-off-by: Shawn O. Pearce <spearce@spearce•org>
---
 refs.c                |    5 +++++
 t/t1400-update-ref.sh |   12 ++++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/refs.c b/refs.c
index 56db394..02850b6 100644
--- a/refs.c
+++ b/refs.c
@@ -294,6 +294,7 @@ static struct ref_lock *lock_ref_sha1_ba
 	int plen,
 	const unsigned char *old_sha1, int mustexist)
 {
+	const char *orig_path = path;
 	struct ref_lock *lock;
 	struct stat st;
 
@@ -303,7 +304,11 @@ static struct ref_lock *lock_ref_sha1_ba
 	plen = strlen(path) - plen;
 	path = resolve_ref(path, lock->old_sha1, mustexist);
 	if (!path) {
+		int last_errno = errno;
+		error("unable to resolve reference %s: %s",
+			orig_path, strerror(errno));
 		unlock_ref(lock);
+		errno = last_errno;
 		return NULL;
 	}
 	lock->lk = xcalloc(1, sizeof(struct lock_file));
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 04fab26..ddc80bb 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -14,6 +14,8 @@ D=44444444444444444444444444444444444444
 E=5555555555555555555555555555555555555555
 F=6666666666666666666666666666666666666666
 m=refs/heads/master
+n_dir=refs/heads/gu
+n=$n_dir/fixes
 
 test_expect_success \
 	"create $m" \
@@ -26,6 +28,16 @@ test_expect_success \
 rm -f .git/$m
 
 test_expect_success \
+	"fail to create $n" \
+	'touch .git/$n_dir
+	 git-update-ref $n $A >out 2>err
+	 test $? = 1 &&
+	 test "" = "$(cat out)" &&
+	 grep "error: unable to resolve reference" err &&
+	 grep $n err'
+rm -f .git/$n_dir out err
+
+test_expect_success \
 	"create $m (by HEAD)" \
 	'git-update-ref HEAD $A &&
 	 test $A = $(cat .git/$m)'
-- 
1.4.2.rc1.g802da

      reply	other threads:[~2006-07-29  3:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-18 13:13 print errors from git-update-ref Alex Riesen
2006-07-24  6:06 ` Junio C Hamano
2006-07-27  1:28   ` Shawn Pearce
2006-07-27 11:04     ` Johannes Schindelin
2006-07-28  6:27       ` Shawn Pearce
2006-07-28  7:26         ` Junio C Hamano
2006-07-29  3:44           ` Shawn Pearce [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060729034451.GB28128@spearce.org \
    --to=spearce@spearce$(echo .)org \
    --cc=Johannes.Schindelin@gmx$(echo .)de \
    --cc=git@vger$(echo .)kernel.org \
    --cc=junkio@cox$(echo .)net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox