add = filespec_from_entry(&other, dst_entry, stage ^ 1);
if (add) {
+ int ren_src_was_dirty = was_dirty(o, rename->path);
char *add_name = unique_path(o, rename->path, other_branch);
if (update_file(o, 0, &add->oid, add->mode, add_name))
return -1;
- remove_file(o, 0, rename->path, 0);
+ if (ren_src_was_dirty) {
+ output(o, 1, _("Refusing to lose dirty file at %s"),
+ rename->path);
+ }
+ /*
+ * Because the double negatives somehow keep confusing me...
+ * 1) update_wd iff !ren_src_was_dirty.
+ * 2) no_wd iff !update_wd
+ * 3) so, no_wd == !!ren_src_was_dirty == ren_src_was_dirty
+ */
+ remove_file(o, 0, rename->path, ren_src_was_dirty);
dst_name = unique_path(o, rename->path, cur_branch);
} else {
if (dir_in_way(rename->path, !o->call_depth, 0)) {
char *new_path2 = unique_path(o, path, ci->branch2);
output(o, 1, _("Renaming %s to %s and %s to %s instead"),
a->path, new_path1, b->path, new_path2);
- if (would_lose_untracked(path))
+ if (was_dirty(o, path))
+ output(o, 1, _("Refusing to lose dirty file at %s"),
+ path);
+ else if (would_lose_untracked(path))
/*
* Only way we get here is if both renames were from
* a directory rename AND user had an untracked file
char *new_path;
struct diff_filepair *pair = pairs->queue[i];
- if (pair->status == 'D')
+ if (pair->status != 'A' && pair->status != 'R')
continue;
dir_rename_ent = check_dir_renamed(pair->two->path,
dir_renames);
{
struct string_list_item *item;
int stage = (tree == a_tree ? 2 : 3);
+ int update_wd;
/*
* In all cases where we can do directory rename detection,
* saying the file would have been overwritten), but it might
* be dirty, though.
*/
- remove_file(o, 1, pair->two->path, 0 /* no_wd */);
+ update_wd = !was_dirty(o, pair->two->path);
+ if (!update_wd)
+ output(o, 1, _("Refusing to lose dirty file at %s"),
+ pair->two->path);
+ remove_file(o, 1, pair->two->path, !update_wd);
/* Find or create a new re->dst_entry */
item = string_list_lookup(entries, new_path);
struct diff_filepair *pair = pairs->queue[i];
char *new_path; /* non-NULL only with directory renames */
- if (pair->status == 'D') {
+ if (pair->status != 'A' && pair->status != 'R') {
diff_free_filepair(pair);
continue;
}
if (mfi.clean && !df_conflict_remains &&
oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {
- int path_renamed_outside_HEAD;
output(o, 3, _("Skipped %s (merged same as existing)"), path);
/*
* The content merge resulted in the same file contents we
* are recorded at the correct path (which may not be true
* if the merge involves a rename).
*/
- path_renamed_outside_HEAD = !path2 || !strcmp(path, path2);
- if (!path_renamed_outside_HEAD) {
+ if (was_tracked(path)) {
add_cacheinfo(o, mfi.mode, &mfi.oid, path,
0, (!o->call_depth), 0);
return mfi.clean;