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

Re: [PATCH] modify/delete conflict resolution overwrites untracked file

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 15, 2008, 03:34 UTC
Message-ID
<7vmyeyyuuh.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<7v63lm1c76.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
Show 18 quoted lines
> Clemens Buchacher <drizzd@aon.at> writes:
>
>> On Wed, Dec 10, 2008 at 09:12:59PM +0100, Clemens Buchacher wrote:
>>> If a file was removed in HEAD, but modified in MERGE_HEAD, recursive merge
>>> will result in a "CONFLICT (delete/modify)". If the (now untracked) file
>>> already exists and was not added to the index, it is overwritten with the
>>> conflict resolution contents.
>>
>> The following patch fixes the problem described above, but it also breaks
>> t6023-merge-rename-nocruft.sh, which tries to merge "A" renamed to "B" in
>> HEAD and "A" modified in MERGE_HEAD, while ignoring an untracked file "A" in
>> the working tree. If we want to be able to do this, we have to handle the
>> other case after rename detection.
>
> If the breakage is in merge-recursive but not in merge-resolve, my gut
> feeling is that we should not be touching unpack-trees at all.  With luck
> I may be able to find some time to take a look at this myself but right
> now we are entertaining a guest, so....

-- >8 -- merge-recursive: do not clobber untracked working tree garbage

When merge-recursive wanted to create a new file in the work tree (either as the final result, or a hint for reference purposes while delete/modify conflicts), it unconditionally overwrote an untracked file in the working tree. Be careful not to lose whatever the user has that is not tracked.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 merge-recursive.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
diff --git c/merge-recursive.c w/merge-recursive.c
index a0c804c..2da4333 100644
--- c/merge-recursive.c
+++ w/merge-recursive.c
@@ -447,6 +447,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
 	}
 }
 
+static int would_lose_untracked(const char *path)
+{
+	int pos = cache_name_pos(path, strlen(path));
+
+	if (pos < 0)
+		pos = -1 - pos;
+	while (pos < active_nr &&
+	       !strcmp(path, active_cache[pos]->name)) {
+		/*
+		 * If stage #0, it is definitely tracked.
+		 * If it has stage #2 then it was tracked
+		 * before this merge started.  All other
+		 * cases the path was not tracked.
+		 */
+		switch (ce_stage(active_cache[pos])) {
+		case 0:
+		case 2:
+			return 0;
+		}
+		pos++;
+	}
+	return file_exists(path);
+}
+
 static int make_room_for_path(const char *path)
 {
 	int status;
@@ -462,6 +486,14 @@ static int make_room_for_path(const char *path)
 		die(msg, path, "");
 	}
 
+	/*
+	 * Do not unlink a file in the work tree if we are not
+	 * tracking it.
+	 */
+	if (would_lose_untracked(path))
+		return error("refusing to lose untracked file at '%s'",
+			     path);
+
 	/* Successful unlink is good.. */
 	if (!unlink(path))
 		return 0;
Previous: Junio C HamanoNext: Johannes Schindelin
Message 9 of 24 in “modify/delete conflict resolution overwrites untracked file”
  1. modify/delete conflict resolution overwrites untracked fileClemens Buchacher, Dec 10, 2008
  2. Junio C HamanoDec 10, 2008
  3. Clemens BuchacherDec 10, 2008
  4. Junio C HamanoDec 10, 2008
  5. Clemens BuchacherDec 11, 2008
  6. Junio C HamanoDec 11, 2008
  7. Clemens BuchacherDec 15, 2008
  8. Junio C HamanoDec 15, 2008
  9. Junio C HamanoDec 15, 2008
  10. Johannes SchindelinDec 15, 2008
  11. Junio C HamanoDec 15, 2008
  12. Johannes SchindelinDec 15, 2008
  13. Clemens BuchacherDec 15, 2008
  14. Junio C HamanoDec 15, 2008
  15. Mike RalphsonDec 15, 2008
  16. Johannes SchindelinDec 15, 2008
  17. Mike RalphsonDec 15, 2008
  18. Junio C HamanoDec 15, 2008
  19. Clemens BuchacherDec 15, 2008
  20. Junio C HamanoDec 16, 2008
  21. Jakub NarebskiDec 16, 2008
  22. Clemens BuchacherDec 28, 2008
  23. Junio C HamanoDec 28, 2008
  24. Clemens BuchacherDec 28, 2008

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.