From: "Devin J. Pohly" <>

Allow a fetch-style remote helper to issue the notification
  ref <sha1> <name>
to specify a ref's value during the fetch operation.

Currently, a remote helper with the "fetch" capability cannot fetch a
ref unless its sha1 was known when the "list" command was executed.
This limitation is arbitrary, as the helper may eventually be able to
determine the correct sha1 as it fetches objects.

Signed-off-by: Devin J. Pohly <>

Soliciting general opinions - first git patch. :)

The fetch command can be a lot more convenient than import if you're working
with a remote that doesn't give you a commit and the associated objects at the
same time.  And there's no apparent reason that something like this isn't

How it works: the old_sha1 field is currently set when the output from "list"
is parsed, then not used again until after the "fetch" command completes, just
before updating refs.  Changing it during the fetch only affects the final
value of the ref.  (Forgetting to resolve a ref will result in exactly the
same behavior as before: an error from check_everything_connected.)

Not sure if either or both of the warning()s should be a die() instead.

 Documentation/git-remote-helpers.txt |  8 ++++++--
 transport-helper.c                   | 24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-remote-helpers.txt 
index f5836e4..fb4240f 100644
--- a/Documentation/git-remote-helpers.txt
+++ b/Documentation/git-remote-helpers.txt
@@ -229,8 +229,12 @@ Supported if the helper has the "option" capability.
        to the database.  Fetch commands are sent in a batch, one
        per line, terminated with a blank line.
        Outputs a single blank line when all fetch commands in the
-       same batch are complete. Only objects which were reported
-       in the ref list with a sha1 may be fetched this way.
+       same batch are complete.
+If the named ref was reported in the ref list without a sha1, must
+output a 'ref <sha1> <name>' line once the sha1 is known.  This is
+also required for a symref if its target did not have a sha1 in the
 Optionally may output a 'lock <file>' line indicating a file under
 GIT_DIR/objects/pack which is keeping a pack until refs can be
diff --git a/transport-helper.c b/transport-helper.c
index cfe0988..6fce419 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -363,6 +363,30 @@ static int fetch_with_fetch(struct transport *transport,
                                warning("%s also locked %s", data->name, name);
                                transport->pack_lockfile = xstrdup(name);
+               } else if (!prefixcmp(buf.buf, "ref ")) {
+                       const char *rest = buf.buf + 4;
+                       char *eov, *eon;
+                       struct ref *posn;
+                       eov = strchr(rest, ' ');
+                       if (!eov)
+                               die("Malformed ref command: %s", buf.buf);
+                       eon = strchr(eov + 1, ' ');
+                       *eov = '\0';
+                       if (eon)
+                               *eon = '\0';
+                       for (i = 0; i < nr_heads; i++) {
+                               posn = to_fetch[i];
+                               if (!strcmp(eov + 1, posn->name))
+                                       break;
+                       }
+                       if (i == nr_heads || (posn->status & 
+                               warning("Ref %s is not being fetched", eov + 1);
+                               continue;
+                       }
+                       if (!is_null_sha1(posn->old_sha1))
+                               warning("Ref %s is being overwritten", eov + 1);
+                       get_sha1_hex(rest, posn->old_sha1);
                else if (!buf.len)

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to