Re: [PATCH] Replace perl code with pure shell code

Subsystems: the rest

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] Replace perl code with pure shell code

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:51

Simon 'corecode' Schubert [off-list ref] writes:
quoted hunk
Signed-off-by: Simon 'corecode' Schubert <redacted>
...
diff --git a/git-clone.sh b/git-clone.sh
index ced7dfb..b3c6fa4 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -66,48 +66,6 @@ Perhaps git-update-server-info needs to be run there?"
...
-open FH, "<", "$git_dir/CLONE_HEAD";
-while (<FH>) {
-	my ($sha1, $name) = /^([0-9a-f]{40})\s(.*)$/;
-	next if ($name =~ /\^\173/);
-	if ($name eq "HEAD") {
...
Thanks.  I like the general direction, but not quite.

You exposed one outstanding bug, which is a hint about what is
not quite right with your patch.

-- >8 --
[PATCH] update-ref: do not accept malformatted refs.

We used to use lock_any_ref_for_update() because the command
needs to also update HEAD (which is not under refs/, so
lock_ref_sha1() cannot be used).  The function however did not
check for refs with illegal characters in them.

Use check_ref_format() to catch malformed refs.  For this check,
we specifically do not want to say having less than two levels
in the name is illegal to allow HEAD (and perhaps other special
refs in the future).

Signed-off-by: Junio C Hamano <redacted>
---
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index 1461937..5ee960b 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -61,10 +61,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 
 	lock = lock_any_ref_for_update(refname, oldval ? oldsha1 : NULL);
 	if (!lock)
-		return 1;
+		die("%s: cannot lock the ref", refname);
 	if (write_ref_sha1(lock, sha1, msg) < 0)
-		return 1;
-
-	/* write_ref_sha1 always unlocks the ref, no need to do it explicitly */
+		die("%s: cannot update the ref", refname);
 	return 0;
 }
diff --git a/refs.c b/refs.c
index 12e46b8..3db444c 100644
--- a/refs.c
+++ b/refs.c
@@ -710,6 +710,8 @@ struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1)
 
 struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1)
 {
+	if (check_ref_format(ref) == -1)
+		return NULL;
 	return lock_ref_sha1_basic(ref, old_sha1, NULL);
 }
 

[PATCH] Replace perl code with pure shell code

From: Simon 'corecode' Schubert <hidden>
Date: 2016-06-15 22:42:51

Signed-off-by: Simon 'corecode' Schubert <redacted>
---
quoted
-	next if ($name =~ /\^\173/);
-	if ($name eq "HEAD") {
...
Thanks.  I like the general direction, but not quite.

You exposed one outstanding bug, which is a hint about what is
not quite right with your patch.
I already wondered.  What's those ^{} tags, and why is CLONE_HEAD littered with them?

 git-clone.sh |   67 ++++++++++++++++++++--------------------------------------
 1 files changed, 23 insertions(+), 44 deletions(-)
diff --git a/git-clone.sh b/git-clone.sh
index ced7dfb..869caf9 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -66,48 +66,6 @@ Perhaps git-update-server-info needs to be run there?"
 	rm -f "$GIT_DIR/REMOTE_HEAD"
 }
 
-# Read git-fetch-pack -k output and store the remote branches.
-copy_refs='
-use File::Path qw(mkpath);
-use File::Basename qw(dirname);
-my $git_dir = $ARGV[0];
-my $use_separate_remote = $ARGV[1];
-my $origin = $ARGV[2];
-
-my $branch_top = ($use_separate_remote ? "remotes/$origin" : "heads");
-my $tag_top = "tags";
-
-sub store {
-	my ($sha1, $name, $top) = @_;
-	$name = "$git_dir/refs/$top/$name";
-	mkpath(dirname($name));
-	open O, ">", "$name";
-	print O "$sha1\n";
-	close O;
-}
-
-open FH, "<", "$git_dir/CLONE_HEAD";
-while (<FH>) {
-	my ($sha1, $name) = /^([0-9a-f]{40})\s(.*)$/;
-	next if ($name =~ /\^\173/);
-	if ($name eq "HEAD") {
-		open O, ">", "$git_dir/REMOTE_HEAD";
-		print O "$sha1\n";
-		close O;
-		next;
-	}
-	if ($name =~ s/^refs\/heads\///) {
-		store($sha1, $name, $branch_top);
-		next;
-	}
-	if ($name =~ s/^refs\/tags\///) {
-		store($sha1, $name, $tag_top);
-		next;
-	}
-}
-close FH;
-'
-
 quiet=
 local=no
 use_local=no
@@ -332,8 +290,29 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
 if test -f "$GIT_DIR/CLONE_HEAD"
 then
 	# Read git-fetch-pack -k output and store the remote branches.
-	@@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" ||
-	exit
+	if [ -n "$use_separate_remote" ]
+	then
+		branch_top="remotes/$origin"
+	else
+		branch_top="heads"
+	fi
+	tag_top="tags"
+	while read sha1 name
+	do
+		case "$name" in
+		*^{*)
+			continue ;;
+		HEAD)
+			destname="REMOTE_HEAD" ;;
+		refs/heads/*)
+			destname="refs/$branch_top/${name#refs/heads/}" ;;
+		refs/tags/*)
+			destname="refs/$tag_top/${name#refs/tags/}" ;;
+		*)
+			continue ;;
+		esac
+		git-update-ref -m "clone: from $repo" "$destname" "$sha1" ""
+	done < "$GIT_DIR/CLONE_HEAD"
 fi
 
 cd "$D" || exit
-- 
1.5.0.rc1.196.geebfb

Re: [PATCH] Replace perl code with pure shell code

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:42:51

Simon 'corecode' Schubert [off-list ref] wrote:
I already wondered.  What's those ^{} tags, and why is CLONE_HEAD littered 
with them?
They are the deref of the thing without them.

As in, "foo" is a tag pointing at some object (probably a commit
but not necessarily) then "foo^{}" is whatever "foo"'s tag points at.
 
+		case "$name" in
+		*^{*)
+			continue ;;
Probably could just be:

		case "$name" in
		*^{})
			continue ;;

This is common in Git.  ^{} on the end of a ref name shows up in
the peek-remote/ls-remote output, but certainly is *not* a ref.

Sorry I missed that case eariler when I reviewed the patch. I thought
about it and why it wasn't handled here, but then thought maybe it
wasn't actually occuring in the input (that someone else higher up
had filtered them out).

-- 
Shawn.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help