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

Re: Merge with local conflicts in new files

From
Junio C Hamano <junkio@cox.net>
Date
May 16, 2006, 22:40 UTC
Message-ID
<7v1wut61aj.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<8aa486160605161500m1dd8428cj@mail.gmail.com>
Santi <sbejar@gmail.com> writes:
Show 5 quoted lines
>       In the case of:
>
> - You merge from a branch with new files
> - You have these files in the working directory
> - You do not have these files in the HEAD.
and
 - You have not told git that these files matter.
Show 11 quoted lines
>...
> test_expect_success 'prepare repository' \
> 'echo "Hello" > init &&
> git add init &&
> git commit -m "Initial commit" &&
> git branch B &&
> echo "foo" > foo &&
> git add foo &&
> git commit -m "File: foo" &&
> git checkout B &&
> echo "bar" > foo '

At this point, you have not told git that foo is a file that is relevant on branch B, so git considers it a fair game to overwrite.

At least, that was the original reasoning.

It happens not just during the ordinary "git-merge", by the way. If you are on branch B that did not have 'foo', created 'foo' and switched to branch A (which has 'foo') before telling the index that you care about your version of 'foo' on branch B, 'foo' from branch A will overwrite your throwaway copy in the working tree:

	$ git branch
	* master
        $ git branch another
	$ echo 'New file' >afile
        $ git add afile
        $ git commit -m 'Add afile'
        $ git checkout another
        $ ls afile
	ls: afile: No such file or directory
        $ echo 'Lost file' >afile
        $ git checkout master
        $ cat afile
        New file

We acquired "git apply" which does take notice when you have such an untracked file in the working tree that conflicts with what it does to the index, and I think its behaviour sometimes is more user friendly and safer than what the merge does currently (but it irritates people some other times).

This is totally untested, but on top of "next" you could do something like this, perhaps.

We _might_ want to do this conditionally, only when the user asks, though. I dunno. Being able to blow away irrelevant files is sometimes a good thing, so we _might_ want to have a reverse logic to "git apply" that makes it blow away untracked working tree files under "--index" option.

-- >8 --
diff --git a/read-tree.c b/read-tree.c
index aa6172b..185a73f 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -453,8 +453,18 @@ static int merged_entry(struct cache_ent
 			invalidate_ce_path(old);
 		}
 	}
-	else
+	else {
+		/*
+		 * Originally we did not have a cache entry here but
+		 * are creating a new file as a result of the merge.
+		 * Do we want to lose the untracked working tree files?
+		 */
+		struct stat st;
+
+		if (!lstat(merge->name, &st))
+			die("Untracked working tree file '%s' would be overwritten by merge.", merge->name);
 		invalidate_ce_path(merge);
+	}
 	merge->ce_flags &= ~htons(CE_STAGEMASK);
 	add_cache_entry(merge, ADD_CACHE_OK_TO_ADD);
 	return 1;
@@ -701,7 +711,7 @@ static int bind_merge(struct cache_entry
 		return error("Cannot do a bind merge of %d trees\n",
 			     merge_size);
 	if (!a)
-		return merged_entry(old, NULL);
+		return merged_entry(old, old);
 	if (old)
 		die("Entry '%s' overlaps.  Cannot bind.", a->name);
 
@@ -736,7 +746,7 @@ static int oneway_merge(struct cache_ent
 		}
 		return keep_entry(old);
 	}
-	return merged_entry(a, NULL);
+	return merged_entry(a, old);
 }
 
 static int read_cache_unmerged(void)
Previous: SantiNext: Santi
Message 3 of 10 in “Merge with local conflicts in new files”
  1. SantiMay 16, 2006
  2. SantiMay 16, 2006
  3. Junio C HamanoMay 16, 2006
  4. SantiMay 16, 2006
  5. Junio C HamanoMay 16, 2006
  6. Pavel RoskinMay 17, 2006
  7. Junio C HamanoMay 17, 2006
  8. Martin LanghoffMay 17, 2006
  9. read-tree -m -u: do not overwrite or remove untracked working tree files.Junio C Hamano, May 17, 2006
  10. Jakub NarebskiMay 17, 2006

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.