commit - e15c42decfa8a80fb91cc1e19b467efc34a8c05d
commit + 7db2b0ddc68d7d2761c2c1b93fa9543431efde97
blob - 78eb9ebab2c20cab529d7f47d39f8d4829ac8699
blob + a7ca5b927daf30815b370c13f3ec304c395a1051
--- 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