Re* file deletion in index lost after checkout -b

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio C Hamano <gitster@xxxxxxxxx> writes:

> Jing Xue <jingxue@xxxxxxxxxxxxxxxxx> writes:
> ...
>> In Git 1.6.0 the following sequence:
>> ...
>> The deletion of 2.txt appears lost during 'checkout -b foo', while the
>> modification and addition were both brought over. Is it a bug?
>
> This behaviour is unchanged since early June 2005.
>
>     http://thread.gmane.org/gmane.comp.version-control.git/4641/focus=4646
>
> This is exactly the case marked as *0*, which both Linus and I said "it
> feels somewhat wrong but otherwise we cannot start from an empty index".
>
> We may want to do better this time around, though.

Try this patch.

 Documentation/git-read-tree.txt |   11 ++++++++++-
 builtin-checkout.c              |    1 +
 builtin-read-tree.c             |    1 +
 unpack-trees.c                  |   11 ++++++++++-
 unpack-trees.h                  |    1 +
 5 files changed, 23 insertions(+), 2 deletions(-)

diff --git c/Documentation/git-read-tree.txt i/Documentation/git-read-tree.txt
index 6f4b9b0..24155ab 100644
--- c/Documentation/git-read-tree.txt
+++ i/Documentation/git-read-tree.txt
@@ -160,7 +160,10 @@ Here are the "carry forward" rules:
       0 nothing             nothing  nothing  (does not happen)
       1 nothing             nothing  exists   use M
       2 nothing             exists   nothing  remove path from index
-      3 nothing             exists   exists   use M
+      3 nothing             exists   exists,  use M if index is empty
+				     H == M   keep index otherwise
+				     exists   fail
+				     H != M
 
         clean I==H  I==M
        ------------------
@@ -207,6 +210,12 @@ you picked it up via e-mail in a patch form), `git diff-index
 merge, but it would not show in `git diff-index --cached $M`
 output after two-tree merge.
 
+Case #3 is slightly tricky and needs explanation.  The result from this
+rule logically should be to remove the path if the user staged the removal
+of the path and then swiching to a new branch.  That however will prevent
+the initial checkout from happening, so the rule is modified to use M (new
+tree) only when the contents of the index is empty.  Otherwise the removal
+of the path is kept as long as $H and $M are the same.
 
 3-Way Merge
 ~~~~~~~~~~~
diff --git c/builtin-checkout.c i/builtin-checkout.c
index efdb1e0..c73a815 100644
--- c/builtin-checkout.c
+++ i/builtin-checkout.c
@@ -242,6 +242,7 @@ static int merge_working_tree(struct checkout_opts *opts,
 		}
 
 		/* 2-way merge to the new branch */
+		topts.index_was_empty = !active_nr;
 		topts.update = 1;
 		topts.merge = 1;
 		topts.gently = opts->merge;
diff --git c/builtin-read-tree.c i/builtin-read-tree.c
index dddc304..41ece57 100644
--- c/builtin-read-tree.c
+++ i/builtin-read-tree.c
@@ -160,6 +160,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 				die("you need to resolve your current index first");
 			stage = 1;
 			opts.merge = 1;
+			opts.index_was_empty = !active_nr;
 			continue;
 		}
 
diff --git c/unpack-trees.c i/unpack-trees.c
index ef21c62..43ff477 100644
--- c/unpack-trees.c
+++ i/unpack-trees.c
@@ -941,8 +941,17 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o)
 			return -1;
 		}
 	}
-	else if (newtree)
+	else if (newtree) {
+		if (oldtree && !o->index_was_empty) {
+			/*
+			 * deletion of the path was staged;
+			 */
+			if (same(oldtree, newtree))
+				return 1;
+			return reject_merge(oldtree, o);
+		}
 		return merged_entry(newtree, current, o);
+	}
 	return deleted_entry(oldtree, current, o);
 }
 
diff --git c/unpack-trees.h i/unpack-trees.h
index 94e5672..61d82ce 100644
--- c/unpack-trees.h
+++ i/unpack-trees.h
@@ -26,6 +26,7 @@ struct unpack_trees_options {
 		     verbose_update:1,
 		     aggressive:1,
 		     skip_unmerged:1,
+		     index_was_empty:1,
 		     gently:1;
 	const char *prefix;
 	int pos;
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux