From: Elijah Newren <newren@gmail.com>
To: git@vger.kernel.org
Cc: Elijah Newren <newren@gmail.com>
Subject: [PATCH 27/30] merge-recursive: Apply necessary modifications for directory renames
Date: Fri, 10 Nov 2017 11:05:47 -0800 [thread overview]
Message-ID: <20171110190550.27059-28-newren@gmail.com> (raw)
In-Reply-To: <20171110190550.27059-1-newren@gmail.com>
This commit hooks together all the directory rename logic by making the
necessary changes to the rename struct, it's dst_entry, and the
diff_filepair under consideration.
Signed-off-by: Elijah Newren <newren@gmail.com>
---
merge-recursive.c | 195 +++++++++++++++++++++++++++++++++++-
t/t6043-merge-rename-directories.sh | 50 ++++-----
2 files changed, 219 insertions(+), 26 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index 2a7258f6bb..838bfd32ec 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -166,6 +166,7 @@ static int oid_eq(const struct object_id *a, const struct object_id *b)
enum rename_type {
RENAME_NORMAL = 0,
+ RENAME_DIR,
RENAME_DELETE,
RENAME_ONE_FILE_TO_ONE,
RENAME_ONE_FILE_TO_TWO,
@@ -599,6 +600,7 @@ struct rename {
*/
struct stage_data *src_entry;
struct stage_data *dst_entry;
+ unsigned add_turned_into_rename:1;
unsigned processed:1;
};
@@ -633,6 +635,26 @@ static int update_stages(struct merge_options *opt, const char *path,
return 0;
}
+static int update_stages_for_stage_data(struct merge_options *opt,
+ const char *path,
+ const struct stage_data *stage_data)
+{
+ struct diff_filespec o, a, b;
+ o.mode = stage_data->stages[1].mode;
+ oidcpy(&o.oid, &stage_data->stages[1].oid);
+
+ a.mode = stage_data->stages[2].mode;
+ oidcpy(&a.oid, &stage_data->stages[2].oid);
+
+ b.mode = stage_data->stages[3].mode;
+ oidcpy(&b.oid, &stage_data->stages[3].oid);
+
+ return update_stages(opt, path,
+ is_null_sha1(o.oid.hash) ? NULL : &o,
+ is_null_sha1(a.oid.hash) ? NULL : &a,
+ is_null_sha1(b.oid.hash) ? NULL : &b);
+}
+
static void update_entry(struct stage_data *entry,
struct diff_filespec *o,
struct diff_filespec *a,
@@ -1100,6 +1122,18 @@ static int merge_file_one(struct merge_options *o,
return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi);
}
+static int conflict_rename_dir(struct merge_options *o,
+ struct diff_filepair *pair,
+ const char *rename_branch,
+ const char *other_branch)
+{
+ const struct diff_filespec *dest = pair->two;
+
+ if (update_file(o, 1, &dest->oid, dest->mode, dest->path))
+ return -1;
+ return 0;
+}
+
static int handle_change_delete(struct merge_options *o,
const char *path, const char *old_path,
const struct object_id *o_oid, int o_mode,
@@ -1369,6 +1403,24 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
if (!ret)
ret = update_file(o, 0, &mfi_c2.oid, mfi_c2.mode,
new_path2);
+ /*
+ * unpack_trees() actually populates the index for us for
+ * "normal" rename/rename(2to1) situtations so that the
+ * correct entries are at the higher stages, which would
+ * make the call below to update_stages_for_stage_data
+ * unnecessary. However, if either of the renames came
+ * from a directory rename, then unpack_trees() will not
+ * have gotten the right data loaded into the index, so we
+ * need to do so now. (While it'd be tempting to move this
+ * call to update_stages_for_stage_data() to
+ * apply_directory_rename_modifications(), that would break
+ * our intermediate calls to would_lose_untracked() since
+ * those rely on the current in-memory index. See also the
+ * big "NOTE" in update_stages()).
+ */
+ if (update_stages_for_stage_data(o, path, ci->dst_entry1))
+ ret = -1;
+
free(new_path2);
free(new_path1);
}
@@ -1888,6 +1940,120 @@ static char *check_for_directory_rename(struct merge_options *o,
return new_path;
}
+static void apply_directory_rename_modifications(struct merge_options *o,
+ struct diff_filepair *pair,
+ char *new_path,
+ struct rename *re,
+ struct tree *tree,
+ struct tree *o_tree,
+ struct tree *a_tree,
+ struct tree *b_tree,
+ struct string_list *entries,
+ int *clean)
+{
+ struct string_list_item *item;
+ int stage = (tree == a_tree ? 2 : 3);
+
+ /*
+ * In all cases where we can do directory rename detection,
+ * unpack_trees() will have read pair->two->path into the
+ * index and the working copy. We need to remove it so that
+ * we can instead place it at new_path. It is guaranteed to
+ * not be untracked (unpack_trees() would have errored out
+ * saying the file would have been overwritten), but it might
+ * be dirty, though.
+ */
+ remove_file(o, 1, pair->two->path, 0 /* no_wd */);
+
+ /* Find or create a new re->dst_entry */
+ item = string_list_lookup(entries, new_path);
+ if (item) {
+ /*
+ * Since we're renaming on this side of history, and it's
+ * due to a directory rename on the other side of history
+ * (which we only allow when the directory in question no
+ * longer exists on the other side of history), the
+ * original entry for re->dst_entry is no longer
+ * necessary...
+ */
+ re->dst_entry->processed = 1;
+
+ /*
+ * ...because we'll be using this new one.
+ */
+ re->dst_entry = item->util;
+ } else {
+ /*
+ * re->dst_entry is for the before-dir-rename path, and we
+ * need it to hold information for the after-dir-rename
+ * path. Before creating a new entry, we need to mark the
+ * old one as unnecessary (...unless it is shared by
+ * src_entry, i.e. this didn't use to be a rename, in which
+ * case we can just allow the normal processing to happen
+ * for it).
+ */
+ if (!strcmp(pair->one->path, pair->two->path)) {
+ /*
+ * Paths should only match if this was initially a
+ * non-rename that is being turned into one by
+ * directory rename detection.
+ */
+ assert(pair->status != 'R');
+ } else {
+ assert(pair->status == 'R');
+ re->dst_entry->processed = 1;
+ //string_list_remove(entries, pair->two->path, 0);
+ }
+
+ re->dst_entry = insert_stage_data(new_path,
+ o_tree, a_tree, b_tree,
+ entries);
+ item = string_list_insert(entries, new_path);
+ item->util = re->dst_entry;
+ }
+
+ /*
+ * Update the stage_data with the information about the path we are
+ * moving into place. That slot will be empty and available for us
+ * to write to because of the collision checks in
+ * handle_path_level_conflicts().
+ *
+ * It may be tempting to actually update the index at this point as
+ * well, using update_stages_for_stage_data(), but as per the big
+ * "NOTE" in update_stages(), doing so will modify the current
+ * in-memory index which will break calls to would_lose_untracked()
+ * that we need to make. Instead, we need to just make sure that
+ * the various conflict_rename_*() functions update the index
+ * explicitly rather than relying on unpack_trees() to have done it.
+ */
+ assert(is_null_oid(&re->dst_entry->stages[stage].oid));
+ get_tree_entry(tree->object.oid.hash,
+ pair->two->path,
+ re->dst_entry->stages[stage].oid.hash,
+ &re->dst_entry->stages[stage].mode);
+
+ /* Update pair status */
+ if (pair->status == 'A') {
+ /*
+ * Recording rename information for this add makes it look
+ * like a rename/delete conflict. Make sure we can
+ * correctly handle this as an add that was moved to a new
+ * directory instead of reporting a rename/delete conflict.
+ */
+ re->add_turned_into_rename = 1;
+ }
+ /*
+ * We don't actually look at pair->status again, but it seems
+ * pedagogically correct to adjust it.
+ */
+ pair->status = 'R';
+
+ /*
+ * Finally, record the new location.
+ */
+ pair->two->path = new_path;
+}
+
/*
* Get information of all renames which occurred in 'pairs', making use of
* any implicit directory renames inferred from the other side of history.
@@ -1937,6 +2103,7 @@ static struct string_list *get_renames(struct merge_options *o,
re = xmalloc(sizeof(*re));
re->processed = 0;
+ re->add_turned_into_rename = 0;
re->pair = pair;
item = string_list_lookup(entries, re->pair->one->path);
if (!item)
@@ -1953,6 +2120,12 @@ static struct string_list *get_renames(struct merge_options *o,
re->dst_entry = item->util;
item = string_list_insert(renames, pair->one->path);
item->util = re;
+ if (new_path)
+ apply_directory_rename_modifications(o, pair, new_path,
+ re, tree, o_tree,
+ a_tree, b_tree,
+ entries,
+ clean_merge);
}
hashmap_iter_init(&collisions, &iter);
@@ -2122,7 +2295,19 @@ static int process_renames(struct merge_options *o,
dst_other.mode = ren1->dst_entry->stages[other_stage].mode;
try_merge = 0;
- if (oid_eq(&src_other.oid, &null_oid)) {
+ if (oid_eq(&src_other.oid, &null_oid) &&
+ ren1->add_turned_into_rename) {
+ setup_rename_conflict_info(RENAME_DIR,
+ ren1->pair,
+ NULL,
+ branch1,
+ branch2,
+ ren1->dst_entry,
+ NULL,
+ o,
+ NULL,
+ NULL);
+ } else if (oid_eq(&src_other.oid, &null_oid)) {
setup_rename_conflict_info(RENAME_DELETE,
ren1->pair,
NULL,
@@ -2546,6 +2731,14 @@ static int process_entry(struct merge_options *o,
o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
conflict_info);
break;
+ case RENAME_DIR:
+ clean_merge = 1;
+ if (conflict_rename_dir(o,
+ conflict_info->pair1,
+ conflict_info->branch1,
+ conflict_info->branch2))
+ clean_merge = -1;
+ break;
case RENAME_DELETE:
clean_merge = 0;
if (conflict_rename_delete(o,
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index 858d83016a..e737bad2c5 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -64,7 +64,7 @@ test_expect_success '1a-setup: Simple directory rename detection' '
git commit -m "C"
'
-test_expect_failure '1a-check: Simple directory rename detection' '
+test_expect_success '1a-check: Simple directory rename detection' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -121,7 +121,7 @@ test_expect_success '1b-setup: Merge a directory with another' '
git commit -m "C"
'
-test_expect_failure '1b-check: Merge a directory with another' '
+test_expect_success '1b-check: Merge a directory with another' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -173,7 +173,7 @@ test_expect_success '1c-setup: Transitive renaming' '
git commit -m "C"
'
-test_expect_failure '1c-check: Transitive renaming' '
+test_expect_success '1c-check: Transitive renaming' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -235,7 +235,7 @@ test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) con
git commit -m "C"
'
-test_expect_failure '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
+test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -302,7 +302,7 @@ test_expect_success '1e-setup: Renamed directory, with all files being renamed t
git commit -m "C"
'
-test_expect_failure '1e-check: Renamed directory, with all files being renamed too' '
+test_expect_success '1e-check: Renamed directory, with all files being renamed too' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -361,7 +361,7 @@ test_expect_success '1f-setup: Split a directory into two other directories' '
git commit -m "C"
'
-test_expect_failure '1f-check: Split a directory into two other directories' '
+test_expect_success '1f-check: Split a directory into two other directories' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -807,7 +807,7 @@ test_expect_success '5a-setup: Merge directories, other side adds files to origi
git commit -m "C"
'
-test_expect_failure '5a-check: Merge directories, other side adds files to original and target' '
+test_expect_success '5a-check: Merge directories, other side adds files to original and target' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -878,7 +878,7 @@ test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflic
git commit -m "C"
'
-test_expect_failure '5b-check: Rename/delete in order to get add/add/add conflict' '
+test_expect_success '5b-check: Rename/delete in order to get add/add/add conflict' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -951,7 +951,7 @@ test_expect_success '5c-setup: Transitive rename would cause rename/rename/renam
git commit -m "C"
'
-test_expect_failure '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
+test_expect_success '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1025,7 +1025,7 @@ test_expect_success '5d-setup: Directory/file/file conflict due to directory ren
git commit -m "C"
'
-test_expect_failure '5d-check: Directory/file/file conflict due to directory rename' '
+test_expect_success '5d-check: Directory/file/file conflict due to directory rename' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1403,7 +1403,7 @@ test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS
git commit -m "C"
'
-test_expect_failure '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1471,7 +1471,7 @@ test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive r
git commit -m "C"
'
-test_expect_failure '7b-check: rename/rename(2to1), but only due to transitive rename' '
+test_expect_success '7b-check: rename/rename(2to1), but only due to transitive rename' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1537,7 +1537,7 @@ test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may
git commit -m "C"
'
-test_expect_failure '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
+test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1595,7 +1595,7 @@ test_expect_success '7d-setup: transitive rename involved in rename/delete; how
git commit -m "C"
'
-test_expect_failure '7d-check: transitive rename involved in rename/delete; how is it reported?' '
+test_expect_success '7d-check: transitive rename involved in rename/delete; how is it reported?' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1664,7 +1664,7 @@ test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in th
git commit -m "C"
'
-test_expect_failure '7e-check: transitive rename in rename/delete AND dirs in the way' '
+test_expect_success '7e-check: transitive rename in rename/delete AND dirs in the way' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1748,7 +1748,7 @@ test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
git commit -m "C"
'
-test_expect_failure '8a-check: Dual-directory rename, one into the others way' '
+test_expect_success '8a-check: Dual-directory rename, one into the others way' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -1881,7 +1881,7 @@ test_expect_success '8c-setup: rename+modify/delete' '
git commit -m "C"
'
-test_expect_failure '8c-check: rename+modify/delete' '
+test_expect_success '8c-check: rename+modify/delete' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -1960,7 +1960,7 @@ test_expect_success '8d-setup: rename/delete...or not?' '
git commit -m "C"
'
-test_expect_failure '8d-check: rename/delete...or not?' '
+test_expect_success '8d-check: rename/delete...or not?' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -2026,7 +2026,7 @@ test_expect_success '8e-setup: Both sides rename, one side adds to original dire
git commit -m "C"
'
-test_expect_failure '8e-check: Both sides rename, one side adds to original directory' '
+test_expect_success '8e-check: Both sides rename, one side adds to original directory' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out 2>err &&
@@ -2111,7 +2111,7 @@ test_expect_success '9a-setup: Inner renamed directory within outer renamed dire
git commit -m "C"
'
-test_expect_failure '9a-check: Inner renamed directory within outer renamed directory' '
+test_expect_success '9a-check: Inner renamed directory within outer renamed directory' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -2171,7 +2171,7 @@ test_expect_success '9b-setup: Transitive rename with content merge' '
git commit -m "C"
'
-test_expect_failure '9b-check: Transitive rename with content merge' '
+test_expect_success '9b-check: Transitive rename with content merge' '
git checkout B^0 &&
git merge -s recursive C^0 &&
@@ -2254,7 +2254,7 @@ test_expect_success '9c-setup: Doubly transitive rename?' '
git commit -m "C"
'
-test_expect_failure '9c-check: Doubly transitive rename?' '
+test_expect_success '9c-check: Doubly transitive rename?' '
git checkout B^0 &&
git merge -s recursive C^0 >out &&
@@ -2337,7 +2337,7 @@ test_expect_success '9d-setup: N-way transitive rename?' '
git commit -m "C"
'
-test_expect_failure '9d-check: N-way transitive rename?' '
+test_expect_success '9d-check: N-way transitive rename?' '
git checkout B^0 &&
git merge -s recursive C^0 >out &&
@@ -2411,7 +2411,7 @@ test_expect_success '9e-setup: N-to-1 whammo' '
git commit -m "C"
'
-test_expect_failure '9e-check: N-to-1 whammo' '
+test_expect_success '9e-check: N-to-1 whammo' '
git checkout B^0 &&
test_must_fail git merge -s recursive C^0 >out &&
@@ -2482,7 +2482,7 @@ test_expect_success '9f-setup: Renamed directory that only contained immediate s
git commit -m "C"
'
-test_expect_failure '9f-check: Renamed directory that only contained immediate subdirs' '
+test_expect_success '9f-check: Renamed directory that only contained immediate subdirs' '
git checkout B^0 &&
git merge -s recursive C^0 &&
--
2.15.0.5.g9567be9905
next prev parent reply other threads:[~2017-11-10 19:07 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-10 19:05 [PATCH 00/30] Add directory rename detection to git Elijah Newren
2017-11-10 19:05 ` [PATCH 01/30] Tighten and correct a few testcases for merging and cherry-picking Elijah Newren
2017-11-13 19:32 ` Stefan Beller
2017-11-10 19:05 ` [PATCH 02/30] merge-recursive: Fix logic ordering issue Elijah Newren
2017-11-13 19:48 ` Stefan Beller
2017-11-13 22:04 ` Elijah Newren
2017-11-13 22:12 ` Stefan Beller
2017-11-13 23:39 ` Elijah Newren
2017-11-13 23:46 ` Stefan Beller
2017-11-10 19:05 ` [PATCH 03/30] merge-recursive: Add explanation for src_entry and dst_entry Elijah Newren
2017-11-13 21:06 ` Stefan Beller
2017-11-13 22:57 ` Elijah Newren
2017-11-13 23:11 ` Stefan Beller
2017-11-14 1:26 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 04/30] directory rename detection: basic testcases Elijah Newren
2017-11-13 22:04 ` Stefan Beller
2017-11-14 0:57 ` Elijah Newren
2017-11-14 1:21 ` Stefan Beller
2017-11-14 1:40 ` Elijah Newren
2017-11-14 2:03 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 05/30] directory rename detection: directory splitting testcases Elijah Newren
2017-11-13 23:20 ` Stefan Beller
2017-11-10 19:05 ` [PATCH 06/30] directory rename detection: testcases to avoid taking detection too far Elijah Newren
2017-11-13 23:25 ` Stefan Beller
2017-11-14 1:02 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 07/30] directory rename detection: partially renamed directory testcase/discussion Elijah Newren
2017-11-14 0:07 ` Stefan Beller
2017-11-10 19:05 ` [PATCH 08/30] directory rename detection: files/directories in the way of some renames Elijah Newren
2017-11-14 0:15 ` Stefan Beller
2017-11-14 1:19 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 09/30] directory rename detection: testcases checking which side did the rename Elijah Newren
2017-11-14 0:25 ` Stefan Beller
2017-11-14 1:30 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 10/30] directory rename detection: more involved edge/corner testcases Elijah Newren
2017-11-14 0:42 ` Stefan Beller
2017-11-14 21:11 ` Elijah Newren
2017-11-14 22:47 ` Stefan Beller
2017-11-10 19:05 ` [PATCH 11/30] directory rename detection: testcases exploring possibly suboptimal merges Elijah Newren
2017-11-14 20:33 ` Stefan Beller
2017-11-14 21:42 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 12/30] directory rename detection: miscellaneous testcases to complete coverage Elijah Newren
2017-11-15 20:03 ` Stefan Beller
2017-11-16 21:17 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 13/30] directory rename detection: tests for handling overwriting untracked files Elijah Newren
2017-11-10 19:05 ` [PATCH 14/30] directory rename detection: tests for handling overwriting dirty files Elijah Newren
2017-11-10 19:05 ` [PATCH 15/30] merge-recursive: Move the get_renames() function Elijah Newren
2017-11-14 4:46 ` Junio C Hamano
2017-11-14 17:41 ` Elijah Newren
2017-11-15 1:20 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 16/30] merge-recursive: Introduce new functions to handle rename logic Elijah Newren
2017-11-14 4:56 ` Junio C Hamano
2017-11-14 5:14 ` Junio C Hamano
2017-11-14 18:24 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 17/30] merge-recursive: Fix leaks of allocated renames and diff_filepairs Elijah Newren
2017-11-14 4:58 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 18/30] merge-recursive: Make !o->detect_rename codepath more obvious Elijah Newren
2017-11-10 19:05 ` [PATCH 19/30] merge-recursive: Split out code for determining diff_filepairs Elijah Newren
2017-11-14 5:20 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 20/30] merge-recursive: Add a new hashmap for storing directory renames Elijah Newren
2017-11-10 19:05 ` [PATCH 21/30] merge-recursive: Add get_directory_renames() Elijah Newren
2017-11-14 5:30 ` Junio C Hamano
2017-11-14 18:38 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 22/30] merge-recursive: Check for directory level conflicts Elijah Newren
2017-11-10 19:05 ` [PATCH 23/30] merge-recursive: Add a new hashmap for storing file collisions Elijah Newren
2017-11-10 19:05 ` [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging Elijah Newren
2018-06-10 10:56 ` René Scharfe
2018-06-10 11:03 ` René Scharfe
2018-06-10 20:44 ` Jeff King
2018-06-11 15:03 ` Elijah Newren
2018-06-14 17:36 ` Junio C Hamano
2017-11-10 19:05 ` [PATCH 25/30] merge-recursive: Check for file level conflicts then get new name Elijah Newren
2017-11-10 19:05 ` [PATCH 26/30] merge-recursive: When comparing files, don't include trees Elijah Newren
2017-11-10 19:05 ` Elijah Newren [this message]
2017-11-15 20:23 ` [PATCH 27/30] merge-recursive: Apply necessary modifications for directory renames Stefan Beller
2017-11-16 3:54 ` Elijah Newren
2017-11-10 19:05 ` [PATCH 28/30] merge-recursive: Avoid clobbering untracked files with " Elijah Newren
2017-11-10 19:05 ` [RFC PATCH 29/30] merge-recursive: Fix overwriting dirty files involved in renames Elijah Newren
2017-11-10 19:05 ` [PATCH 30/30] merge-recursive: Fix remaining directory rename + dirty overwrite cases Elijah Newren
2017-11-10 22:27 ` [PATCH 00/30] Add directory rename detection to git Philip Oakley
2017-11-10 23:26 ` Elijah Newren
2017-11-13 15:04 ` Philip Oakley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171110190550.27059-28-newren@gmail.com \
--to=newren@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).