git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Adding glob support to remotes

From
Junio C Hamano <junkio@cox.net>
Date
Nov 22, 2006, 20:50 UTC
Message-ID
<7v3b8bryt6.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<200611221441.02459.andyparkins@gmail.com>
Andy Parkins <andyparkins@gmail.com> writes:
Show 14 quoted lines
> On Wednesday 2006 November 22 12:56, Junio C Hamano wrote:
>
>> > However, git-ls-remote needs the name of the remote repository (of
>> > course), but that isn't directly available in git-parse-remote.sh.
>>
>> Is it really the case?  I do not remember the details offhand,
>> but I do not think canon_refs_list_for_fetch is the function you
>> should be messing with to implement the remote."origin".fetch
>> stuff.  It should be get_remote_default_refs_for_fetch().  The
>> function returns the list based on which remote, so it surely
>> knows which remote the caller is talking about.
>
> The problem is that canon_refs_list_for_fetch bombs out too early because "*" 
> is not an acceptable name for a ref.

I do not understand and that is why I do not understand why you would need to touch check-ref-format.

"remote.$1.fetch" is read by get_remote_default_refs_for_fetch and currently the value is given canon_refs_list_for_fetch without any preprocessing. My suggestion is to catch the "wildcard" in get_remote_default_refs_for_fetch, do your replacement based on an earlier ls-remote output, and give replaced values to canon_refs_list_for_fetch. That way I do not think check-ref-format that is used by canon_refs_list_for_fetch needs to see any wildcard.

Both config and remotes but not branches _could_ have wildcard so you would need to do the same wildcard replacement in two case arms of get_remote_default_refs_for_fetch but I think that can be done in a common helper function.

If on the other hand if you want to do this in canon_*, then you could do that before the "for ref" loop to set "$@" to the wildcard-expanded form. But there are other codepaths that use this function and I do not know if you want to apply the wildcarding to all of them (I haven't checked all the callers). If you are sure all the callers want the wildcarding the same way, it would be more appropriate to do so there than doing it in get_remote_default_refs_for_fetch as I suggested in the above. I.e. something like this perhaps.

 canon_refs_list_for_fetch () {
 ...
 			    --get-all "branch.${curr_branch}.merge")
 		fi
 	fi
+
+	expanded_ref_list=
+	for ref
+	do
+		if ref is wildcard
+		then
+			compute wildcard replacement and set it to nref
+			expanded_ref_list="$expanded_ref_list $nref"
+		else
+			expanded_ref_list="$expanded_ref_list $ref"
+		fi
+	done
+	set x $expanded_ref_list
+	shift
+
 	for ref
 	do
 		force=
>>  (1) dumb protocols currently cannot deal with a remote that has
>
> I'm not sure I've understood this point.  I shall look at git-fetch.sh more 
> closely to try and address this though.
I was talking about this part of the code:
      case "$remote" in
      http://* | https://* | ftp://*)
	  if [ -n "$GIT_SSL_NO_VERIFY" ]; then
	      curl_extra_args="-k"
	  fi
	  if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
		"`git-repo-config --bool http.noEPSV`" = true ]; then
	      noepsv_opt="--disable-epsv"
	  fi
	  max_depth=5
	  depth=0
	  head="ref: $remote_name"
	  while (expr "z$head" : "zref:" && expr $depth \< $max_depth) >/dev/null
	  do
	    remote_name_quoted=$(@@PERL@@ -e '
	      my $u = $ARGV[0];
              $u =~ s/^ref:\s*//;
	      $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
	      print "$u";
	  ' "$head")
	    head=$(curl -nsfL $curl_extra_args $noepsv_opt "$remote/$remote_name_quoted")
	    depth=$( expr \( $depth + 1 \) )
	  done
	  expr "z$head" : "z$_x40\$" >/dev/null ||
	      die "Failed to fetch $remote_name from $remote"
	  echo >&2 Fetching "$remote_name from $remote" using http
	  git-http-fetch -v -a "$head" "$remote/" || exit
	  ;;

The while loop is initialized with "ref: refs/heads/$branch", extracts the "refs/heads/$branch" from it by hand, and runs "curl -nsfL" to get http://host/repo.git/refs/heads/$branch, until it is not a symref anymore (refs/heads/$branch _could_ be a symref that points at refs/heads/$another, and that is the loop is about). At the end of the loop, $head would contain what is read from the ref -- 40-byte object name. That is given to git-http-fetch.

However, the above assumes $GIT_DIR/refs/heads/$branch file exists at the remote end for "curl -nsfL" to fetch. When refs are packed-and-pruned, refs/heads/$branch may not exist as a standalone file; the right way to learn "what object does a ref point at" is to ask ls-remote, and if you do one ls-remote upfront then all you need to do here is a single grep.

Previous: Andy ParkinsNext: Andy Parkins
Message 4 of 5 in “Adding glob support to remotes”
  1. Andy ParkinsNov 22, 2006
  2. Junio C HamanoNov 22, 2006
  3. Andy ParkinsNov 22, 2006
  4. Junio C HamanoNov 22, 2006
  5. Andy ParkinsNov 23, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.