commit - d68b973725ce0a2c7b1f5094448a444d4f2effdc
commit + 21de8138fee88f812099d8b0b71d8280f4f6ba4e
blob - 2e6723491391ba8acccf1a7f0ef9085db6cba827
blob + 3a699c9c2d5c9bc7d891ae0c0e65af894a4e653e
--- lib/reference.c
+++ lib/reference.c
new->ref = ref;
*newp = new;
+ if (cmp_cb != got_ref_cmp_by_name &&
+ (new->ref->flags & GOT_REF_IS_PACKED)) {
+ /*
+ * If we are not sorting elements by name then we must still
+ * detect collisions between a packed ref and an on-disk ref
+ * using the same name. On-disk refs take precedence and are
+ * already present on the list before packed refs get added.
+ */
+ TAILQ_FOREACH(re, refs, entry) {
+ err = got_ref_cmp_by_name(NULL, &cmp,
+ re->ref, new->ref);
+ if (err)
+ return err;
+ if (cmp == 0) {
+ free(new);
+ *newp = NULL;
+ return NULL;
+ }
+ }
+ }
+
/*
* We must de-duplicate entries on insert because packed-refs may
* contain redundant entries. On-disk refs take precedence.
blob - a025c5170abf06b7f707406ee2d9193c3fa6ff43
blob + cab7171d5632c0bdf72e14e1d6dda98d3a4ce810
--- regress/cmdline/branch.sh
+++ regress/cmdline/branch.sh
test_done "$testroot" "$ret"
}
+
+test_branch_packed_ref_collision() {
+ local testroot=`test_init branch_packed_ref_collision`
+ local commit_id=`git_show_head $testroot/repo`
+ got br -r $testroot/repo zoo > $testroot/stdout
+ got co -b zoo $testroot/repo $testroot/wt > /dev/null
+ echo "modified alpha" > $testroot/wt/alpha
+
+ # sleep in order to ensure that a significant fraction of time
+ # passes between commits; required for got branch -t option below
+ sleep 1
+
+ (cd $testroot/wt && got commit -m "modified alpha" >/dev/null)
+ local commit_id2=`git_show_branch_head $testroot/repo zoo`
+
+ # Fabricate a packed reference which points to an older commit
+ # and collides with the existing on-disk reference
+ echo '# pack-refs with: peeled fully-peeled sorted' > \
+ $testroot/repo/.git/packed-refs
+ echo "$commit_id refs/heads/zoo" >> $testroot/repo/.git/packed-refs
+
+ # Bug: This command used to show both packed and on-disk
+ # variants of ref/heads/zoo:
+ (cd $testroot/wt && got br -lt > $testroot/stdout)
+
+ echo "* zoo: $commit_id2" > $testroot/stdout.expected
+ echo " master: $commit_id" >> $testroot/stdout.expected
+ cmp -s $testroot/stdout $testroot/stdout.expected
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ test_done "$testroot" "$ret"
+}
+
test_parseargs "$@"
run_test test_branch_create
run_test test_branch_list
run_test test_branch_delete_current_branch
run_test test_branch_delete_packed
run_test test_branch_show
+run_test test_branch_packed_ref_collision