transport-helper: update remote helper namespace

When pushing, the remote namespace is updated correctly (e.g. refs/origin/master), but not the remote helper's (e.g. refs/testgit/origin/master), which currently is only updated while fetching. Since the remote namespace is used to tell fast-export which commits to avoid (because they were already imported/exported), it makes sense to have them in sync so they don't get generated twice. If the remote helper was implemented properly, they would be ignored, if not, they probably would end up repeated. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Felipe Contreras committed Apr 17, 2013 at 23:14 UTC 664059fb624467975da5c9a4bf6053c83126eaa7
2 files changed +31 -4
t/t5801-remote-helpers.sh
+12
@@ -153,6 +153,18 @@ test_expect_success 'push ref with existing object' '
153 compare_refs local dup server dup
154 '
155
156 +test_expect_success 'push update refs' '
157 + (cd local &&
158 + git checkout -b update master &&
159 + echo update >>file &&
160 + git commit -a -m update &&
161 + git push origin update
162 + git rev-parse --verify remotes/origin/update >expect &&
163 + git rev-parse --verify testgit/origin/heads/update >actual &&
164 + test_cmp expect actual
165 + )
166 +'
167 +
168 test_expect_success 'proper failure checks for fetching' '
169 (GIT_REMOTE_TESTGIT_FAILURE=1 &&
170 export GIT_REMOTE_TESTGIT_FAILURE &&
transport-helper.c
+19 -4
@@ -11,6 +11,7 @@
11 #include "thread-utils.h"
12 #include "sigchain.h"
13 #include "argv-array.h"
14 +#include "refs.h"
15
16 static int debug;
17
@@ -620,7 +621,7 @@ static int fetch(struct transport *transport,
621 return -1;
622 }
623
623 -static void push_update_ref_status(struct strbuf *buf,
624 +static int push_update_ref_status(struct strbuf *buf,
625 struct ref **ref,
626 struct ref *remote_refs)
627 {
@@ -686,7 +687,7 @@ static void push_update_ref_status(struct strbuf *buf,
687 *ref = find_ref_by_name(remote_refs, refname);
688 if (!*ref) {
689 warning("helper reported unexpected status of %s", refname);
689 - return;
690 + return 1;
691 }
692
693 if ((*ref)->status != REF_STATUS_NONE) {
@@ -695,11 +696,12 @@ static void push_update_ref_status(struct strbuf *buf,
696 * status reported by the remote helper if the latter is 'no match'.
697 */
698 if (status == REF_STATUS_NONE)
698 - return;
699 + return 1;
700 }
701
702 (*ref)->status = status;
703 (*ref)->remote_status = msg;
704 + return 0;
705 }
706
707 static void push_update_refs_status(struct helper_data *data,
@@ -708,11 +710,24 @@ static void push_update_refs_status(struct helper_data *data,
710 struct strbuf buf = STRBUF_INIT;
711 struct ref *ref = remote_refs;
712 for (;;) {
713 + char *private;
714 +
715 recvline(data, &buf);
716 if (!buf.len)
717 break;
718
715 - push_update_ref_status(&buf, &ref, remote_refs);
719 + if (push_update_ref_status(&buf, &ref, remote_refs))
720 + continue;
721 +
722 + if (!data->refspecs)
723 + continue;
724 +
725 + /* propagate back the update to the remote namespace */
726 + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
727 + if (!private)
728 + continue;
729 + update_ref("update by helper", private, ref->new_sha1, NULL, 0, 0);
730 + free(private);
731 }
732 strbuf_release(&buf);
733 }