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

[PATCH v3] do not overwrite untracked during merge from unborn branch

From
Clemens Buchacher <drizzd@aon.at>
Date
Nov 14, 2010, 22:07 UTC
Message-ID
<20101114220749.GA29786@localhost>
In-Reply-To
<20101114214953.GB16413@burratino>

In case HEAD does not point to a valid commit yet, merge is implemented as a hard reset. This will cause untracked files to be overwritten.

Instead, assume the empty tree for HEAD and do a regular merge. An untracked file will cause the merge to abort and do nothing. If no conflicting files are present, the merge will have the same effect as a hard reset.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
---
On Sun, Nov 14, 2010 at 03:49:53PM -0600, Jonathan Nieder wrote:
>
> Naturally, this is the sort of patch that would want to be
> fast-tracked to master (or even maint) if it is in good shape.
Ok, no problem. This applies to master and maint.
Clemens
 builtin/merge.c            |   20 +++++++++++++++++++-
 t/t7607-merge-overwrite.sh |   16 ++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletions(-)
diff --git a/builtin/merge.c b/builtin/merge.c
index 10f091b..613543e 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -234,6 +234,24 @@ static void save_state(void)
 		die("not a valid object: %s", buffer.buf);
 }
 
+static void read_empty(unsigned const char *sha1, int verbose)
+{
+	int i = 0;
+	const char *args[7];
+
+	args[i++] = "read-tree";
+	if (verbose)
+		args[i++] = "-v";
+	args[i++] = "-m";
+	args[i++] = "-u";
+	args[i++] = EMPTY_TREE_SHA1_HEX;
+	args[i++] = sha1_to_hex(sha1);
+	args[i] = NULL;
+
+	if (run_command_v_opt(args, RUN_GIT_CMD))
+		die("read-tree failed");
+}
+
 static void reset_hard(unsigned const char *sha1, int verbose)
 {
 	int i = 0;
@@ -985,7 +1003,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 			die("%s - not something we can merge", argv[0]);
 		update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
 				DIE_ON_ERR);
-		reset_hard(remote_head->sha1, 0);
+		read_empty(remote_head->sha1, 0);
 		return 0;
 	} else {
 		struct strbuf merge_names = STRBUF_INIT;
diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh
index d82349a..3988900 100755
--- a/t/t7607-merge-overwrite.sh
+++ b/t/t7607-merge-overwrite.sh
@@ -84,4 +84,20 @@ test_expect_success 'will not overwrite removed file with staged changes' '
 	test_cmp important c1.c
 '
 
+cat >expect <<\EOF
+error: Untracked working tree file 'c0.c' would be overwritten by merge.
+fatal: read-tree failed
+EOF
+
+test_expect_success 'will not overwrite untracked file on unborn branch' '
+	git reset --hard c0 &&
+	git rm -fr . &&
+	git checkout --orphan new &&
+	cp important c0.c &&
+	test_must_fail git merge c0 2>out &&
+	test_cmp out expect &&
+	test_path_is_missing .git/MERGE_HEAD &&
+	test_cmp important c0.c
+'
+
 test_done
-- 
1.7.3.1.105.g84915
Previous: Miles Bader
Message 9 of 9 in “pulling the root commit overwrites untracked files without warning (1.7.2.3)”
  1. Gert PalokOct 21, 2010
  2. Clemens BuchacherOct 22, 2010
  3. Clemens BuchacherOct 22, 2010
  4. Clemens BuchacherNov 14, 2010
  5. do not overwrite untracked during merge from unborn branchClemens Buchacher, Nov 14, 2010
  6. do not overwrite untracked during merge from unborn branchClemens Buchacher, Nov 14, 2010
  7. do not overwrite untracked during merge from unborn branchClemens Buchacher, Nov 14, 2010
  8. Miles BaderNov 15, 2010
  9. do not overwrite untracked during merge from unborn branchClemens Buchacher, Nov 14, 2010

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.