if (oidset_insert(seen, oid))
return 0;
path = ".have";
+ } else {
+ oidset_insert(seen, oid);
}
show_ref(path, oid->hash);
return 0;
{
static struct oidset seen = OIDSET_INIT;
+ for_each_ref(show_ref_cb, &seen);
for_each_alternate_ref(show_one_alternate_ref, &seen);
oidset_clear(&seen);
- for_each_ref(show_ref_cb, &seen);
if (!sent_capabilities)
show_ref("capabilities^{}", null_sha1);
)
'
+extract_ref_advertisement () {
+ perl -lne '
+ # \\ is there to skip capabilities after \0
+ /push< ([^\\]+)/ or next;
+ exit 0 if $1 eq "0000";
+ print $1;
+ '
+}
+
+test_expect_success 'receive-pack de-dupes .have lines' '
+ git init shared &&
+ git -C shared commit --allow-empty -m both &&
+ git clone -s shared fork &&
+ (
+ cd shared &&
+ git checkout -b only-shared &&
+ git commit --allow-empty -m only-shared &&
+ git update-ref refs/heads/foo HEAD
+ ) &&
+
+ # Notable things in this expectation:
+ # - local refs are not de-duped
+ # - .have does not duplicate locals
+ # - .have does not duplicate itself
+ local=$(git -C fork rev-parse HEAD) &&
+ shared=$(git -C shared rev-parse only-shared) &&
+ cat >expect <<-EOF &&
+ $local refs/heads/master
+ $local refs/remotes/origin/HEAD
+ $local refs/remotes/origin/master
+ $shared .have
+ EOF
+
+ GIT_TRACE_PACKET=$(pwd)/trace git push fork HEAD:foo &&
+ extract_ref_advertisement <trace >refs &&
+ test_cmp expect refs
+'
+
test_done