merge-recursive.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 0c0d48624..ed2200065 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -815,6 +815,32 @@ static int make_room_for_path(struct merge_options *o, const char *path) return err(o, msg, path, _(": perhaps a D/F conflict?")); } +static int working_tree_matches(const char *path, const char *buf, unsigned long size, unsigned mode) +{ + int fd, matches; + struct stat st; + + fd = open(path, O_RDONLY); + if (fd < 0) + return 0; + matches = 0; + if (!fstat(fd, &st) && st.st_size == size && S_ISREG(st.st_mode) && !(0700 & (st.st_mode ^ mode))) { + char tmpbuf[1024]; + while (size) { + int n = read(fd, tmpbuf, sizeof(tmpbuf)); + if (n <= 0 || n > size) + break; + if (memcmp(tmpbuf, buf, n)) + break; + buf += n; + size -= n; + } + matches = !size; + } + close(fd); + return matches; +} + static int update_file_flags(struct merge_options *o, const struct object_id *oid, unsigned mode, @@ -856,6 +882,8 @@ static int update_file_flags(struct merge_options *o, size = strbuf.len; buf = strbuf_detach(&strbuf, NULL); } + if (working_tree_matches(path, buf, size, mode)) + goto free_buf; } if (make_room_for_path(o, path) < 0) { @@ -1782,20 +1810,8 @@ static int merge_content(struct merge_options *o, 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 - * already had. We can return early if those file contents - * 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) { - add_cacheinfo(o, mfi.mode, &mfi.oid, path, - 0, (!o->call_depth), 0); - return mfi.clean; - } + /* We could set a flag here and pass it to "update_file()" */ } else output(o, 2, _("Auto-merging %s"), path);