{"thread":{"id":"12360","subject":"[PATCH 4/4] Teach git-fetch to grab a tag at the same time as a commit","startedAt":"2008-02-28T08:43:05Z","lastAt":"2008-02-28T08:43:05Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"70224","messageId":"20080228084305.GD16870@spearce.org","threadId":"12360","inReplyTo":null,"subject":"[PATCH 4/4] Teach git-fetch to grab a tag at the same time as a commit","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-02-28T08:43:05Z","receivedAt":"2008-02-28T08:43:05Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the situation is the following on the remote and L is the common\nbase between both sides:\n\n          T - tag1    S - tag2\n         /           /\n    L - A - O - O - B\n     \\               \\\n      origin/master   master\n\nand we have decided to fetch \"master\" to acquire the range L..B we\ncan also nab tag S at the same time during the first connection,\nas we can clearly see from the refs advertised by upload-pack that\nS^{} = B and master = B.\n\nUnfortunately we still cannot nab T at the same time as we are not\nable to see that T^{} will also be in the range implied by L..B.\nSuch computations must be performed on the remote side (not yet\nsupported) or on the client side as post-processing (the current\nbehavior).\n\nThis optimization is an extension of the previous one in that it\nhelps on projects which tend to publish both a new commit and a\nnew tag, then lay idle for a while before publishing anything else.\nMost followers are able to download both the new commit and the new\ntag in one connection, rather than two.  git.git tends to follow\nsuch patterns with its roughly once-daily updates from Junio.\n\nA protocol extension and additional server side logic would be\nnecessary to also ensure T is grabbed on the first connection.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-fetch.c |   14 +++++++++++++-\n 1 files changed, 13 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-fetch.c b/builtin-fetch.c\nindex a80f95b..eddf788 100644\n--- a/builtin-fetch.c\n+++ b/builtin-fetch.c\n@@ -458,6 +458,17 @@ static int add_existing(const char *refname, const unsigned char *sha1,\n \treturn 0;\n }\n \n+static int will_fetch(struct ref **head, const unsigned char *sha1)\n+{\n+\tstruct ref *rm = *head;\n+\twhile (rm) {\n+\t\tif (!hashcmp(rm->old_sha1, sha1))\n+\t\t\treturn 1;\n+\t\trm = rm->next;\n+\t}\n+\treturn 0;\n+}\n+\n static void find_non_local_tags(struct transport *transport,\n \t\t\tstruct ref **head,\n \t\t\tstruct ref ***tail)\n@@ -494,7 +505,8 @@ static void find_non_local_tags(struct transport *transport,\n \n \t\tif (!path_list_has_path(&existing_refs, ref_name) &&\n \t\t    !path_list_has_path(&new_refs, ref_name) &&\n-\t\t    has_sha1_file(ref->old_sha1)) {\n+\t\t    (has_sha1_file(ref->old_sha1) ||\n+\t\t     will_fetch(head, ref->old_sha1))) {\n \t\t\tpath_list_insert(ref_name, &new_refs);\n \n \t\t\trm = alloc_ref(strlen(ref_name) + 1);\n-- \n1.5.4.3.393.g5540\n"}]}