* If the ref did not exist and we are creating it, we have to
* make sure there is no existing packed ref that conflicts
* with refname. This check is deferred so that we can batch it.
+ *
+ * For case-insensitive filesystems, we should also check for F/D
+ * conflicts between 'foo' and 'Foo/bar'. So let's lowercase
+ * the refname.
*/
- item = string_list_append(refnames_to_check, refname);
+ if (ignore_case) {
+ struct strbuf lower = STRBUF_INIT;
+
+ strbuf_addstr(&lower, refname);
+ strbuf_tolower(&lower);
+
+ item = string_list_append_nodup(refnames_to_check,
+ strbuf_detach(&lower, NULL));
+ } else {
+ item = string_list_append(refnames_to_check, refname);
+ }
+
item->util = xmalloc(sizeof(update_idx));
memcpy(item->util, &update_idx, sizeof(update_idx));
}
"ref_transaction_prepare");
size_t i;
int ret = 0;
- struct string_list refnames_to_check = STRING_LIST_INIT_NODUP;
+ struct string_list refnames_to_check = STRING_LIST_INIT_DUP;
char *head_ref = NULL;
int head_type;
struct files_transaction_backend_data *backend_data;
cd case_sensitive &&
git branch branch1 &&
git branch bRanch1
+ ) &&
+ git clone --ref-format=reftable . case_sensitive_fd &&
+ (
+ cd case_sensitive_fd &&
+ git branch foo/bar &&
+ git branch Foo
)
'
)
'
+test_expect_success CASE_INSENSITIVE_FS,REFFILES 'F/D conflict on case insensitive filesystem' '
+ test_when_finished rm -rf case_insensitive &&
+ (
+ git init --bare case_insensitive &&
+ cd case_insensitive &&
+ git remote add origin -- ../case_sensitive_fd &&
+ test_must_fail git fetch -f origin "refs/heads/*:refs/heads/*" 2>err &&
+ test_grep "failed: refname conflict" err &&
+ git rev-parse refs/heads/main >expect &&
+ git rev-parse refs/heads/foo/bar >actual &&
+ test_cmp expect actual
+ )
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd