summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--refs/files-backend.c19
-rwxr-xr-xt/t5510-fetch.sh20
2 files changed, 37 insertions, 2 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index d1af5d6bc7..bfdf85121a 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -906,8 +906,23 @@ retry:
* 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));
}
@@ -2832,7 +2847,7 @@ static int files_transaction_prepare(struct ref_store *ref_store,
"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;
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 6f8db0ace4..08dbea6503 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -53,6 +53,12 @@ test_expect_success "clone and setup child repos" '
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
)
'
@@ -1572,6 +1578,20 @@ test_expect_success REFFILES 'existing reference lock in repo' '
)
'
+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