git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] merge-recursive.c: Fix case-changing merge bug

From
David Turner <dturner@twopensource.com>
Date
May 2, 2014, 00:21 UTC
Message-ID
<1398990069.19099.5.camel@stross>
In-Reply-To
<CAE+yK_m_bPt2pS6MQOrpvVDuLAJf8NFxYOgM8i98tU6-gLcTDw@mail.gmail.com>

On a case-insensitive filesystem, when merging, a file would be wrongly deleted from the working tree if an incoming commit had renamed it changing only its case. When merging a rename, the file with the old name would be deleted -- but since the filesystem considers the old name to be the same as the new name, the new file would in fact be deleted.

We avoid this by not deleting files that have a case-clone in the index at stage 0.

Signed-off-by: David Turner <dturner@twitter.com>
---
 merge-recursive.c           |  6 ++++++
 t/t7063-merge-ignorecase.sh | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100755 t/t7063-merge-ignorecase.sh
diff --git a/merge-recursive.c b/merge-recursive.c
index 4177092..cab16fa 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -589,6 +589,12 @@ static int remove_file(struct merge_options *o, int clean,
 			return -1;
 	}
 	if (update_working_directory) {
+		if (ignore_case) {
+			struct cache_entry *ce;
+			ce = cache_file_exists(path, strlen(path), ignore_case);
+			if (ce && ce_stage(ce) == 0)
+				return 0;
+		}
 		if (remove_path(path))
 			return -1;
 	}
diff --git a/t/t7063-merge-ignorecase.sh b/t/t7063-merge-ignorecase.sh
new file mode 100755
index 0000000..6d4959f
--- /dev/null
+++ b/t/t7063-merge-ignorecase.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+test_description='git-merge with case-changing rename on case-insensitive file system'
+
+. ./test-lib.sh
+
+if ! test_have_prereq CASE_INSENSITIVE_FS
+then
+	skip_all='skipping case insensitive tests - case sensitive file system'
+	test_done
+fi
+
+test_expect_success 'merge with case-changing rename with ignorecase=true' '
+	test $(git config core.ignorecase) = true &&
+	touch TestCase &&
+	git add TestCase &&
+	git commit -m "add TestCase" &&
+	git checkout -b with-camel &&
+	touch foo &&
+	git add foo &&
+	git commit -m "intervening commit" &&
+	git checkout master &&
+	git rm TestCase &&
+	touch testcase &&
+	git add testcase &&
+	git commit -m "rename to testcase" &&
+	git checkout with-camel &&
+	git merge master -m "merge" &&
+	test -e testcase
+'
+
+test_done
Previous: David TurnerNext: Junio C Hamano
Message 2 of 24 in “Bug: Case-insensitive filesystems can cause merge and checkout problems”
  1. David TurnerApr 29, 2014
  2. merge-recursive.c: Fix case-changing merge bugDavid Turner, May 2, 2014
  3. Junio C HamanoMay 6, 2014
  4. David TurnerMay 6, 2014
  5. Junio C HamanoMay 6, 2014
  6. 1/2 merge-recursive.c: Fix case-changing merge.dturner@twopensource.com, May 6, 2014
  7. 2/2 ignorecase: Fix git mv on insensitive filesystemsdturner@twopensource.com, May 6, 2014
  8. Johannes SixtMay 7, 2014
  9. David TurnerMay 7, 2014
  10. Junio C HamanoMay 7, 2014
  11. David TurnerMay 7, 2014
  12. Johannes SixtMay 8, 2014
  13. Torsten BögershausenMay 8, 2014
  14. 0/2 Re: ignorecase: Fix git mv on insensitive filesystemsdturner@twopensource.com, May 8, 2014
  15. 1/2 merge-recursive.c: Fix case-changing merge.dturner@twopensource.com, May 8, 2014
  16. Junio C HamanoMay 8, 2014
  17. 2/2 ignorecase: Fix git mv on insensitive filesystemsdturner@twopensource.com, May 8, 2014
  18. Junio C HamanoMay 8, 2014
  19. David TurnerMay 8, 2014
  20. Junio C HamanoMay 8, 2014
  21. brian m. carlsonMay 8, 2014
  22. Junio C HamanoMay 7, 2014
  23. Jonathan NiederMay 7, 2014
  24. Junio C HamanoMay 7, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.