From patchwork Fri Apr 5 15:00:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A537F1515 for ; Fri, 5 Apr 2019 15:01:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8965D28B53 for ; Fri, 5 Apr 2019 15:01:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87E1128B70; Fri, 5 Apr 2019 15:01:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B6A9428B53 for ; Fri, 5 Apr 2019 15:01:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731392AbfDEPBO (ORCPT ); Fri, 5 Apr 2019 11:01:14 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45626 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730587AbfDEPA6 (ORCPT ); Fri, 5 Apr 2019 11:00:58 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFI001918; Fri, 5 Apr 2019 08:00:40 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:40 -0700 Received: from sj-prod-exch-02.YOJOE.local (10.129.18.29) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:42 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 08:00:42 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id EB4D4220B692; Fri, 5 Apr 2019 08:00:38 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 01/15] Use 'unsigned short' for mode, like diff_filespec does Date: Fri, 5 Apr 2019 08:00:12 -0700 Message-ID: <20190405150026.5260-2-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP struct diff_filespec defines mode to be an 'unsigned short'. Several other places in the API which we'd like to interact with using a diff_filespec used a plain unsigned (or unsigned int). This caused problems when taking addresses, so switch to unsigned short. Signed-off-by: Elijah Newren --- archive.c | 2 +- blame.c | 2 +- blame.h | 2 +- builtin/rm.c | 2 +- builtin/update-index.c | 2 +- cache.h | 2 +- fsck.c | 2 +- line-log.c | 2 +- match-trees.c | 8 ++++---- merge-recursive.c | 6 +++--- notes.c | 2 +- sha1-name.c | 2 +- tree-diff.c | 2 +- tree-walk.c | 6 +++--- tree-walk.h | 6 +++--- 15 files changed, 24 insertions(+), 24 deletions(-) diff --git a/archive.c b/archive.c index 1f98324a93..92bc001545 100644 --- a/archive.c +++ b/archive.c @@ -415,7 +415,7 @@ static void parse_treeish_arg(const char **argv, if (prefix) { struct object_id tree_oid; - unsigned int mode; + unsigned short mode; int err; err = get_tree_entry(&tree->object.oid, prefix, &tree_oid, diff --git a/blame.c b/blame.c index 5c07dec190..326231476e 100644 --- a/blame.c +++ b/blame.c @@ -99,7 +99,7 @@ static void verify_working_tree_path(struct repository *r, for (parents = work_tree->parents; parents; parents = parents->next) { const struct object_id *commit_oid = &parents->item->object.oid; struct object_id blob_oid; - unsigned mode; + unsigned short mode; if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) && oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB) diff --git a/blame.h b/blame.h index be3a895043..2a285eb027 100644 --- a/blame.h +++ b/blame.h @@ -52,7 +52,7 @@ struct blame_origin { struct blame_entry *suspects; mmfile_t file; struct object_id blob_oid; - unsigned mode; + unsigned short mode; /* guilty gets set when shipping any suspects to the final * blame list instead of other commits */ diff --git a/builtin/rm.c b/builtin/rm.c index db85b33982..90cbe896c9 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -110,7 +110,7 @@ static int check_local_mod(struct object_id *head, int index_only) const struct cache_entry *ce; const char *name = list.entry[i].name; struct object_id oid; - unsigned mode; + unsigned short mode; int local_changes = 0; int staged_changes = 0; diff --git a/builtin/update-index.c b/builtin/update-index.c index 1b6c42f748..0baf51c316 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -597,7 +597,7 @@ static struct cache_entry *read_one_ent(const char *which, struct object_id *ent, const char *path, int namelen, int stage) { - unsigned mode; + unsigned short mode; struct object_id oid; struct cache_entry *ce; diff --git a/cache.h b/cache.h index ac92421f3a..851c3e6945 100644 --- a/cache.h +++ b/cache.h @@ -1331,7 +1331,7 @@ static inline int hex2chr(const char *s) #define FALLBACK_DEFAULT_ABBREV 7 struct object_context { - unsigned mode; + unsigned short mode; /* * symlink_path is only used by get_tree_entry_follow_symlinks, * and only for symlinks that point outside the repository. diff --git a/fsck.c b/fsck.c index 2260adb71e..4703f55561 100644 --- a/fsck.c +++ b/fsck.c @@ -604,7 +604,7 @@ static int fsck_tree(struct tree *item, struct fsck_options *options) o_name = NULL; while (desc.size) { - unsigned mode; + unsigned short mode; const char *name; const struct object_id *oid; diff --git a/line-log.c b/line-log.c index 24e21731c4..f743592bc0 100644 --- a/line-log.c +++ b/line-log.c @@ -498,7 +498,7 @@ static struct commit *check_single_commit(struct rev_info *revs) static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec) { - unsigned mode; + unsigned short mode; struct object_id oid; if (get_tree_entry(&commit->object.oid, spec->path, &oid, &mode)) diff --git a/match-trees.c b/match-trees.c index ddc4d39845..9d1ec8d6b0 100644 --- a/match-trees.c +++ b/match-trees.c @@ -140,7 +140,7 @@ static void match_trees(const struct object_id *hash1, while (one.size) { const char *path; const struct object_id *elem; - unsigned mode; + unsigned short mode; int score; elem = tree_entry_extract(&one, &path, &mode); @@ -196,7 +196,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix, rewrite_here = NULL; while (desc.size) { const char *name; - unsigned mode; + unsigned short mode; tree_entry_extract(&desc, &name, &mode); if (strlen(name) == toplen && @@ -285,7 +285,7 @@ void shift_tree(const struct object_id *hash1, if (add_score < del_score) { /* We need to pick a subtree of two */ - unsigned mode; + unsigned short mode; if (!*del_prefix) return; @@ -313,7 +313,7 @@ void shift_tree_by(const struct object_id *hash1, const char *shift_prefix) { struct object_id sub1, sub2; - unsigned mode1, mode2; + unsigned short mode1, mode2; unsigned candidate = 0; /* Can hash2 be a tree at shift_prefix in tree hash1? */ diff --git a/merge-recursive.c b/merge-recursive.c index 6c40c61c47..fcf37be2a7 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -214,7 +214,7 @@ struct rename_conflict_info { */ struct stage_data { struct { - unsigned mode; + unsigned short mode; struct object_id oid; } stages[4]; struct rename_conflict_info *rename_conflict_info; @@ -482,7 +482,7 @@ static void get_files_dirs(struct merge_options *o, struct tree *tree) static int get_tree_entry_if_blob(const struct object_id *tree, const char *path, struct object_id *hashy, - unsigned int *mode_o) + unsigned short *mode_o) { int ret; @@ -1935,7 +1935,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o, static int tree_has_path(struct tree *tree, const char *path) { struct object_id hashy; - unsigned int mode_o; + unsigned short mode_o; return !get_tree_entry(&tree->object.oid, path, &hashy, &mode_o); diff --git a/notes.c b/notes.c index 7f7cc4d511..ba4cae7851 100644 --- a/notes.c +++ b/notes.c @@ -986,7 +986,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, combine_notes_fn combine_notes, int flags) { struct object_id oid, object_oid; - unsigned mode; + unsigned short mode; struct leaf_node root_tree; if (!t) diff --git a/sha1-name.c b/sha1-name.c index 6dda2c16df..d4b3d01f3c 100644 --- a/sha1-name.c +++ b/sha1-name.c @@ -1577,7 +1577,7 @@ static void diagnose_invalid_oid_path(const char *prefix, int object_name_len) { struct object_id oid; - unsigned mode; + unsigned short mode; if (!prefix) prefix = ""; diff --git a/tree-diff.c b/tree-diff.c index e6d306f69f..f1f641eb6a 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -181,7 +181,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, struct tree_desc *t, struct tree_desc *tp, int imin) { - unsigned mode; + unsigned short mode; const char *path; const struct object_id *oid; int pathlen; diff --git a/tree-walk.c b/tree-walk.c index 1e4bbc8a0e..ec32a47b2e 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -500,7 +500,7 @@ struct dir_state { struct object_id oid; }; -static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned *mode) +static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned short *mode) { int namelen = strlen(name); while (t->size) { @@ -535,7 +535,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_ return -1; } -int get_tree_entry(const struct object_id *tree_oid, const char *name, struct object_id *oid, unsigned *mode) +int get_tree_entry(const struct object_id *tree_oid, const char *name, struct object_id *oid, unsigned short *mode) { int retval; void *tree; @@ -585,7 +585,7 @@ int get_tree_entry(const struct object_id *tree_oid, const char *name, struct ob * See the code for enum get_oid_result for a description of * the return values. */ -enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode) +enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned short *mode) { int retval = MISSING_OBJECT; struct dir_state *parents = NULL; diff --git a/tree-walk.h b/tree-walk.h index 8225171866..3aa381b6a3 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -16,7 +16,7 @@ struct tree_desc { unsigned int size; }; -static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep) +static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned short *modep) { *pathp = desc->entry.path; *modep = desc->entry.mode; @@ -51,7 +51,7 @@ struct traverse_info; typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *); int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info); -enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode); +enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned short *mode); struct traverse_info { const char *traverse_path; @@ -66,7 +66,7 @@ struct traverse_info { int show_all_errors; }; -int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned *); +int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned short *); extern char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n); extern void setup_traverse_info(struct traverse_info *info, const char *base); From patchwork Fri Apr 5 15:00:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887573 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B1FE6139A for ; Fri, 5 Apr 2019 15:01:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C92B289B8 for ; Fri, 5 Apr 2019 15:01:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F96128B35; Fri, 5 Apr 2019 15:01:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1D0928B6E for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731385AbfDEPBM (ORCPT ); Fri, 5 Apr 2019 11:01:12 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40228 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731359AbfDEPBL (ORCPT ); Fri, 5 Apr 2019 11:01:11 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSns001751; Fri, 5 Apr 2019 08:00:42 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:41 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:39 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:39 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 0CBBF220CB17; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 02/15] merge-recursive: rename merge_options argument from 'o' to 'opt' Date: Fri, 5 Apr 2019 08:00:13 -0700 Message-ID: <20190405150026.5260-3-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=15 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The name 'o' was used for the merge_options struct pointer taken by many functions, but in a few places it was named 'opt'. Several functions that didn't need merge_options instead used 'o' for a diff_filespec argument or local. Some functions needed both an inconsistently either renamed the merge_options to 'opt' or the diff_filespec to 'one'. I want to remove the weird split in the codebase between using a diff_filespec and a pair of (oid,mode) values in favor of using a diff_filespec everywhere, but that dramatically increases the number of cases where we want to use 'o' as a diff_filespec. Rename the merge_options argument to 'opt' to make room. Signed-off-by: Elijah Newren --- merge-recursive.c | 984 +++++++++++++++++++++++----------------------- 1 file changed, 492 insertions(+), 492 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index fcf37be2a7..09b76d596e 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -115,32 +115,32 @@ static void collision_init(struct hashmap *map) hashmap_init(map, (hashmap_cmp_fn) collision_cmp, NULL, 0); } -static void flush_output(struct merge_options *o) +static void flush_output(struct merge_options *opt) { - if (o->buffer_output < 2 && o->obuf.len) { - fputs(o->obuf.buf, stdout); - strbuf_reset(&o->obuf); + if (opt->buffer_output < 2 && opt->obuf.len) { + fputs(opt->obuf.buf, stdout); + strbuf_reset(&opt->obuf); } } -static int err(struct merge_options *o, const char *err, ...) +static int err(struct merge_options *opt, const char *err, ...) { va_list params; - if (o->buffer_output < 2) - flush_output(o); + if (opt->buffer_output < 2) + flush_output(opt); else { - strbuf_complete(&o->obuf, '\n'); - strbuf_addstr(&o->obuf, "error: "); + strbuf_complete(&opt->obuf, '\n'); + strbuf_addstr(&opt->obuf, "error: "); } va_start(params, err); - strbuf_vaddf(&o->obuf, err, params); + strbuf_vaddf(&opt->obuf, err, params); va_end(params); - if (o->buffer_output > 1) - strbuf_addch(&o->obuf, '\n'); + if (opt->buffer_output > 1) + strbuf_addch(&opt->obuf, '\n'); else { - error("%s", o->obuf.buf); - strbuf_reset(&o->obuf); + error("%s", opt->obuf.buf); + strbuf_reset(&opt->obuf); } return -1; @@ -228,7 +228,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, const char *branch2, struct stage_data *dst_entry1, struct stage_data *dst_entry2, - struct merge_options *o, + struct merge_options *opt, struct stage_data *src_entry1, struct stage_data *src_entry2) { @@ -239,15 +239,15 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, * When we have two renames involved, it's easiest to get the * correct things into stage 2 and 3, and to make sure that the * content merge puts HEAD before the other branch if we just - * ensure that branch1 == o->branch1. So, simply flip arguments + * ensure that branch1 == opt->branch1. So, simply flip arguments * around if we don't have that. */ - if (dst_entry2 && branch1 != o->branch1) { + if (dst_entry2 && branch1 != opt->branch1) { setup_rename_conflict_info(rename_type, pair2, pair1, branch2, branch1, dst_entry2, dst_entry1, - o, + opt, src_entry2, src_entry1); return; } @@ -276,7 +276,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, */ if (rename_type == RENAME_ADD || rename_type == RENAME_TWO_FILES_TO_ONE) { - ostage1 = o->branch1 == branch1 ? 3 : 2; + ostage1 = opt->branch1 == branch1 ? 3 : 2; ci->ren1_other.path = pair1->one->path; oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid); @@ -292,67 +292,67 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, } } -static int show(struct merge_options *o, int v) +static int show(struct merge_options *opt, int v) { - return (!o->call_depth && o->verbosity >= v) || o->verbosity >= 5; + return (!opt->call_depth && opt->verbosity >= v) || opt->verbosity >= 5; } __attribute__((format (printf, 3, 4))) -static void output(struct merge_options *o, int v, const char *fmt, ...) +static void output(struct merge_options *opt, int v, const char *fmt, ...) { va_list ap; - if (!show(o, v)) + if (!show(opt, v)) return; - strbuf_addchars(&o->obuf, ' ', o->call_depth * 2); + strbuf_addchars(&opt->obuf, ' ', opt->call_depth * 2); va_start(ap, fmt); - strbuf_vaddf(&o->obuf, fmt, ap); + strbuf_vaddf(&opt->obuf, fmt, ap); va_end(ap); - strbuf_addch(&o->obuf, '\n'); - if (!o->buffer_output) - flush_output(o); + strbuf_addch(&opt->obuf, '\n'); + if (!opt->buffer_output) + flush_output(opt); } -static void output_commit_title(struct merge_options *o, struct commit *commit) +static void output_commit_title(struct merge_options *opt, struct commit *commit) { struct merge_remote_desc *desc; - strbuf_addchars(&o->obuf, ' ', o->call_depth * 2); + strbuf_addchars(&opt->obuf, ' ', opt->call_depth * 2); desc = merge_remote_util(commit); if (desc) - strbuf_addf(&o->obuf, "virtual %s\n", desc->name); + strbuf_addf(&opt->obuf, "virtual %s\n", desc->name); else { - strbuf_add_unique_abbrev(&o->obuf, &commit->object.oid, + strbuf_add_unique_abbrev(&opt->obuf, &commit->object.oid, DEFAULT_ABBREV); - strbuf_addch(&o->obuf, ' '); + strbuf_addch(&opt->obuf, ' '); if (parse_commit(commit) != 0) - strbuf_addstr(&o->obuf, _("(bad commit)\n")); + strbuf_addstr(&opt->obuf, _("(bad commit)\n")); else { const char *title; const char *msg = get_commit_buffer(commit, NULL); int len = find_commit_subject(msg, &title); if (len) - strbuf_addf(&o->obuf, "%.*s\n", len, title); + strbuf_addf(&opt->obuf, "%.*s\n", len, title); unuse_commit_buffer(commit, msg); } } - flush_output(o); + flush_output(opt); } -static int add_cacheinfo(struct merge_options *o, +static int add_cacheinfo(struct merge_options *opt, unsigned int mode, const struct object_id *oid, const char *path, int stage, int refresh, int options) { - struct index_state *istate = o->repo->index; + struct index_state *istate = opt->repo->index; struct cache_entry *ce; int ret; ce = make_cache_entry(istate, mode, oid ? oid : &null_oid, path, stage, 0); if (!ce) - return err(o, _("add_cacheinfo failed for path '%s'; merge aborting."), path); + return err(opt, _("add_cacheinfo failed for path '%s'; merge aborting."), path); ret = add_index_entry(istate, ce, options); if (refresh) { @@ -361,7 +361,7 @@ static int add_cacheinfo(struct merge_options *o, nce = refresh_cache_entry(istate, ce, CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING); if (!nce) - return err(o, _("add_cacheinfo failed to refresh for path '%s'; merge aborting."), path); + return err(opt, _("add_cacheinfo failed to refresh for path '%s'; merge aborting."), path); if (nce != ce) ret = add_index_entry(istate, nce, options); } @@ -374,7 +374,7 @@ static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree) init_tree_desc(desc, tree->buffer, tree->size); } -static int unpack_trees_start(struct merge_options *o, +static int unpack_trees_start(struct merge_options *opt, struct tree *common, struct tree *head, struct tree *merge) @@ -383,49 +383,49 @@ static int unpack_trees_start(struct merge_options *o, struct tree_desc t[3]; struct index_state tmp_index = { NULL }; - memset(&o->unpack_opts, 0, sizeof(o->unpack_opts)); - if (o->call_depth) - o->unpack_opts.index_only = 1; + memset(&opt->unpack_opts, 0, sizeof(opt->unpack_opts)); + if (opt->call_depth) + opt->unpack_opts.index_only = 1; else - o->unpack_opts.update = 1; - o->unpack_opts.merge = 1; - o->unpack_opts.head_idx = 2; - o->unpack_opts.fn = threeway_merge; - o->unpack_opts.src_index = o->repo->index; - o->unpack_opts.dst_index = &tmp_index; - o->unpack_opts.aggressive = !merge_detect_rename(o); - setup_unpack_trees_porcelain(&o->unpack_opts, "merge"); + opt->unpack_opts.update = 1; + opt->unpack_opts.merge = 1; + opt->unpack_opts.head_idx = 2; + opt->unpack_opts.fn = threeway_merge; + opt->unpack_opts.src_index = opt->repo->index; + opt->unpack_opts.dst_index = &tmp_index; + opt->unpack_opts.aggressive = !merge_detect_rename(opt); + setup_unpack_trees_porcelain(&opt->unpack_opts, "merge"); init_tree_desc_from_tree(t+0, common); init_tree_desc_from_tree(t+1, head); init_tree_desc_from_tree(t+2, merge); - rc = unpack_trees(3, t, &o->unpack_opts); - cache_tree_free(&o->repo->index->cache_tree); + rc = unpack_trees(3, t, &opt->unpack_opts); + cache_tree_free(&opt->repo->index->cache_tree); /* - * Update o->repo->index to match the new results, AFTER saving a copy - * in o->orig_index. Update src_index to point to the saved copy. + * Update opt->repo->index to match the new results, AFTER saving a copy + * in opt->orig_index. Update src_index to point to the saved copy. * (verify_uptodate() checks src_index, and the original index is * the one that had the necessary modification timestamps.) */ - o->orig_index = *o->repo->index; - *o->repo->index = tmp_index; - o->unpack_opts.src_index = &o->orig_index; + opt->orig_index = *opt->repo->index; + *opt->repo->index = tmp_index; + opt->unpack_opts.src_index = &opt->orig_index; return rc; } -static void unpack_trees_finish(struct merge_options *o) +static void unpack_trees_finish(struct merge_options *opt) { - discard_index(&o->orig_index); - clear_unpack_trees_porcelain(&o->unpack_opts); + discard_index(&opt->orig_index); + clear_unpack_trees_porcelain(&opt->unpack_opts); } -struct tree *write_tree_from_memory(struct merge_options *o) +struct tree *write_tree_from_memory(struct merge_options *opt) { struct tree *result = NULL; - struct index_state *istate = o->repo->index; + struct index_state *istate = opt->repo->index; if (unmerged_index(istate)) { int i; @@ -444,11 +444,11 @@ struct tree *write_tree_from_memory(struct merge_options *o) if (!cache_tree_fully_valid(istate->cache_tree) && cache_tree_update(istate, 0) < 0) { - err(o, _("error building trees")); + err(opt, _("error building trees")); return NULL; } - result = lookup_tree(o->repo, &istate->cache_tree->oid); + result = lookup_tree(opt->repo, &istate->cache_tree->oid); return result; } @@ -459,24 +459,24 @@ static int save_files_dirs(const struct object_id *oid, { struct path_hashmap_entry *entry; int baselen = base->len; - struct merge_options *o = context; + struct merge_options *opt = context; strbuf_addstr(base, path); FLEX_ALLOC_MEM(entry, path, base->buf, base->len); hashmap_entry_init(entry, path_hash(entry->path)); - hashmap_add(&o->current_file_dir_set, entry); + hashmap_add(&opt->current_file_dir_set, entry); strbuf_setlen(base, baselen); return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0); } -static void get_files_dirs(struct merge_options *o, struct tree *tree) +static void get_files_dirs(struct merge_options *opt, struct tree *tree) { struct pathspec match_all; memset(&match_all, 0, sizeof(match_all)); read_tree_recursive(the_repository, tree, "", 0, 0, - &match_all, save_files_dirs, o); + &match_all, save_files_dirs, opt); } static int get_tree_entry_if_blob(const struct object_id *tree, @@ -573,7 +573,7 @@ static int string_list_df_name_compare(const char *one, const char *two) return onelen - twolen; } -static void record_df_conflict_files(struct merge_options *o, +static void record_df_conflict_files(struct merge_options *opt, struct string_list *entries) { /* If there is a D/F conflict and the file for such a conflict @@ -598,7 +598,7 @@ static void record_df_conflict_files(struct merge_options *o, * If we're merging merge-bases, we don't want to bother with * any working directory changes. */ - if (o->call_depth) + if (opt->call_depth) return; /* Ensure D/F conflicts are adjacent in the entries list. */ @@ -610,7 +610,7 @@ static void record_df_conflict_files(struct merge_options *o, df_sorted_entries.cmp = string_list_df_name_compare; string_list_sort(&df_sorted_entries); - string_list_clear(&o->df_conflict_file_set, 1); + string_list_clear(&opt->df_conflict_file_set, 1); for (i = 0; i < df_sorted_entries.nr; i++) { const char *path = df_sorted_entries.items[i].string; int len = strlen(path); @@ -626,7 +626,7 @@ static void record_df_conflict_files(struct merge_options *o, len > last_len && memcmp(path, last_file, last_len) == 0 && path[last_len] == '/') { - string_list_insert(&o->df_conflict_file_set, last_file); + string_list_insert(&opt->df_conflict_file_set, last_file); } /* @@ -717,20 +717,20 @@ static void update_entry(struct stage_data *entry, oidcpy(&entry->stages[3].oid, &b->oid); } -static int remove_file(struct merge_options *o, int clean, +static int remove_file(struct merge_options *opt, int clean, const char *path, int no_wd) { - int update_cache = o->call_depth || clean; - int update_working_directory = !o->call_depth && !no_wd; + int update_cache = opt->call_depth || clean; + int update_working_directory = !opt->call_depth && !no_wd; if (update_cache) { - if (remove_file_from_index(o->repo->index, path)) + if (remove_file_from_index(opt->repo->index, path)) return -1; } if (update_working_directory) { if (ignore_case) { struct cache_entry *ce; - ce = index_file_exists(o->repo->index, path, strlen(path), + ce = index_file_exists(opt->repo->index, path, strlen(path), ignore_case); if (ce && ce_stage(ce) == 0 && strcmp(path, ce->name)) return 0; @@ -751,7 +751,7 @@ static void add_flattened_path(struct strbuf *out, const char *s) out->buf[i] = '_'; } -static char *unique_path(struct merge_options *o, const char *path, const char *branch) +static char *unique_path(struct merge_options *opt, const char *path, const char *branch) { struct path_hashmap_entry *entry; struct strbuf newpath = STRBUF_INIT; @@ -762,16 +762,16 @@ static char *unique_path(struct merge_options *o, const char *path, const char * add_flattened_path(&newpath, branch); base_len = newpath.len; - while (hashmap_get_from_hash(&o->current_file_dir_set, + while (hashmap_get_from_hash(&opt->current_file_dir_set, path_hash(newpath.buf), newpath.buf) || - (!o->call_depth && file_exists(newpath.buf))) { + (!opt->call_depth && file_exists(newpath.buf))) { strbuf_setlen(&newpath, base_len); strbuf_addf(&newpath, "_%d", suffix++); } FLEX_ALLOC_MEM(entry, path, newpath.buf, newpath.len); hashmap_entry_init(entry, path_hash(entry->path)); - hashmap_add(&o->current_file_dir_set, entry); + hashmap_add(&opt->current_file_dir_set, entry); return strbuf_detach(&newpath, NULL); } @@ -810,10 +810,10 @@ static int dir_in_way(struct index_state *istate, const char *path, * Returns whether path was tracked in the index before the merge started, * and its oid and mode match the specified values */ -static int was_tracked_and_matches(struct merge_options *o, const char *path, +static int was_tracked_and_matches(struct merge_options *opt, const char *path, const struct object_id *oid, unsigned mode) { - int pos = index_name_pos(&o->orig_index, path, strlen(path)); + int pos = index_name_pos(&opt->orig_index, path, strlen(path)); struct cache_entry *ce; if (0 > pos) @@ -821,16 +821,16 @@ static int was_tracked_and_matches(struct merge_options *o, const char *path, return 0; /* See if the file we were tracking before matches */ - ce = o->orig_index.cache[pos]; + ce = opt->orig_index.cache[pos]; return (oid_eq(&ce->oid, oid) && ce->ce_mode == mode); } /* * Returns whether path was tracked in the index before the merge started */ -static int was_tracked(struct merge_options *o, const char *path) +static int was_tracked(struct merge_options *opt, const char *path) { - int pos = index_name_pos(&o->orig_index, path, strlen(path)); + int pos = index_name_pos(&opt->orig_index, path, strlen(path)); if (0 <= pos) /* we were tracking this path before the merge */ @@ -839,13 +839,13 @@ static int was_tracked(struct merge_options *o, const char *path) return 0; } -static int would_lose_untracked(struct merge_options *o, const char *path) +static int would_lose_untracked(struct merge_options *opt, const char *path) { - struct index_state *istate = o->repo->index; + struct index_state *istate = opt->repo->index; /* * This may look like it can be simplified to: - * return !was_tracked(o, path) && file_exists(path) + * return !was_tracked(opt, path) && file_exists(path) * but it can't. This function needs to know whether path was in * the working tree due to EITHER having been tracked in the index * before the merge OR having been put into the working copy and @@ -882,38 +882,38 @@ static int would_lose_untracked(struct merge_options *o, const char *path) return file_exists(path); } -static int was_dirty(struct merge_options *o, const char *path) +static int was_dirty(struct merge_options *opt, const char *path) { struct cache_entry *ce; int dirty = 1; - if (o->call_depth || !was_tracked(o, path)) + if (opt->call_depth || !was_tracked(opt, path)) return !dirty; - ce = index_file_exists(o->unpack_opts.src_index, + ce = index_file_exists(opt->unpack_opts.src_index, path, strlen(path), ignore_case); - dirty = verify_uptodate(ce, &o->unpack_opts) != 0; + dirty = verify_uptodate(ce, &opt->unpack_opts) != 0; return dirty; } -static int make_room_for_path(struct merge_options *o, const char *path) +static int make_room_for_path(struct merge_options *opt, const char *path) { int status, i; const char *msg = _("failed to create path '%s'%s"); /* Unlink any D/F conflict files that are in the way */ - for (i = 0; i < o->df_conflict_file_set.nr; i++) { - const char *df_path = o->df_conflict_file_set.items[i].string; + for (i = 0; i < opt->df_conflict_file_set.nr; i++) { + const char *df_path = opt->df_conflict_file_set.items[i].string; size_t pathlen = strlen(path); size_t df_pathlen = strlen(df_path); if (df_pathlen < pathlen && path[df_pathlen] == '/' && strncmp(path, df_path, df_pathlen) == 0) { - output(o, 3, + output(opt, 3, _("Removing %s to make room for subdirectory\n"), df_path); unlink(df_path); - unsorted_string_list_delete_item(&o->df_conflict_file_set, + unsorted_string_list_delete_item(&opt->df_conflict_file_set, i, 0); break; } @@ -924,16 +924,16 @@ static int make_room_for_path(struct merge_options *o, const char *path) if (status) { if (status == SCLD_EXISTS) /* something else exists */ - return err(o, msg, path, _(": perhaps a D/F conflict?")); - return err(o, msg, path, ""); + return err(opt, msg, path, _(": perhaps a D/F conflict?")); + return err(opt, msg, path, ""); } /* * Do not unlink a file in the work tree if we are not * tracking it. */ - if (would_lose_untracked(o, path)) - return err(o, _("refusing to lose untracked file at '%s'"), + if (would_lose_untracked(opt, path)) + return err(opt, _("refusing to lose untracked file at '%s'"), path); /* Successful unlink is good.. */ @@ -943,10 +943,10 @@ static int make_room_for_path(struct merge_options *o, const char *path) if (errno == ENOENT) return 0; /* .. but not some other error (who really cares what?) */ - return err(o, msg, path, _(": perhaps a D/F conflict?")); + return err(opt, msg, path, _(": perhaps a D/F conflict?")); } -static int update_file_flags(struct merge_options *o, +static int update_file_flags(struct merge_options *opt, const struct object_id *oid, unsigned mode, const char *path, @@ -955,7 +955,7 @@ static int update_file_flags(struct merge_options *o, { int ret = 0; - if (o->call_depth) + if (opt->call_depth) update_wd = 0; if (update_wd) { @@ -975,21 +975,21 @@ static int update_file_flags(struct merge_options *o, buf = read_object_file(oid, &type, &size); if (!buf) - return err(o, _("cannot read object %s '%s'"), oid_to_hex(oid), path); + return err(opt, _("cannot read object %s '%s'"), oid_to_hex(oid), path); if (type != OBJ_BLOB) { - ret = err(o, _("blob expected for %s '%s'"), oid_to_hex(oid), path); + ret = err(opt, _("blob expected for %s '%s'"), oid_to_hex(oid), path); goto free_buf; } if (S_ISREG(mode)) { struct strbuf strbuf = STRBUF_INIT; - if (convert_to_working_tree(o->repo->index, path, buf, size, &strbuf)) { + if (convert_to_working_tree(opt->repo->index, path, buf, size, &strbuf)) { free(buf); size = strbuf.len; buf = strbuf_detach(&strbuf, NULL); } } - if (make_room_for_path(o, path) < 0) { + if (make_room_for_path(opt, path) < 0) { update_wd = 0; goto free_buf; } @@ -1001,7 +1001,7 @@ static int update_file_flags(struct merge_options *o, mode = 0666; fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode); if (fd < 0) { - ret = err(o, _("failed to open '%s': %s"), + ret = err(opt, _("failed to open '%s': %s"), path, strerror(errno)); goto free_buf; } @@ -1012,11 +1012,11 @@ static int update_file_flags(struct merge_options *o, safe_create_leading_directories_const(path); unlink(path); if (symlink(lnk, path)) - ret = err(o, _("failed to symlink '%s': %s"), + ret = err(opt, _("failed to symlink '%s': %s"), path, strerror(errno)); free(lnk); } else - ret = err(o, + ret = err(opt, _("do not know what to do with %06o %s '%s'"), mode, oid_to_hex(oid), path); free_buf: @@ -1024,19 +1024,19 @@ static int update_file_flags(struct merge_options *o, } update_index: if (!ret && update_cache) - if (add_cacheinfo(o, mode, oid, path, 0, update_wd, + if (add_cacheinfo(opt, mode, oid, path, 0, update_wd, ADD_CACHE_OK_TO_ADD)) return -1; return ret; } -static int update_file(struct merge_options *o, +static int update_file(struct merge_options *opt, int clean, const struct object_id *oid, unsigned mode, const char *path) { - return update_file_flags(o, oid, mode, path, o->call_depth || clean, !o->call_depth); + return update_file_flags(opt, oid, mode, path, opt->call_depth || clean, !opt->call_depth); } /* Low level file merging, update and removal */ @@ -1048,7 +1048,7 @@ struct merge_file_info { merge:1; }; -static int merge_3way(struct merge_options *o, +static int merge_3way(struct merge_options *opt, mmbuffer_t *result_buf, const struct diff_filespec *one, const struct diff_filespec *a, @@ -1062,15 +1062,15 @@ static int merge_3way(struct merge_options *o, char *base_name, *name1, *name2; int merge_status; - ll_opts.renormalize = o->renormalize; + ll_opts.renormalize = opt->renormalize; ll_opts.extra_marker_size = extra_marker_size; - ll_opts.xdl_opts = o->xdl_opts; + ll_opts.xdl_opts = opt->xdl_opts; - if (o->call_depth) { + if (opt->call_depth) { ll_opts.virtual_ancestor = 1; ll_opts.variant = 0; } else { - switch (o->recursive_variant) { + switch (opt->recursive_variant) { case MERGE_RECURSIVE_OURS: ll_opts.variant = XDL_MERGE_FAVOR_OURS; break; @@ -1084,14 +1084,14 @@ static int merge_3way(struct merge_options *o, } if (strcmp(a->path, b->path) || - (o->ancestor != NULL && strcmp(a->path, one->path) != 0)) { - base_name = o->ancestor == NULL ? NULL : - mkpathdup("%s:%s", o->ancestor, one->path); + (opt->ancestor != NULL && strcmp(a->path, one->path) != 0)) { + base_name = opt->ancestor == NULL ? NULL : + mkpathdup("%s:%s", opt->ancestor, one->path); name1 = mkpathdup("%s:%s", branch1, a->path); name2 = mkpathdup("%s:%s", branch2, b->path); } else { - base_name = o->ancestor == NULL ? NULL : - mkpathdup("%s", o->ancestor); + base_name = opt->ancestor == NULL ? NULL : + mkpathdup("%s", opt->ancestor); name1 = mkpathdup("%s", branch1); name2 = mkpathdup("%s", branch2); } @@ -1102,7 +1102,7 @@ static int merge_3way(struct merge_options *o, merge_status = ll_merge(result_buf, a->path, &orig, base_name, &src1, name1, &src2, name2, - o->repo->index, &ll_opts); + opt->repo->index, &ll_opts); free(base_name); free(name1); @@ -1184,7 +1184,7 @@ static void print_commit(struct commit *commit) strbuf_release(&sb); } -static int merge_submodule(struct merge_options *o, +static int merge_submodule(struct merge_options *opt, struct object_id *result, const char *path, const struct object_id *base, const struct object_id *a, const struct object_id *b) @@ -1194,7 +1194,7 @@ static int merge_submodule(struct merge_options *o, struct object_array merges; int i; - int search = !o->call_depth; + int search = !opt->call_depth; /* store a in result in case we fail */ oidcpy(result, a); @@ -1208,32 +1208,32 @@ static int merge_submodule(struct merge_options *o, return 0; if (add_submodule_odb(path)) { - output(o, 1, _("Failed to merge submodule %s (not checked out)"), path); + output(opt, 1, _("Failed to merge submodule %s (not checked out)"), path); return 0; } - if (!(commit_base = lookup_commit_reference(o->repo, base)) || - !(commit_a = lookup_commit_reference(o->repo, a)) || - !(commit_b = lookup_commit_reference(o->repo, b))) { - output(o, 1, _("Failed to merge submodule %s (commits not present)"), path); + if (!(commit_base = lookup_commit_reference(opt->repo, base)) || + !(commit_a = lookup_commit_reference(opt->repo, a)) || + !(commit_b = lookup_commit_reference(opt->repo, b))) { + output(opt, 1, _("Failed to merge submodule %s (commits not present)"), path); return 0; } /* check whether both changes are forward */ if (!in_merge_bases(commit_base, commit_a) || !in_merge_bases(commit_base, commit_b)) { - output(o, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path); + output(opt, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path); return 0; } /* Case #1: a is contained in b or vice versa */ if (in_merge_bases(commit_a, commit_b)) { oidcpy(result, b); - if (show(o, 3)) { - output(o, 3, _("Fast-forwarding submodule %s to the following commit:"), path); - output_commit_title(o, commit_b); - } else if (show(o, 2)) - output(o, 2, _("Fast-forwarding submodule %s"), path); + if (show(opt, 3)) { + output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); + output_commit_title(opt, commit_b); + } else if (show(opt, 2)) + output(opt, 2, _("Fast-forwarding submodule %s"), path); else ; /* no output */ @@ -1241,11 +1241,11 @@ static int merge_submodule(struct merge_options *o, } if (in_merge_bases(commit_b, commit_a)) { oidcpy(result, a); - if (show(o, 3)) { - output(o, 3, _("Fast-forwarding submodule %s to the following commit:"), path); - output_commit_title(o, commit_a); - } else if (show(o, 2)) - output(o, 2, _("Fast-forwarding submodule %s"), path); + if (show(opt, 3)) { + output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); + output_commit_title(opt, commit_a); + } else if (show(opt, 2)) + output(opt, 2, _("Fast-forwarding submodule %s"), path); else ; /* no output */ @@ -1264,18 +1264,18 @@ static int merge_submodule(struct merge_options *o, return 0; /* find commit which merges them */ - parent_count = find_first_merges(o->repo, &merges, path, + parent_count = find_first_merges(opt->repo, &merges, path, commit_a, commit_b); switch (parent_count) { case 0: - output(o, 1, _("Failed to merge submodule %s (merge following commits not found)"), path); + output(opt, 1, _("Failed to merge submodule %s (merge following commits not found)"), path); break; case 1: - output(o, 1, _("Failed to merge submodule %s (not fast-forward)"), path); - output(o, 2, _("Found a possible merge resolution for the submodule:\n")); + output(opt, 1, _("Failed to merge submodule %s (not fast-forward)"), path); + output(opt, 2, _("Found a possible merge resolution for the submodule:\n")); print_commit((struct commit *) merges.objects[0].item); - output(o, 2, _( + output(opt, 2, _( "If this is correct simply add it to the index " "for example\n" "by using:\n\n" @@ -1285,7 +1285,7 @@ static int merge_submodule(struct merge_options *o, break; default: - output(o, 1, _("Failed to merge submodule %s (multiple merges found)"), path); + output(opt, 1, _("Failed to merge submodule %s (multiple merges found)"), path); for (i = 0; i < merges.nr; i++) print_commit((struct commit *) merges.objects[i].item); } @@ -1294,7 +1294,7 @@ static int merge_submodule(struct merge_options *o, return 0; } -static int merge_mode_and_contents(struct merge_options *o, +static int merge_mode_and_contents(struct merge_options *opt, const struct diff_filespec *one, const struct diff_filespec *a, const struct diff_filespec *b, @@ -1304,13 +1304,13 @@ static int merge_mode_and_contents(struct merge_options *o, const int extra_marker_size, struct merge_file_info *result) { - if (o->branch1 != branch1) { + if (opt->branch1 != branch1) { /* * It's weird getting a reverse merge with HEAD on the bottom * side of the conflict markers and the other branch on the * top. Fix that. */ - return merge_mode_and_contents(o, one, b, a, + return merge_mode_and_contents(opt, one, b, a, filename, branch2, branch1, extra_marker_size, result); @@ -1353,17 +1353,17 @@ static int merge_mode_and_contents(struct merge_options *o, mmbuffer_t result_buf; int ret = 0, merge_status; - merge_status = merge_3way(o, &result_buf, one, a, b, + merge_status = merge_3way(opt, &result_buf, one, a, b, branch1, branch2, extra_marker_size); if ((merge_status < 0) || !result_buf.ptr) - ret = err(o, _("Failed to execute internal merge")); + ret = err(opt, _("Failed to execute internal merge")); if (!ret && write_object_file(result_buf.ptr, result_buf.size, blob_type, &result->oid)) - ret = err(o, _("Unable to add %s to database"), + ret = err(opt, _("Unable to add %s to database"), a->path); free(result_buf.ptr); @@ -1371,13 +1371,13 @@ static int merge_mode_and_contents(struct merge_options *o, return ret; result->clean = (merge_status == 0); } else if (S_ISGITLINK(a->mode)) { - result->clean = merge_submodule(o, &result->oid, + result->clean = merge_submodule(opt, &result->oid, one->path, &one->oid, &a->oid, &b->oid); } else if (S_ISLNK(a->mode)) { - switch (o->recursive_variant) { + switch (opt->recursive_variant) { case MERGE_RECURSIVE_NORMAL: oidcpy(&result->oid, &a->oid); if (!oid_eq(&a->oid, &b->oid)) @@ -1395,12 +1395,12 @@ static int merge_mode_and_contents(struct merge_options *o, } if (result->merge) - output(o, 2, _("Auto-merging %s"), filename); + output(opt, 2, _("Auto-merging %s"), filename); return 0; } -static int handle_rename_via_dir(struct merge_options *o, +static int handle_rename_via_dir(struct merge_options *opt, struct diff_filepair *pair, const char *rename_branch) { @@ -1412,10 +1412,10 @@ static int handle_rename_via_dir(struct merge_options *o, */ const struct diff_filespec *dest = pair->two; - if (!o->call_depth && would_lose_untracked(o, dest->path)) { - char *alt_path = unique_path(o, dest->path, rename_branch); + if (!opt->call_depth && would_lose_untracked(opt, dest->path)) { + char *alt_path = unique_path(opt, dest->path, rename_branch); - output(o, 1, _("Error: Refusing to lose untracked file at %s; " + output(opt, 1, _("Error: Refusing to lose untracked file at %s; " "writing to %s instead."), dest->path, alt_path); /* @@ -1423,21 +1423,21 @@ static int handle_rename_via_dir(struct merge_options *o, * index. Instead, write to dest->path for the index but * only at the higher appropriate stage. */ - if (update_file(o, 0, &dest->oid, dest->mode, alt_path)) + if (update_file(opt, 0, &dest->oid, dest->mode, alt_path)) return -1; free(alt_path); - return update_stages(o, dest->path, NULL, - rename_branch == o->branch1 ? dest : NULL, - rename_branch == o->branch1 ? NULL : dest); + return update_stages(opt, dest->path, NULL, + rename_branch == opt->branch1 ? dest : NULL, + rename_branch == opt->branch1 ? NULL : dest); } /* Update dest->path both in index and in worktree */ - if (update_file(o, 1, &dest->oid, dest->mode, dest->path)) + if (update_file(opt, 1, &dest->oid, dest->mode, dest->path)) return -1; return 0; } -static int handle_change_delete(struct merge_options *o, +static int handle_change_delete(struct merge_options *opt, const char *path, const char *old_path, const struct object_id *o_oid, int o_mode, const struct object_id *changed_oid, @@ -1450,20 +1450,20 @@ static int handle_change_delete(struct merge_options *o, const char *update_path = path; int ret = 0; - if (dir_in_way(o->repo->index, path, !o->call_depth, 0) || - (!o->call_depth && would_lose_untracked(o, path))) { - update_path = alt_path = unique_path(o, path, change_branch); + if (dir_in_way(opt->repo->index, path, !opt->call_depth, 0) || + (!opt->call_depth && would_lose_untracked(opt, path))) { + update_path = alt_path = unique_path(opt, path, change_branch); } - if (o->call_depth) { + if (opt->call_depth) { /* * We cannot arbitrarily accept either a_sha or b_sha as * correct; since there is no true "middle point" between * them, simply reuse the base version for virtual merge base. */ - ret = remove_file_from_index(o->repo->index, path); + ret = remove_file_from_index(opt->repo->index, path); if (!ret) - ret = update_file(o, 0, o_oid, o_mode, update_path); + ret = update_file(opt, 0, o_oid, o_mode, update_path); } else { /* * Despite the four nearly duplicate messages and argument @@ -1482,24 +1482,24 @@ static int handle_change_delete(struct merge_options *o, */ if (!alt_path) { if (!old_path) { - output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + output(opt, 1, _("CONFLICT (%s/delete): %s deleted in %s " "and %s in %s. Version %s of %s left in tree."), change, path, delete_branch, change_past, change_branch, change_branch, path); } else { - output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + output(opt, 1, _("CONFLICT (%s/delete): %s deleted in %s " "and %s to %s in %s. Version %s of %s left in tree."), change, old_path, delete_branch, change_past, path, change_branch, change_branch, path); } } else { if (!old_path) { - output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + output(opt, 1, _("CONFLICT (%s/delete): %s deleted in %s " "and %s in %s. Version %s of %s left in tree at %s."), change, path, delete_branch, change_past, change_branch, change_branch, path, alt_path); } else { - output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + output(opt, 1, _("CONFLICT (%s/delete): %s deleted in %s " "and %s to %s in %s. Version %s of %s left in tree at %s."), change, old_path, delete_branch, change_past, path, change_branch, change_branch, path, alt_path); @@ -1507,19 +1507,19 @@ static int handle_change_delete(struct merge_options *o, } /* * No need to call update_file() on path when change_branch == - * o->branch1 && !alt_path, since that would needlessly touch + * opt->branch1 && !alt_path, since that would needlessly touch * path. We could call update_file_flags() with update_cache=0 * and update_wd=0, but that's a no-op. */ - if (change_branch != o->branch1 || alt_path) - ret = update_file(o, 0, changed_oid, changed_mode, update_path); + if (change_branch != opt->branch1 || alt_path) + ret = update_file(opt, 0, changed_oid, changed_mode, update_path); } free(alt_path); return ret; } -static int handle_rename_delete(struct merge_options *o, +static int handle_rename_delete(struct merge_options *opt, struct diff_filepair *pair, const char *rename_branch, const char *delete_branch) @@ -1527,21 +1527,21 @@ static int handle_rename_delete(struct merge_options *o, const struct diff_filespec *orig = pair->one; const struct diff_filespec *dest = pair->two; - if (handle_change_delete(o, - o->call_depth ? orig->path : dest->path, - o->call_depth ? NULL : orig->path, + if (handle_change_delete(opt, + opt->call_depth ? orig->path : dest->path, + opt->call_depth ? NULL : orig->path, &orig->oid, orig->mode, &dest->oid, dest->mode, rename_branch, delete_branch, _("rename"), _("renamed"))) return -1; - if (o->call_depth) - return remove_file_from_index(o->repo->index, dest->path); + if (opt->call_depth) + return remove_file_from_index(opt->repo->index, dest->path); else - return update_stages(o, dest->path, NULL, - rename_branch == o->branch1 ? dest : NULL, - rename_branch == o->branch1 ? NULL : dest); + return update_stages(opt, dest->path, NULL, + rename_branch == opt->branch1 ? dest : NULL, + rename_branch == opt->branch1 ? NULL : dest); } static struct diff_filespec *filespec_from_entry(struct diff_filespec *target, @@ -1557,7 +1557,7 @@ static struct diff_filespec *filespec_from_entry(struct diff_filespec *target, return target; } -static int handle_file_collision(struct merge_options *o, +static int handle_file_collision(struct merge_options *opt, const char *collide_path, const char *prev_path1, const char *prev_path2, @@ -1575,11 +1575,11 @@ static int handle_file_collision(struct merge_options *o, /* * It's easiest to get the correct things into stage 2 and 3, and * to make sure that the content merge puts HEAD before the other - * branch if we just ensure that branch1 == o->branch1. So, simply + * branch if we just ensure that branch1 == opt->branch1. So, simply * flip arguments around if we don't have that. */ - if (branch1 != o->branch1) { - return handle_file_collision(o, collide_path, + if (branch1 != opt->branch1) { + return handle_file_collision(opt, collide_path, prev_path2, prev_path1, branch2, branch1, b_oid, b_mode, @@ -1589,60 +1589,60 @@ static int handle_file_collision(struct merge_options *o, /* * In the recursive case, we just opt to undo renames */ - if (o->call_depth && (prev_path1 || prev_path2)) { + if (opt->call_depth && (prev_path1 || prev_path2)) { /* Put first file (a_oid, a_mode) in its original spot */ if (prev_path1) { - if (update_file(o, 1, a_oid, a_mode, prev_path1)) + if (update_file(opt, 1, a_oid, a_mode, prev_path1)) return -1; } else { - if (update_file(o, 1, a_oid, a_mode, collide_path)) + if (update_file(opt, 1, a_oid, a_mode, collide_path)) return -1; } /* Put second file (b_oid, b_mode) in its original spot */ if (prev_path2) { - if (update_file(o, 1, b_oid, b_mode, prev_path2)) + if (update_file(opt, 1, b_oid, b_mode, prev_path2)) return -1; } else { - if (update_file(o, 1, b_oid, b_mode, collide_path)) + if (update_file(opt, 1, b_oid, b_mode, collide_path)) return -1; } /* Don't leave something at collision path if unrenaming both */ if (prev_path1 && prev_path2) - remove_file(o, 1, collide_path, 0); + remove_file(opt, 1, collide_path, 0); return 0; } /* Remove rename sources if rename/add or rename/rename(2to1) */ if (prev_path1) - remove_file(o, 1, prev_path1, - o->call_depth || would_lose_untracked(o, prev_path1)); + remove_file(opt, 1, prev_path1, + opt->call_depth || would_lose_untracked(opt, prev_path1)); if (prev_path2) - remove_file(o, 1, prev_path2, - o->call_depth || would_lose_untracked(o, prev_path2)); + remove_file(opt, 1, prev_path2, + opt->call_depth || would_lose_untracked(opt, prev_path2)); /* * Remove the collision path, if it wouldn't cause dirty contents * or an untracked file to get lost. We'll either overwrite with * merged contents, or just write out to differently named files. */ - if (was_dirty(o, collide_path)) { - output(o, 1, _("Refusing to lose dirty file at %s"), + if (was_dirty(opt, collide_path)) { + output(opt, 1, _("Refusing to lose dirty file at %s"), collide_path); - update_path = alt_path = unique_path(o, collide_path, "merged"); - } else if (would_lose_untracked(o, collide_path)) { + update_path = alt_path = unique_path(opt, collide_path, "merged"); + } else if (would_lose_untracked(opt, collide_path)) { /* * Only way we get here is if both renames were from * a directory rename AND user had an untracked file * at the location where both files end up after the * two directory renames. See testcase 10d of t6043. */ - output(o, 1, _("Refusing to lose untracked file at " + output(opt, 1, _("Refusing to lose untracked file at " "%s, even though it's in the way."), collide_path); - update_path = alt_path = unique_path(o, collide_path, "merged"); + update_path = alt_path = unique_path(opt, collide_path, "merged"); } else { /* * FIXME: It's possible that the two files are identical @@ -1654,7 +1654,7 @@ static int handle_file_collision(struct merge_options *o, * merge-recursive interoperate anyway, so punting for * now... */ - remove_file(o, 0, collide_path, 0); + remove_file(opt, 0, collide_path, 0); } /* Store things in diff_filespecs for functions that need it */ @@ -1670,14 +1670,14 @@ static int handle_file_collision(struct merge_options *o, b.mode = b_mode; b.oid_valid = 1; - if (merge_mode_and_contents(o, &null, &a, &b, collide_path, - branch1, branch2, o->call_depth * 2, &mfi)) + if (merge_mode_and_contents(opt, &null, &a, &b, collide_path, + branch1, branch2, opt->call_depth * 2, &mfi)) return -1; mfi.clean &= !alt_path; - if (update_file(o, mfi.clean, &mfi.oid, mfi.mode, update_path)) + if (update_file(opt, mfi.clean, &mfi.oid, mfi.mode, update_path)) return -1; - if (!mfi.clean && !o->call_depth && - update_stages(o, collide_path, NULL, &a, &b)) + if (!mfi.clean && !opt->call_depth && + update_stages(opt, collide_path, NULL, &a, &b)) return -1; free(alt_path); /* @@ -1690,7 +1690,7 @@ static int handle_file_collision(struct merge_options *o, return mfi.clean; } -static int handle_rename_add(struct merge_options *o, +static int handle_rename_add(struct merge_options *opt, struct rename_conflict_info *ci) { /* a was renamed to c, and a separate c was added. */ @@ -1700,21 +1700,21 @@ static int handle_rename_add(struct merge_options *o, char *prev_path_desc; struct merge_file_info mfi; - int other_stage = (ci->branch1 == o->branch1 ? 3 : 2); + int other_stage = (ci->branch1 == opt->branch1 ? 3 : 2); - output(o, 1, _("CONFLICT (rename/add): " + output(opt, 1, _("CONFLICT (rename/add): " "Rename %s->%s in %s. Added %s in %s"), a->path, c->path, ci->branch1, c->path, ci->branch2); prev_path_desc = xstrfmt("version of %s from %s", path, a->path); - if (merge_mode_and_contents(o, a, c, &ci->ren1_other, prev_path_desc, - o->branch1, o->branch2, - 1 + o->call_depth * 2, &mfi)) + if (merge_mode_and_contents(opt, a, c, &ci->ren1_other, prev_path_desc, + opt->branch1, opt->branch2, + 1 + opt->call_depth * 2, &mfi)) return -1; free(prev_path_desc); - return handle_file_collision(o, + return handle_file_collision(opt, c->path, a->path, NULL, ci->branch1, ci->branch2, &mfi.oid, mfi.mode, @@ -1722,20 +1722,20 @@ static int handle_rename_add(struct merge_options *o, ci->dst_entry1->stages[other_stage].mode); } -static char *find_path_for_conflict(struct merge_options *o, +static char *find_path_for_conflict(struct merge_options *opt, const char *path, const char *branch1, const char *branch2) { char *new_path = NULL; - if (dir_in_way(o->repo->index, path, !o->call_depth, 0)) { - new_path = unique_path(o, path, branch1); - output(o, 1, _("%s is a directory in %s adding " + if (dir_in_way(opt->repo->index, path, !opt->call_depth, 0)) { + new_path = unique_path(opt, path, branch1); + output(opt, 1, _("%s is a directory in %s adding " "as %s instead"), path, branch2, new_path); - } else if (would_lose_untracked(o, path)) { - new_path = unique_path(o, path, branch1); - output(o, 1, _("Refusing to lose untracked file" + } else if (would_lose_untracked(opt, path)) { + new_path = unique_path(opt, path, branch1); + output(opt, 1, _("Refusing to lose untracked file" " at %s; adding as %s instead"), path, new_path); } @@ -1743,7 +1743,7 @@ static char *find_path_for_conflict(struct merge_options *o, return new_path; } -static int handle_rename_rename_1to2(struct merge_options *o, +static int handle_rename_rename_1to2(struct merge_options *opt, struct rename_conflict_info *ci) { /* One file was renamed in both branches, but to different names. */ @@ -1755,29 +1755,29 @@ static int handle_rename_rename_1to2(struct merge_options *o, struct diff_filespec *b = ci->pair2->two; char *path_desc; - output(o, 1, _("CONFLICT (rename/rename): " + output(opt, 1, _("CONFLICT (rename/rename): " "Rename \"%s\"->\"%s\" in branch \"%s\" " "rename \"%s\"->\"%s\" in \"%s\"%s"), one->path, a->path, ci->branch1, one->path, b->path, ci->branch2, - o->call_depth ? _(" (left unresolved)") : ""); + opt->call_depth ? _(" (left unresolved)") : ""); path_desc = xstrfmt("%s and %s, both renamed from %s", a->path, b->path, one->path); - if (merge_mode_and_contents(o, one, a, b, path_desc, + if (merge_mode_and_contents(opt, one, a, b, path_desc, ci->branch1, ci->branch2, - o->call_depth * 2, &mfi)) + opt->call_depth * 2, &mfi)) return -1; free(path_desc); - if (o->call_depth) { + if (opt->call_depth) { /* * FIXME: For rename/add-source conflicts (if we could detect * such), this is wrong. We should instead find a unique * pathname and then either rename the add-source file to that * unique path, or use that unique path instead of src here. */ - if (update_file(o, 0, &mfi.oid, mfi.mode, one->path)) + if (update_file(opt, 0, &mfi.oid, mfi.mode, one->path)) return -1; /* @@ -1790,18 +1790,18 @@ static int handle_rename_rename_1to2(struct merge_options *o, */ add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); if (add) { - if (update_file(o, 0, &add->oid, add->mode, a->path)) + if (update_file(opt, 0, &add->oid, add->mode, a->path)) return -1; } else - remove_file_from_index(o->repo->index, a->path); + remove_file_from_index(opt->repo->index, a->path); add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); if (add) { - if (update_file(o, 0, &add->oid, add->mode, b->path)) + if (update_file(opt, 0, &add->oid, add->mode, b->path)) return -1; } else - remove_file_from_index(o->repo->index, b->path); + remove_file_from_index(opt->repo->index, b->path); } else { /* * For each destination path, we need to see if there is a @@ -1810,39 +1810,39 @@ static int handle_rename_rename_1to2(struct merge_options *o, */ add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); if (add) { - if (handle_file_collision(o, a->path, + if (handle_file_collision(opt, a->path, NULL, NULL, ci->branch1, ci->branch2, &mfi.oid, mfi.mode, &add->oid, add->mode) < 0) return -1; } else { - char *new_path = find_path_for_conflict(o, a->path, + char *new_path = find_path_for_conflict(opt, a->path, ci->branch1, ci->branch2); - if (update_file(o, 0, &mfi.oid, mfi.mode, new_path ? new_path : a->path)) + if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : a->path)) return -1; free(new_path); - if (update_stages(o, a->path, NULL, a, NULL)) + if (update_stages(opt, a->path, NULL, a, NULL)) return -1; } add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); if (add) { - if (handle_file_collision(o, b->path, + if (handle_file_collision(opt, b->path, NULL, NULL, ci->branch1, ci->branch2, &add->oid, add->mode, &mfi.oid, mfi.mode) < 0) return -1; } else { - char *new_path = find_path_for_conflict(o, b->path, + char *new_path = find_path_for_conflict(opt, b->path, ci->branch2, ci->branch1); - if (update_file(o, 0, &mfi.oid, mfi.mode, new_path ? new_path : b->path)) + if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : b->path)) return -1; free(new_path); - if (update_stages(o, b->path, NULL, NULL, b)) + if (update_stages(opt, b->path, NULL, NULL, b)) return -1; } } @@ -1850,7 +1850,7 @@ static int handle_rename_rename_1to2(struct merge_options *o, return 0; } -static int handle_rename_rename_2to1(struct merge_options *o, +static int handle_rename_rename_2to1(struct merge_options *opt, struct rename_conflict_info *ci) { /* Two files, a & b, were renamed to the same thing, c. */ @@ -1864,7 +1864,7 @@ static int handle_rename_rename_2to1(struct merge_options *o, struct merge_file_info mfi_c1; struct merge_file_info mfi_c2; - output(o, 1, _("CONFLICT (rename/rename): " + output(opt, 1, _("CONFLICT (rename/rename): " "Rename %s->%s in %s. " "Rename %s->%s in %s"), a->path, c1->path, ci->branch1, @@ -1872,17 +1872,17 @@ static int handle_rename_rename_2to1(struct merge_options *o, path_side_1_desc = xstrfmt("version of %s from %s", path, a->path); path_side_2_desc = xstrfmt("version of %s from %s", path, b->path); - if (merge_mode_and_contents(o, a, c1, &ci->ren1_other, path_side_1_desc, - o->branch1, o->branch2, - 1 + o->call_depth * 2, &mfi_c1) || - merge_mode_and_contents(o, b, &ci->ren2_other, c2, path_side_2_desc, - o->branch1, o->branch2, - 1 + o->call_depth * 2, &mfi_c2)) + if (merge_mode_and_contents(opt, a, c1, &ci->ren1_other, path_side_1_desc, + opt->branch1, opt->branch2, + 1 + opt->call_depth * 2, &mfi_c1) || + merge_mode_and_contents(opt, b, &ci->ren2_other, c2, path_side_2_desc, + opt->branch1, opt->branch2, + 1 + opt->call_depth * 2, &mfi_c2)) return -1; free(path_side_1_desc); free(path_side_2_desc); - return handle_file_collision(o, path, a->path, b->path, + return handle_file_collision(opt, path, a->path, b->path, ci->branch1, ci->branch2, &mfi_c1.oid, mfi_c1.mode, &mfi_c2.oid, mfi_c2.mode); @@ -1891,17 +1891,17 @@ static int handle_rename_rename_2to1(struct merge_options *o, /* * Get the diff_filepairs changed between o_tree and tree. */ -static struct diff_queue_struct *get_diffpairs(struct merge_options *o, +static struct diff_queue_struct *get_diffpairs(struct merge_options *opt, struct tree *o_tree, struct tree *tree) { struct diff_queue_struct *ret; struct diff_options opts; - repo_diff_setup(o->repo, &opts); + repo_diff_setup(opt->repo, &opts); opts.flags.recursive = 1; opts.flags.rename_empty = 0; - opts.detect_rename = merge_detect_rename(o); + opts.detect_rename = merge_detect_rename(opt); /* * We do not have logic to handle the detection of copies. In * fact, it may not even make sense to add such logic: would we @@ -1910,17 +1910,17 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o, */ if (opts.detect_rename > DIFF_DETECT_RENAME) opts.detect_rename = DIFF_DETECT_RENAME; - opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit : - o->diff_rename_limit >= 0 ? o->diff_rename_limit : + opts.rename_limit = opt->merge_rename_limit >= 0 ? opt->merge_rename_limit : + opt->diff_rename_limit >= 0 ? opt->diff_rename_limit : 1000; - opts.rename_score = o->rename_score; - opts.show_rename_progress = o->show_rename_progress; + opts.rename_score = opt->rename_score; + opts.show_rename_progress = opt->show_rename_progress; opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_setup_done(&opts); diff_tree_oid(&o_tree->object.oid, &tree->object.oid, "", &opts); diffcore_std(&opts); - if (opts.needed_rename_limit > o->needed_rename_limit) - o->needed_rename_limit = opts.needed_rename_limit; + if (opts.needed_rename_limit > opt->needed_rename_limit) + opt->needed_rename_limit = opts.needed_rename_limit; ret = xmalloc(sizeof(*ret)); *ret = diff_queued_diff; @@ -2039,7 +2039,7 @@ static void remove_hashmap_entries(struct hashmap *dir_renames, * level conflicts for the renamed location. If there is a rename and * there are no conflicts, return the new name. Otherwise, return NULL. */ -static char *handle_path_level_conflicts(struct merge_options *o, +static char *handle_path_level_conflicts(struct merge_options *opt, const char *path, struct dir_rename_entry *entry, struct hashmap *collisions, @@ -2060,7 +2060,7 @@ static char *handle_path_level_conflicts(struct merge_options *o, /* This should only happen when entry->non_unique_new_dir set */ if (!entry->non_unique_new_dir) BUG("entry->non_unqiue_dir not set and !new_path"); - output(o, 1, _("CONFLICT (directory rename split): " + output(opt, 1, _("CONFLICT (directory rename split): " "Unclear where to place %s because directory " "%s was renamed to multiple other directories, " "with no destination getting a majority of the " @@ -2092,7 +2092,7 @@ static char *handle_path_level_conflicts(struct merge_options *o, collision_ent->reported_already = 1; strbuf_add_separated_string_list(&collision_paths, ", ", &collision_ent->source_files); - output(o, 1, _("CONFLICT (implicit dir rename): Existing " + output(opt, 1, _("CONFLICT (implicit dir rename): Existing " "file/dir at %s in the way of implicit " "directory rename(s) putting the following " "path(s) there: %s."), @@ -2102,7 +2102,7 @@ static char *handle_path_level_conflicts(struct merge_options *o, collision_ent->reported_already = 1; strbuf_add_separated_string_list(&collision_paths, ", ", &collision_ent->source_files); - output(o, 1, _("CONFLICT (implicit dir rename): Cannot map " + output(opt, 1, _("CONFLICT (implicit dir rename): Cannot map " "more than one path to %s; implicit directory " "renames tried to put these paths there: %s"), new_path, collision_paths.buf); @@ -2139,7 +2139,7 @@ static char *handle_path_level_conflicts(struct merge_options *o, * causes conflicts for files within those merged directories, then * that should be detected at the individual path level. */ -static void handle_directory_level_conflicts(struct merge_options *o, +static void handle_directory_level_conflicts(struct merge_options *opt, struct hashmap *dir_re_head, struct tree *head, struct hashmap *dir_re_merge, @@ -2194,11 +2194,11 @@ static void handle_directory_level_conflicts(struct merge_options *o, * know that head_ent->new_dir and merge_ent->new_dir * are different strings. */ - output(o, 1, _("CONFLICT (rename/rename): " + output(opt, 1, _("CONFLICT (rename/rename): " "Rename directory %s->%s in %s. " "Rename directory %s->%s in %s"), - head_ent->dir, head_ent->new_dir.buf, o->branch1, - head_ent->dir, merge_ent->new_dir.buf, o->branch2); + head_ent->dir, head_ent->new_dir.buf, opt->branch1, + head_ent->dir, merge_ent->new_dir.buf, opt->branch2); string_list_append(&remove_from_head, head_ent->dir)->util = head_ent; strbuf_release(&head_ent->new_dir); @@ -2397,7 +2397,7 @@ static void compute_collisions(struct hashmap *collisions, } } -static char *check_for_directory_rename(struct merge_options *o, +static char *check_for_directory_rename(struct merge_options *opt, const char *path, struct tree *tree, struct hashmap *dir_renames, @@ -2438,11 +2438,11 @@ static char *check_for_directory_rename(struct merge_options *o, */ oentry = dir_rename_find_entry(dir_rename_exclusions, entry->new_dir.buf); if (oentry) { - output(o, 1, _("WARNING: Avoiding applying %s -> %s rename " + output(opt, 1, _("WARNING: Avoiding applying %s -> %s rename " "to %s, because %s itself was renamed."), entry->dir, entry->new_dir.buf, path, entry->new_dir.buf); } else { - new_path = handle_path_level_conflicts(o, path, entry, + new_path = handle_path_level_conflicts(opt, path, entry, collisions, tree); *clean_merge &= (new_path != NULL); } @@ -2450,7 +2450,7 @@ static char *check_for_directory_rename(struct merge_options *o, return new_path; } -static void apply_directory_rename_modifications(struct merge_options *o, +static void apply_directory_rename_modifications(struct merge_options *opt, struct diff_filepair *pair, char *new_path, struct rename *re, @@ -2473,11 +2473,11 @@ static void apply_directory_rename_modifications(struct merge_options *o, * saying the file would have been overwritten), but it might * be dirty, though. */ - update_wd = !was_dirty(o, pair->two->path); + update_wd = !was_dirty(opt, pair->two->path); if (!update_wd) - output(o, 1, _("Refusing to lose dirty file at %s"), + output(opt, 1, _("Refusing to lose dirty file at %s"), pair->two->path); - remove_file(o, 1, pair->two->path, !update_wd); + remove_file(opt, 1, pair->two->path, !update_wd); /* Find or create a new re->dst_entry */ item = string_list_lookup(entries, new_path); @@ -2566,7 +2566,7 @@ static void apply_directory_rename_modifications(struct merge_options *o, * to be able to associate the correct cache entries with the rename * information; tree is always equal to either a_tree or b_tree. */ -static struct string_list *get_renames(struct merge_options *o, +static struct string_list *get_renames(struct merge_options *opt, struct diff_queue_struct *pairs, struct hashmap *dir_renames, struct hashmap *dir_rename_exclusions, @@ -2596,7 +2596,7 @@ static struct string_list *get_renames(struct merge_options *o, diff_free_filepair(pair); continue; } - new_path = check_for_directory_rename(o, pair->two->path, tree, + new_path = check_for_directory_rename(opt, pair->two->path, tree, dir_renames, dir_rename_exclusions, &collisions, @@ -2626,7 +2626,7 @@ static struct string_list *get_renames(struct merge_options *o, item = string_list_insert(renames, pair->one->path); item->util = re; if (new_path) - apply_directory_rename_modifications(o, pair, new_path, + apply_directory_rename_modifications(opt, pair, new_path, re, tree, o_tree, a_tree, b_tree, entries); @@ -2641,7 +2641,7 @@ static struct string_list *get_renames(struct merge_options *o, return renames; } -static int process_renames(struct merge_options *o, +static int process_renames(struct merge_options *opt, struct string_list *a_renames, struct string_list *b_renames) { @@ -2685,13 +2685,13 @@ static int process_renames(struct merge_options *o, if (ren1) { renames1 = a_renames; renames2Dst = &b_by_dst; - branch1 = o->branch1; - branch2 = o->branch2; + branch1 = opt->branch1; + branch2 = opt->branch2; } else { renames1 = b_renames; renames2Dst = &a_by_dst; - branch1 = o->branch2; - branch2 = o->branch1; + branch1 = opt->branch2; + branch2 = opt->branch1; SWAP(ren2, ren1); } @@ -2725,7 +2725,7 @@ static int process_renames(struct merge_options *o, * the base stage (think of rename + * add-source cases). */ - remove_file(o, 1, ren1_src, 1); + remove_file(opt, 1, ren1_src, 1); update_entry(ren1->dst_entry, ren1->pair->one, ren1->pair->two, @@ -2738,7 +2738,7 @@ static int process_renames(struct merge_options *o, branch2, ren1->dst_entry, ren2->dst_entry, - o, + opt, NULL, NULL); } else if ((lookup = string_list_lookup(renames2Dst, ren1_dst))) { @@ -2765,7 +2765,7 @@ static int process_renames(struct merge_options *o, branch2, ren1->dst_entry, ren2->dst_entry, - o, + opt, ren1->src_entry, ren2->src_entry); @@ -2788,8 +2788,8 @@ static int process_renames(struct merge_options *o, * stage and in other_stage (think of rename + * add-source case). */ - remove_file(o, 1, ren1_src, - renamed_stage == 2 || !was_tracked(o, ren1_src)); + remove_file(opt, 1, ren1_src, + renamed_stage == 2 || !was_tracked(opt, ren1_src)); oidcpy(&src_other.oid, &ren1->src_entry->stages[other_stage].oid); @@ -2808,7 +2808,7 @@ static int process_renames(struct merge_options *o, branch2, ren1->dst_entry, NULL, - o, + opt, NULL, NULL); } else if (oid_eq(&src_other.oid, &null_oid)) { @@ -2819,7 +2819,7 @@ static int process_renames(struct merge_options *o, branch2, ren1->dst_entry, NULL, - o, + opt, NULL, NULL); } else if ((dst_other.mode == ren1->pair->two->mode) && @@ -2832,7 +2832,7 @@ static int process_renames(struct merge_options *o, * update_file_flags() instead of * update_file(). */ - if (update_file_flags(o, + if (update_file_flags(opt, &ren1->pair->two->oid, ren1->pair->two->mode, ren1_dst, @@ -2854,7 +2854,7 @@ static int process_renames(struct merge_options *o, branch2, ren1->dst_entry, NULL, - o, + opt, ren1->src_entry, NULL); } else @@ -2882,7 +2882,7 @@ static int process_renames(struct merge_options *o, NULL, ren1->dst_entry, NULL, - o, + opt, NULL, NULL); } @@ -2919,7 +2919,7 @@ static void initial_cleanup_rename(struct diff_queue_struct *pairs, free(pairs); } -static int detect_and_process_renames(struct merge_options *o, +static int detect_and_process_renames(struct merge_options *opt, struct tree *common, struct tree *head, struct tree *merge, @@ -2933,17 +2933,17 @@ static int detect_and_process_renames(struct merge_options *o, ri->head_renames = NULL; ri->merge_renames = NULL; - if (!merge_detect_rename(o)) + if (!merge_detect_rename(opt)) return 1; - head_pairs = get_diffpairs(o, common, head); - merge_pairs = get_diffpairs(o, common, merge); + head_pairs = get_diffpairs(opt, common, head); + merge_pairs = get_diffpairs(opt, common, merge); - if (o->detect_directory_renames) { + if (opt->detect_directory_renames) { dir_re_head = get_directory_renames(head_pairs); dir_re_merge = get_directory_renames(merge_pairs); - handle_directory_level_conflicts(o, + handle_directory_level_conflicts(opt, dir_re_head, head, dir_re_merge, merge); } else { @@ -2953,19 +2953,19 @@ static int detect_and_process_renames(struct merge_options *o, dir_rename_init(dir_re_merge); } - ri->head_renames = get_renames(o, head_pairs, + ri->head_renames = get_renames(opt, head_pairs, dir_re_merge, dir_re_head, head, common, head, merge, entries, &clean); if (clean < 0) goto cleanup; - ri->merge_renames = get_renames(o, merge_pairs, + ri->merge_renames = get_renames(opt, merge_pairs, dir_re_head, dir_re_merge, merge, common, head, merge, entries, &clean); if (clean < 0) goto cleanup; - clean &= process_renames(o, ri->head_renames, ri->merge_renames); + clean &= process_renames(opt, ri->head_renames, ri->merge_renames); cleanup: /* @@ -3006,7 +3006,7 @@ static struct object_id *stage_oid(const struct object_id *oid, unsigned mode) return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid; } -static int read_oid_strbuf(struct merge_options *o, +static int read_oid_strbuf(struct merge_options *opt, const struct object_id *oid, struct strbuf *dst) { @@ -3015,10 +3015,10 @@ static int read_oid_strbuf(struct merge_options *o, unsigned long size; buf = read_object_file(oid, &type, &size); if (!buf) - return err(o, _("cannot read object %s"), oid_to_hex(oid)); + return err(opt, _("cannot read object %s"), oid_to_hex(oid)); if (type != OBJ_BLOB) { free(buf); - return err(o, _("object %s is not a blob"), oid_to_hex(oid)); + return err(opt, _("object %s is not a blob"), oid_to_hex(oid)); } strbuf_attach(dst, buf, size, size + 1); return 0; @@ -3060,7 +3060,7 @@ static int blob_unchanged(struct merge_options *opt, return ret; } -static int handle_modify_delete(struct merge_options *o, +static int handle_modify_delete(struct merge_options *opt, const char *path, struct object_id *o_oid, int o_mode, struct object_id *a_oid, int a_mode, @@ -3071,18 +3071,18 @@ static int handle_modify_delete(struct merge_options *o, int changed_mode; if (a_oid) { - modify_branch = o->branch1; - delete_branch = o->branch2; + modify_branch = opt->branch1; + delete_branch = opt->branch2; changed_oid = a_oid; changed_mode = a_mode; } else { - modify_branch = o->branch2; - delete_branch = o->branch1; + modify_branch = opt->branch2; + delete_branch = opt->branch1; changed_oid = b_oid; changed_mode = b_mode; } - return handle_change_delete(o, + return handle_change_delete(opt, path, NULL, o_oid, o_mode, changed_oid, changed_mode, @@ -3090,7 +3090,7 @@ static int handle_modify_delete(struct merge_options *o, _("modify"), _("modified")); } -static int handle_content_merge(struct merge_options *o, +static int handle_content_merge(struct merge_options *opt, const char *path, int is_dirty, struct object_id *o_oid, int o_mode, @@ -3119,26 +3119,26 @@ static int handle_content_merge(struct merge_options *o, if (rename_conflict_info) { struct diff_filepair *pair1 = rename_conflict_info->pair1; - path1 = (o->branch1 == rename_conflict_info->branch1) ? + path1 = (opt->branch1 == rename_conflict_info->branch1) ? pair1->two->path : pair1->one->path; /* If rename_conflict_info->pair2 != NULL, we are in * RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a * normal rename. */ path2 = (rename_conflict_info->pair2 || - o->branch2 == rename_conflict_info->branch1) ? + opt->branch2 == rename_conflict_info->branch1) ? pair1->two->path : pair1->one->path; one.path = pair1->one->path; a.path = (char *)path1; b.path = (char *)path2; - if (dir_in_way(o->repo->index, path, !o->call_depth, + if (dir_in_way(opt->repo->index, path, !opt->call_depth, S_ISGITLINK(pair1->two->mode))) df_conflict_remains = 1; } - if (merge_mode_and_contents(o, &one, &a, &b, path, - o->branch1, o->branch2, - o->call_depth * 2, &mfi)) + if (merge_mode_and_contents(opt, &one, &a, &b, path, + opt->branch1, opt->branch2, + opt->call_depth * 2, &mfi)) return -1; /* @@ -3148,14 +3148,14 @@ static int handle_content_merge(struct merge_options *o, * c) The target path is usable (i.e. not involved in D/F conflict) */ if (mfi.clean && - was_tracked_and_matches(o, path, &mfi.oid, mfi.mode) && + was_tracked_and_matches(opt, path, &mfi.oid, mfi.mode) && !df_conflict_remains) { int pos; struct cache_entry *ce; - output(o, 3, _("Skipped %s (merged same as existing)"), path); - if (add_cacheinfo(o, mfi.mode, &mfi.oid, path, - 0, (!o->call_depth && !is_dirty), 0)) + output(opt, 3, _("Skipped %s (merged same as existing)"), path); + if (add_cacheinfo(opt, mfi.mode, &mfi.oid, path, + 0, (!opt->call_depth && !is_dirty), 0)) return -1; /* * However, add_cacheinfo() will delete the old cache entry @@ -3163,11 +3163,11 @@ static int handle_content_merge(struct merge_options *o, * flag to avoid making the file appear as if it were * deleted by the user. */ - pos = index_name_pos(&o->orig_index, path, strlen(path)); - ce = o->orig_index.cache[pos]; + pos = index_name_pos(&opt->orig_index, path, strlen(path)); + ce = opt->orig_index.cache[pos]; if (ce_skip_worktree(ce)) { - pos = index_name_pos(o->repo->index, path, strlen(path)); - ce = o->repo->index->cache[pos]; + pos = index_name_pos(opt->repo->index, path, strlen(path)); + ce = opt->repo->index->cache[pos]; ce->ce_flags |= CE_SKIP_WORKTREE; } return mfi.clean; @@ -3176,52 +3176,52 @@ static int handle_content_merge(struct merge_options *o, if (!mfi.clean) { if (S_ISGITLINK(mfi.mode)) reason = _("submodule"); - output(o, 1, _("CONFLICT (%s): Merge conflict in %s"), + output(opt, 1, _("CONFLICT (%s): Merge conflict in %s"), reason, path); if (rename_conflict_info && !df_conflict_remains) - if (update_stages(o, path, &one, &a, &b)) + if (update_stages(opt, path, &one, &a, &b)) return -1; } if (df_conflict_remains || is_dirty) { char *new_path; - if (o->call_depth) { - remove_file_from_index(o->repo->index, path); + if (opt->call_depth) { + remove_file_from_index(opt->repo->index, path); } else { if (!mfi.clean) { - if (update_stages(o, path, &one, &a, &b)) + if (update_stages(opt, path, &one, &a, &b)) return -1; } else { - int file_from_stage2 = was_tracked(o, path); + int file_from_stage2 = was_tracked(opt, path); struct diff_filespec merged; oidcpy(&merged.oid, &mfi.oid); merged.mode = mfi.mode; - if (update_stages(o, path, NULL, + if (update_stages(opt, path, NULL, file_from_stage2 ? &merged : NULL, file_from_stage2 ? NULL : &merged)) return -1; } } - new_path = unique_path(o, path, rename_conflict_info->branch1); + new_path = unique_path(opt, path, rename_conflict_info->branch1); if (is_dirty) { - output(o, 1, _("Refusing to lose dirty file at %s"), + output(opt, 1, _("Refusing to lose dirty file at %s"), path); } - output(o, 1, _("Adding as %s instead"), new_path); - if (update_file(o, 0, &mfi.oid, mfi.mode, new_path)) { + output(opt, 1, _("Adding as %s instead"), new_path); + if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path)) { free(new_path); return -1; } free(new_path); mfi.clean = 0; - } else if (update_file(o, mfi.clean, &mfi.oid, mfi.mode, path)) + } else if (update_file(opt, mfi.clean, &mfi.oid, mfi.mode, path)) return -1; return !is_dirty && mfi.clean; } -static int handle_rename_normal(struct merge_options *o, +static int handle_rename_normal(struct merge_options *opt, const char *path, struct object_id *o_oid, unsigned int o_mode, struct object_id *a_oid, unsigned int a_mode, @@ -3229,17 +3229,17 @@ static int handle_rename_normal(struct merge_options *o, struct rename_conflict_info *ci) { /* Merge the content and write it out */ - return handle_content_merge(o, path, was_dirty(o, path), + return handle_content_merge(opt, path, was_dirty(opt, path), o_oid, o_mode, a_oid, a_mode, b_oid, b_mode, ci); } /* Per entry merge function */ -static int process_entry(struct merge_options *o, +static int process_entry(struct merge_options *opt, const char *path, struct stage_data *entry) { int clean_merge = 1; - int normalize = o->renormalize; + int normalize = opt->renormalize; unsigned o_mode = entry->stages[1].mode; unsigned a_mode = entry->stages[2].mode; unsigned b_mode = entry->stages[3].mode; @@ -3253,7 +3253,7 @@ static int process_entry(struct merge_options *o, switch (conflict_info->rename_type) { case RENAME_NORMAL: case RENAME_ONE_FILE_TO_ONE: - clean_merge = handle_rename_normal(o, + clean_merge = handle_rename_normal(opt, path, o_oid, o_mode, a_oid, a_mode, @@ -3262,7 +3262,7 @@ static int process_entry(struct merge_options *o, break; case RENAME_VIA_DIR: clean_merge = 1; - if (handle_rename_via_dir(o, + if (handle_rename_via_dir(opt, conflict_info->pair1, conflict_info->branch1)) clean_merge = -1; @@ -3274,11 +3274,11 @@ static int process_entry(struct merge_options *o, * two-way merged cleanly with the added file, I * guess it's a clean merge? */ - clean_merge = handle_rename_add(o, conflict_info); + clean_merge = handle_rename_add(opt, conflict_info); break; case RENAME_DELETE: clean_merge = 0; - if (handle_rename_delete(o, + if (handle_rename_delete(opt, conflict_info->pair1, conflict_info->branch1, conflict_info->branch2)) @@ -3286,7 +3286,7 @@ static int process_entry(struct merge_options *o, break; case RENAME_ONE_FILE_TO_TWO: clean_merge = 0; - if (handle_rename_rename_1to2(o, conflict_info)) + if (handle_rename_rename_1to2(opt, conflict_info)) clean_merge = -1; break; case RENAME_TWO_FILES_TO_ONE: @@ -3296,7 +3296,7 @@ static int process_entry(struct merge_options *o, * can then be two-way merged cleanly, I guess it's * a clean merge? */ - clean_merge = handle_rename_rename_2to1(o, + clean_merge = handle_rename_rename_2to1(opt, conflict_info); break; default: @@ -3306,18 +3306,18 @@ static int process_entry(struct merge_options *o, } else if (o_oid && (!a_oid || !b_oid)) { /* Case A: Deleted in one */ if ((!a_oid && !b_oid) || - (!b_oid && blob_unchanged(o, o_oid, o_mode, a_oid, a_mode, normalize, path)) || - (!a_oid && blob_unchanged(o, o_oid, o_mode, b_oid, b_mode, normalize, path))) { + (!b_oid && blob_unchanged(opt, o_oid, o_mode, a_oid, a_mode, normalize, path)) || + (!a_oid && blob_unchanged(opt, o_oid, o_mode, b_oid, b_mode, normalize, path))) { /* Deleted in both or deleted in one and * unchanged in the other */ if (a_oid) - output(o, 2, _("Removing %s"), path); + output(opt, 2, _("Removing %s"), path); /* do not touch working file if it did not exist */ - remove_file(o, 1, path, !a_oid); + remove_file(opt, 1, path, !a_oid); } else { /* Modify/delete; deleted side may have put a directory in the way */ clean_merge = 0; - if (handle_modify_delete(o, path, o_oid, o_mode, + if (handle_modify_delete(opt, path, o_oid, o_mode, a_oid, a_mode, b_oid, b_mode)) clean_merge = -1; } @@ -3333,53 +3333,53 @@ static int process_entry(struct merge_options *o, const char *conf; if (a_oid) { - add_branch = o->branch1; - other_branch = o->branch2; + add_branch = opt->branch1; + other_branch = opt->branch2; mode = a_mode; oid = a_oid; conf = _("file/directory"); } else { - add_branch = o->branch2; - other_branch = o->branch1; + add_branch = opt->branch2; + other_branch = opt->branch1; mode = b_mode; oid = b_oid; conf = _("directory/file"); } - if (dir_in_way(o->repo->index, path, - !o->call_depth && !S_ISGITLINK(a_mode), + if (dir_in_way(opt->repo->index, path, + !opt->call_depth && !S_ISGITLINK(a_mode), 0)) { - char *new_path = unique_path(o, path, add_branch); + char *new_path = unique_path(opt, path, add_branch); clean_merge = 0; - output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. " + output(opt, 1, _("CONFLICT (%s): There is a directory with name %s in %s. " "Adding %s as %s"), conf, path, other_branch, path, new_path); - if (update_file(o, 0, oid, mode, new_path)) + if (update_file(opt, 0, oid, mode, new_path)) clean_merge = -1; - else if (o->call_depth) - remove_file_from_index(o->repo->index, path); + else if (opt->call_depth) + remove_file_from_index(opt->repo->index, path); free(new_path); } else { - output(o, 2, _("Adding %s"), path); + output(opt, 2, _("Adding %s"), path); /* do not overwrite file if already present */ - if (update_file_flags(o, oid, mode, path, 1, !a_oid)) + if (update_file_flags(opt, oid, mode, path, 1, !a_oid)) clean_merge = -1; } } else if (a_oid && b_oid) { if (!o_oid) { /* Case C: Added in both (check for same permissions) */ - output(o, 1, + output(opt, 1, _("CONFLICT (add/add): Merge conflict in %s"), path); - clean_merge = handle_file_collision(o, + clean_merge = handle_file_collision(opt, path, NULL, NULL, - o->branch1, - o->branch2, + opt->branch1, + opt->branch2, a_oid, a_mode, b_oid, b_mode); } else { /* case D: Modified in both, but differently. */ int is_dirty = 0; /* unpack_trees would have bailed if dirty */ - clean_merge = handle_content_merge(o, path, + clean_merge = handle_content_merge(opt, path, is_dirty, o_oid, o_mode, a_oid, a_mode, @@ -3391,48 +3391,48 @@ static int process_entry(struct merge_options *o, * this entry was deleted altogether. a_mode == 0 means * we had that path and want to actively remove it. */ - remove_file(o, 1, path, !a_mode); + remove_file(opt, 1, path, !a_mode); } else BUG("fatal merge failure, shouldn't happen."); return clean_merge; } -int merge_trees(struct merge_options *o, +int merge_trees(struct merge_options *opt, struct tree *head, struct tree *merge, struct tree *common, struct tree **result) { - struct index_state *istate = o->repo->index; + struct index_state *istate = opt->repo->index; int code, clean; struct strbuf sb = STRBUF_INIT; - if (!o->call_depth && repo_index_has_changes(o->repo, head, &sb)) { - err(o, _("Your local changes to the following files would be overwritten by merge:\n %s"), + if (!opt->call_depth && repo_index_has_changes(opt->repo, head, &sb)) { + err(opt, _("Your local changes to the following files would be overwritten by merge:\n %s"), sb.buf); return -1; } - if (o->subtree_shift) { - merge = shift_tree_object(o->repo, head, merge, o->subtree_shift); - common = shift_tree_object(o->repo, head, common, o->subtree_shift); + if (opt->subtree_shift) { + merge = shift_tree_object(opt->repo, head, merge, opt->subtree_shift); + common = shift_tree_object(opt->repo, head, common, opt->subtree_shift); } if (oid_eq(&common->object.oid, &merge->object.oid)) { - output(o, 0, _("Already up to date!")); + output(opt, 0, _("Already up to date!")); *result = head; return 1; } - code = unpack_trees_start(o, common, head, merge); + code = unpack_trees_start(opt, common, head, merge); if (code != 0) { - if (show(o, 4) || o->call_depth) - err(o, _("merging of trees %s and %s failed"), + if (show(opt, 4) || opt->call_depth) + err(opt, _("merging of trees %s and %s failed"), oid_to_hex(&head->object.oid), oid_to_hex(&merge->object.oid)); - unpack_trees_finish(o); + unpack_trees_finish(opt); return -1; } @@ -3447,21 +3447,21 @@ int merge_trees(struct merge_options *o, * opposed to decaring a local hashmap is for convenience * so that we don't have to pass it to around. */ - hashmap_init(&o->current_file_dir_set, path_hashmap_cmp, NULL, 512); - get_files_dirs(o, head); - get_files_dirs(o, merge); + hashmap_init(&opt->current_file_dir_set, path_hashmap_cmp, NULL, 512); + get_files_dirs(opt, head); + get_files_dirs(opt, merge); - entries = get_unmerged(o->repo->index); - clean = detect_and_process_renames(o, common, head, merge, + entries = get_unmerged(opt->repo->index); + clean = detect_and_process_renames(opt, common, head, merge, entries, &re_info); - record_df_conflict_files(o, entries); + record_df_conflict_files(opt, entries); if (clean < 0) goto cleanup; for (i = entries->nr-1; 0 <= i; i--) { const char *path = entries->items[i].string; struct stage_data *e = entries->items[i].util; if (!e->processed) { - int ret = process_entry(o, path, e); + int ret = process_entry(opt, path, e); if (!ret) clean = 0; else if (ret < 0) { @@ -3483,19 +3483,19 @@ int merge_trees(struct merge_options *o, string_list_clear(entries, 1); free(entries); - hashmap_free(&o->current_file_dir_set, 1); + hashmap_free(&opt->current_file_dir_set, 1); if (clean < 0) { - unpack_trees_finish(o); + unpack_trees_finish(opt); return clean; } } else clean = 1; - unpack_trees_finish(o); + unpack_trees_finish(opt); - if (o->call_depth && !(*result = write_tree_from_memory(o))) + if (opt->call_depth && !(*result = write_tree_from_memory(opt))) return -1; return clean; @@ -3516,7 +3516,7 @@ static struct commit_list *reverse_commit_list(struct commit_list *list) * Merge the commits h1 and h2, return the resulting virtual * commit object and a flag indicating the cleanness of the merge. */ -int merge_recursive(struct merge_options *o, +int merge_recursive(struct merge_options *opt, struct commit *h1, struct commit *h2, struct commit_list *ca, @@ -3527,10 +3527,10 @@ int merge_recursive(struct merge_options *o, struct tree *mrtree; int clean; - if (show(o, 4)) { - output(o, 4, _("Merging:")); - output_commit_title(o, h1); - output_commit_title(o, h2); + if (show(opt, 4)) { + output(opt, 4, _("Merging:")); + output_commit_title(opt, h1); + output_commit_title(opt, h2); } if (!ca) { @@ -3538,13 +3538,13 @@ int merge_recursive(struct merge_options *o, ca = reverse_commit_list(ca); } - if (show(o, 5)) { + if (show(opt, 5)) { unsigned cnt = commit_list_count(ca); - output(o, 5, Q_("found %u common ancestor:", + output(opt, 5, Q_("found %u common ancestor:", "found %u common ancestors:", cnt), cnt); for (iter = ca; iter; iter = iter->next) - output_commit_title(o, iter->item); + output_commit_title(opt, iter->item); } merged_common_ancestors = pop_commit(&ca); @@ -3552,13 +3552,13 @@ int merge_recursive(struct merge_options *o, /* if there is no common ancestor, use an empty tree */ struct tree *tree; - tree = lookup_tree(o->repo, o->repo->hash_algo->empty_tree); - merged_common_ancestors = make_virtual_commit(o->repo, tree, "ancestor"); + tree = lookup_tree(opt->repo, opt->repo->hash_algo->empty_tree); + merged_common_ancestors = make_virtual_commit(opt->repo, tree, "ancestor"); } for (iter = ca; iter; iter = iter->next) { const char *saved_b1, *saved_b2; - o->call_depth++; + opt->call_depth++; /* * When the merge fails, the result contains files * with conflict markers. The cleanness flag is @@ -3567,46 +3567,46 @@ int merge_recursive(struct merge_options *o, * overwritten it: the committed "conflicts" were * already resolved. */ - discard_index(o->repo->index); - saved_b1 = o->branch1; - saved_b2 = o->branch2; - o->branch1 = "Temporary merge branch 1"; - o->branch2 = "Temporary merge branch 2"; - if (merge_recursive(o, merged_common_ancestors, iter->item, + discard_index(opt->repo->index); + saved_b1 = opt->branch1; + saved_b2 = opt->branch2; + opt->branch1 = "Temporary merge branch 1"; + opt->branch2 = "Temporary merge branch 2"; + if (merge_recursive(opt, merged_common_ancestors, iter->item, NULL, &merged_common_ancestors) < 0) return -1; - o->branch1 = saved_b1; - o->branch2 = saved_b2; - o->call_depth--; + opt->branch1 = saved_b1; + opt->branch2 = saved_b2; + opt->call_depth--; if (!merged_common_ancestors) - return err(o, _("merge returned no commit")); + return err(opt, _("merge returned no commit")); } - discard_index(o->repo->index); - if (!o->call_depth) - repo_read_index(o->repo); + discard_index(opt->repo->index); + if (!opt->call_depth) + repo_read_index(opt->repo); - o->ancestor = "merged common ancestors"; - clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2), + opt->ancestor = "merged common ancestors"; + clean = merge_trees(opt, get_commit_tree(h1), get_commit_tree(h2), get_commit_tree(merged_common_ancestors), &mrtree); if (clean < 0) { - flush_output(o); + flush_output(opt); return clean; } - if (o->call_depth) { - *result = make_virtual_commit(o->repo, mrtree, "merged tree"); + if (opt->call_depth) { + *result = make_virtual_commit(opt->repo, mrtree, "merged tree"); commit_list_insert(h1, &(*result)->parents); commit_list_insert(h2, &(*result)->parents->next); } - flush_output(o); - if (!o->call_depth && o->buffer_output < 2) - strbuf_release(&o->obuf); - if (show(o, 2)) + flush_output(opt); + if (!opt->call_depth && opt->buffer_output < 2) + strbuf_release(&opt->obuf); + if (show(opt, 2)) diff_warn_rename_limit("merge.renamelimit", - o->needed_rename_limit, 0); + opt->needed_rename_limit, 0); return clean; } @@ -3628,7 +3628,7 @@ static struct commit *get_ref(struct repository *repo, const struct object_id *o return (struct commit *)object; } -int merge_recursive_generic(struct merge_options *o, +int merge_recursive_generic(struct merge_options *opt, const struct object_id *head, const struct object_id *merge, int num_base_list, @@ -3637,127 +3637,127 @@ int merge_recursive_generic(struct merge_options *o, { int clean; struct lock_file lock = LOCK_INIT; - struct commit *head_commit = get_ref(o->repo, head, o->branch1); - struct commit *next_commit = get_ref(o->repo, merge, o->branch2); + struct commit *head_commit = get_ref(opt->repo, head, opt->branch1); + struct commit *next_commit = get_ref(opt->repo, merge, opt->branch2); struct commit_list *ca = NULL; if (base_list) { int i; for (i = 0; i < num_base_list; ++i) { struct commit *base; - if (!(base = get_ref(o->repo, base_list[i], oid_to_hex(base_list[i])))) - return err(o, _("Could not parse object '%s'"), + if (!(base = get_ref(opt->repo, base_list[i], oid_to_hex(base_list[i])))) + return err(opt, _("Could not parse object '%s'"), oid_to_hex(base_list[i])); commit_list_insert(base, &ca); } } - repo_hold_locked_index(o->repo, &lock, LOCK_DIE_ON_ERROR); - clean = merge_recursive(o, head_commit, next_commit, ca, + repo_hold_locked_index(opt->repo, &lock, LOCK_DIE_ON_ERROR); + clean = merge_recursive(opt, head_commit, next_commit, ca, result); if (clean < 0) { rollback_lock_file(&lock); return clean; } - if (write_locked_index(o->repo->index, &lock, + if (write_locked_index(opt->repo->index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - return err(o, _("Unable to write index.")); + return err(opt, _("Unable to write index.")); return clean ? 0 : 1; } -static void merge_recursive_config(struct merge_options *o) +static void merge_recursive_config(struct merge_options *opt) { char *value = NULL; - git_config_get_int("merge.verbosity", &o->verbosity); - git_config_get_int("diff.renamelimit", &o->diff_rename_limit); - git_config_get_int("merge.renamelimit", &o->merge_rename_limit); + git_config_get_int("merge.verbosity", &opt->verbosity); + git_config_get_int("diff.renamelimit", &opt->diff_rename_limit); + git_config_get_int("merge.renamelimit", &opt->merge_rename_limit); if (!git_config_get_string("diff.renames", &value)) { - o->diff_detect_rename = git_config_rename("diff.renames", value); + opt->diff_detect_rename = git_config_rename("diff.renames", value); free(value); } if (!git_config_get_string("merge.renames", &value)) { - o->merge_detect_rename = git_config_rename("merge.renames", value); + opt->merge_detect_rename = git_config_rename("merge.renames", value); free(value); } git_config(git_xmerge_config, NULL); } -void init_merge_options(struct merge_options *o, +void init_merge_options(struct merge_options *opt, struct repository *repo) { const char *merge_verbosity; - memset(o, 0, sizeof(struct merge_options)); - o->repo = repo; - o->verbosity = 2; - o->buffer_output = 1; - o->diff_rename_limit = -1; - o->merge_rename_limit = -1; - o->renormalize = 0; - o->diff_detect_rename = -1; - o->merge_detect_rename = -1; - o->detect_directory_renames = 1; - merge_recursive_config(o); + memset(opt, 0, sizeof(struct merge_options)); + opt->repo = repo; + opt->verbosity = 2; + opt->buffer_output = 1; + opt->diff_rename_limit = -1; + opt->merge_rename_limit = -1; + opt->renormalize = 0; + opt->diff_detect_rename = -1; + opt->merge_detect_rename = -1; + opt->detect_directory_renames = 1; + merge_recursive_config(opt); merge_verbosity = getenv("GIT_MERGE_VERBOSITY"); if (merge_verbosity) - o->verbosity = strtol(merge_verbosity, NULL, 10); - if (o->verbosity >= 5) - o->buffer_output = 0; - strbuf_init(&o->obuf, 0); - string_list_init(&o->df_conflict_file_set, 1); + opt->verbosity = strtol(merge_verbosity, NULL, 10); + if (opt->verbosity >= 5) + opt->buffer_output = 0; + strbuf_init(&opt->obuf, 0); + string_list_init(&opt->df_conflict_file_set, 1); } -int parse_merge_opt(struct merge_options *o, const char *s) +int parse_merge_opt(struct merge_options *opt, const char *s) { const char *arg; if (!s || !*s) return -1; if (!strcmp(s, "ours")) - o->recursive_variant = MERGE_RECURSIVE_OURS; + opt->recursive_variant = MERGE_RECURSIVE_OURS; else if (!strcmp(s, "theirs")) - o->recursive_variant = MERGE_RECURSIVE_THEIRS; + opt->recursive_variant = MERGE_RECURSIVE_THEIRS; else if (!strcmp(s, "subtree")) - o->subtree_shift = ""; + opt->subtree_shift = ""; else if (skip_prefix(s, "subtree=", &arg)) - o->subtree_shift = arg; + opt->subtree_shift = arg; else if (!strcmp(s, "patience")) - o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF); + opt->xdl_opts = DIFF_WITH_ALG(opt, PATIENCE_DIFF); else if (!strcmp(s, "histogram")) - o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF); + opt->xdl_opts = DIFF_WITH_ALG(opt, HISTOGRAM_DIFF); else if (skip_prefix(s, "diff-algorithm=", &arg)) { long value = parse_algorithm_value(arg); if (value < 0) return -1; /* clear out previous settings */ - DIFF_XDL_CLR(o, NEED_MINIMAL); - o->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK; - o->xdl_opts |= value; + DIFF_XDL_CLR(opt, NEED_MINIMAL); + opt->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK; + opt->xdl_opts |= value; } else if (!strcmp(s, "ignore-space-change")) - DIFF_XDL_SET(o, IGNORE_WHITESPACE_CHANGE); + DIFF_XDL_SET(opt, IGNORE_WHITESPACE_CHANGE); else if (!strcmp(s, "ignore-all-space")) - DIFF_XDL_SET(o, IGNORE_WHITESPACE); + DIFF_XDL_SET(opt, IGNORE_WHITESPACE); else if (!strcmp(s, "ignore-space-at-eol")) - DIFF_XDL_SET(o, IGNORE_WHITESPACE_AT_EOL); + DIFF_XDL_SET(opt, IGNORE_WHITESPACE_AT_EOL); else if (!strcmp(s, "ignore-cr-at-eol")) - DIFF_XDL_SET(o, IGNORE_CR_AT_EOL); + DIFF_XDL_SET(opt, IGNORE_CR_AT_EOL); else if (!strcmp(s, "renormalize")) - o->renormalize = 1; + opt->renormalize = 1; else if (!strcmp(s, "no-renormalize")) - o->renormalize = 0; + opt->renormalize = 0; else if (!strcmp(s, "no-renames")) - o->merge_detect_rename = 0; + opt->merge_detect_rename = 0; else if (!strcmp(s, "find-renames")) { - o->merge_detect_rename = 1; - o->rename_score = 0; + opt->merge_detect_rename = 1; + opt->rename_score = 0; } else if (skip_prefix(s, "find-renames=", &arg) || skip_prefix(s, "rename-threshold=", &arg)) { - if ((o->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0) + if ((opt->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0) return -1; - o->merge_detect_rename = 1; + opt->merge_detect_rename = 1; } /* * Please update $__git_merge_strategy_options in From patchwork Fri Apr 5 15:00:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887545 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E7581515 for ; Fri, 5 Apr 2019 15:01:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E67E628B14 for ; Fri, 5 Apr 2019 15:00:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DAEE528B6B; Fri, 5 Apr 2019 15:00:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 45C4228A4A for ; Fri, 5 Apr 2019 15:00:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731270AbfDEPA5 (ORCPT ); Fri, 5 Apr 2019 11:00:57 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45624 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728743AbfDEPA5 (ORCPT ); Fri, 5 Apr 2019 11:00:57 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFJ001918; Fri, 5 Apr 2019 08:00:41 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:41 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:42 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:39 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 2BF67220CB1D; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 03/15] merge-recursive: rename diff_filespec 'one' to 'o' Date: Fri, 5 Apr 2019 08:00:14 -0700 Message-ID: <20190405150026.5260-4-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In the previous commit, we noted that several places throughout merge recursive both had a reason to use 'o'; some for a merge_options struct, and others for a diff_filespec struct. Some places had both, forcing one of the two to be renamed, though the choice was inconsistent. Now that the merge_options struct has been renamed to 'opt' everywhere, we can replace the few places that used 'one' for the diff_filespec to 'o'. Signed-off-by: Elijah Newren --- merge-recursive.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 09b76d596e..36af5d9cc6 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1050,7 +1050,7 @@ struct merge_file_info { static int merge_3way(struct merge_options *opt, mmbuffer_t *result_buf, - const struct diff_filespec *one, + const struct diff_filespec *o, const struct diff_filespec *a, const struct diff_filespec *b, const char *branch1, @@ -1084,9 +1084,9 @@ static int merge_3way(struct merge_options *opt, } if (strcmp(a->path, b->path) || - (opt->ancestor != NULL && strcmp(a->path, one->path) != 0)) { + (opt->ancestor != NULL && strcmp(a->path, o->path) != 0)) { base_name = opt->ancestor == NULL ? NULL : - mkpathdup("%s:%s", opt->ancestor, one->path); + mkpathdup("%s:%s", opt->ancestor, o->path); name1 = mkpathdup("%s:%s", branch1, a->path); name2 = mkpathdup("%s:%s", branch2, b->path); } else { @@ -1096,7 +1096,7 @@ static int merge_3way(struct merge_options *opt, name2 = mkpathdup("%s", branch2); } - read_mmblob(&orig, &one->oid); + read_mmblob(&orig, &o->oid); read_mmblob(&src1, &a->oid); read_mmblob(&src2, &b->oid); @@ -1295,7 +1295,7 @@ static int merge_submodule(struct merge_options *opt, } static int merge_mode_and_contents(struct merge_options *opt, - const struct diff_filespec *one, + const struct diff_filespec *o, const struct diff_filespec *a, const struct diff_filespec *b, const char *filename, @@ -1310,7 +1310,7 @@ static int merge_mode_and_contents(struct merge_options *opt, * side of the conflict markers and the other branch on the * top. Fix that. */ - return merge_mode_and_contents(opt, one, b, a, + return merge_mode_and_contents(opt, o, b, a, filename, branch2, branch1, extra_marker_size, result); @@ -1329,31 +1329,31 @@ static int merge_mode_and_contents(struct merge_options *opt, oidcpy(&result->oid, &b->oid); } } else { - if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid)) + if (!oid_eq(&a->oid, &o->oid) && !oid_eq(&b->oid, &o->oid)) result->merge = 1; /* * Merge modes */ - if (a->mode == b->mode || a->mode == one->mode) + if (a->mode == b->mode || a->mode == o->mode) result->mode = b->mode; else { result->mode = a->mode; - if (b->mode != one->mode) { + if (b->mode != o->mode) { result->clean = 0; result->merge = 1; } } - if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid)) + if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &o->oid)) oidcpy(&result->oid, &b->oid); - else if (oid_eq(&b->oid, &one->oid)) + else if (oid_eq(&b->oid, &o->oid)) oidcpy(&result->oid, &a->oid); else if (S_ISREG(a->mode)) { mmbuffer_t result_buf; int ret = 0, merge_status; - merge_status = merge_3way(opt, &result_buf, one, a, b, + merge_status = merge_3way(opt, &result_buf, o, a, b, branch1, branch2, extra_marker_size); @@ -1372,8 +1372,8 @@ static int merge_mode_and_contents(struct merge_options *opt, result->clean = (merge_status == 0); } else if (S_ISGITLINK(a->mode)) { result->clean = merge_submodule(opt, &result->oid, - one->path, - &one->oid, + o->path, + &o->oid, &a->oid, &b->oid); } else if (S_ISLNK(a->mode)) { @@ -1750,7 +1750,7 @@ static int handle_rename_rename_1to2(struct merge_options *opt, struct merge_file_info mfi; struct diff_filespec other; struct diff_filespec *add; - struct diff_filespec *one = ci->pair1->one; + struct diff_filespec *o = ci->pair1->one; struct diff_filespec *a = ci->pair1->two; struct diff_filespec *b = ci->pair2->two; char *path_desc; @@ -1758,13 +1758,13 @@ static int handle_rename_rename_1to2(struct merge_options *opt, output(opt, 1, _("CONFLICT (rename/rename): " "Rename \"%s\"->\"%s\" in branch \"%s\" " "rename \"%s\"->\"%s\" in \"%s\"%s"), - one->path, a->path, ci->branch1, - one->path, b->path, ci->branch2, + o->path, a->path, ci->branch1, + o->path, b->path, ci->branch2, opt->call_depth ? _(" (left unresolved)") : ""); path_desc = xstrfmt("%s and %s, both renamed from %s", - a->path, b->path, one->path); - if (merge_mode_and_contents(opt, one, a, b, path_desc, + a->path, b->path, o->path); + if (merge_mode_and_contents(opt, o, a, b, path_desc, ci->branch1, ci->branch2, opt->call_depth * 2, &mfi)) return -1; @@ -1777,7 +1777,7 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * pathname and then either rename the add-source file to that * unique path, or use that unique path instead of src here. */ - if (update_file(opt, 0, &mfi.oid, mfi.mode, one->path)) + if (update_file(opt, 0, &mfi.oid, mfi.mode, o->path)) return -1; /* @@ -2863,10 +2863,10 @@ static int process_renames(struct merge_options *opt, if (clean_merge < 0) goto cleanup_and_return; if (try_merge) { - struct diff_filespec *one, *a, *b; + struct diff_filespec *o, *a, *b; src_other.path = (char *)ren1_src; - one = ren1->pair->one; + o = ren1->pair->one; if (a_renames == renames1) { a = ren1->pair->two; b = &src_other; @@ -2874,7 +2874,7 @@ static int process_renames(struct merge_options *opt, b = ren1->pair->two; a = &src_other; } - update_entry(ren1->dst_entry, one, a, b); + update_entry(ren1->dst_entry, o, a, b); setup_rename_conflict_info(RENAME_NORMAL, ren1->pair, NULL, From patchwork Fri Apr 5 15:00:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887559 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F301C139A for ; Fri, 5 Apr 2019 15:01:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D6BE928B64 for ; Fri, 5 Apr 2019 15:01:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAFE728B53; Fri, 5 Apr 2019 15:01:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 70EA628B64 for ; Fri, 5 Apr 2019 15:01:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731342AbfDEPBC (ORCPT ); Fri, 5 Apr 2019 11:01:02 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45634 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728743AbfDEPA7 (ORCPT ); Fri, 5 Apr 2019 11:00:59 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFK001918; Fri, 5 Apr 2019 08:00:41 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:41 -0700 Received: from sj-prod-exch-02.YOJOE.local (10.129.18.29) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:42 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 08:00:42 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 3B666220CB27; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 04/15] merge-recursive: rename locals 'o' and 'a' to 'obuf' and 'abuf' Date: Fri, 5 Apr 2019 08:00:15 -0700 Message-ID: <20190405150026.5260-5-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since we want to replace oid,mode pairs with a single diff_filespec, we will soon want to be able to use the names 'o', 'a', and 'b' for the three different file versions. Rename some local variables in blob_unchanged() that would otherwise conflict. Signed-off-by: Elijah Newren --- merge-recursive.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 36af5d9cc6..4ed1b48630 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -3031,9 +3031,10 @@ static int blob_unchanged(struct merge_options *opt, unsigned a_mode, int renormalize, const char *path) { - struct strbuf o = STRBUF_INIT; - struct strbuf a = STRBUF_INIT; + struct strbuf obuf = STRBUF_INIT; + struct strbuf abuf = STRBUF_INIT; int ret = 0; /* assume changed for safety */ + const struct index_state *idx = opt->repo->index; if (a_mode != o_mode) return 0; @@ -3043,20 +3044,21 @@ static int blob_unchanged(struct merge_options *opt, return 0; assert(o_oid && a_oid); - if (read_oid_strbuf(opt, o_oid, &o) || read_oid_strbuf(opt, a_oid, &a)) + if (read_oid_strbuf(opt, o_oid, &obuf) || + read_oid_strbuf(opt, a_oid, &abuf)) goto error_return; /* * Note: binary | is used so that both renormalizations are * performed. Comparison can be skipped if both files are * unchanged since their sha1s have already been compared. */ - if (renormalize_buffer(opt->repo->index, path, o.buf, o.len, &o) | - renormalize_buffer(opt->repo->index, path, a.buf, a.len, &a)) - ret = (o.len == a.len && !memcmp(o.buf, a.buf, o.len)); + if (renormalize_buffer(idx, path, obuf.buf, obuf.len, &obuf) | + renormalize_buffer(idx, path, abuf.buf, abuf.len, &abuf)) + ret = (obuf.len == abuf.len && !memcmp(obuf.buf, abuf.buf, obuf.len)); error_return: - strbuf_release(&o); - strbuf_release(&a); + strbuf_release(&obuf); + strbuf_release(&abuf); return ret; } From patchwork Fri Apr 5 15:00:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887547 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 56B04139A for ; Fri, 5 Apr 2019 15:01:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3455F28B70 for ; Fri, 5 Apr 2019 15:01:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 28BA628B74; Fri, 5 Apr 2019 15:01:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A2CDB28B72 for ; Fri, 5 Apr 2019 15:01:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731335AbfDEPA7 (ORCPT ); Fri, 5 Apr 2019 11:00:59 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40158 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731020AbfDEPA6 (ORCPT ); Fri, 5 Apr 2019 11:00:58 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSnt001751; Fri, 5 Apr 2019 08:00:43 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:43 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:39 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:39 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 3FE47220CB28; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 05/15] merge-recursive: use 'ci' for rename_conflict_info variable name Date: Fri, 5 Apr 2019 08:00:16 -0700 Message-ID: <20190405150026.5260-6-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=4 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=999 adultscore=1 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We used a couple different names, but used 'ci' the most. Use the same variable name throughout for a little extra consistency. Signed-off-by: Elijah Newren --- merge-recursive.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 4ed1b48630..ea5646debd 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -3098,7 +3098,7 @@ static int handle_content_merge(struct merge_options *opt, struct object_id *o_oid, int o_mode, struct object_id *a_oid, int a_mode, struct object_id *b_oid, int b_mode, - struct rename_conflict_info *rename_conflict_info) + struct rename_conflict_info *ci) { const char *reason = _("content"); const char *path1 = NULL, *path2 = NULL; @@ -3118,17 +3118,17 @@ static int handle_content_merge(struct merge_options *opt, oidcpy(&b.oid, b_oid); b.mode = b_mode; - if (rename_conflict_info) { - struct diff_filepair *pair1 = rename_conflict_info->pair1; + if (ci) { + struct diff_filepair *pair1 = ci->pair1; - path1 = (opt->branch1 == rename_conflict_info->branch1) ? + path1 = (opt->branch1 == ci->branch1) ? pair1->two->path : pair1->one->path; - /* If rename_conflict_info->pair2 != NULL, we are in + /* If ci->pair2 != NULL, we are in * RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a * normal rename. */ - path2 = (rename_conflict_info->pair2 || - opt->branch2 == rename_conflict_info->branch1) ? + path2 = (ci->pair2 || + opt->branch2 == ci->branch1) ? pair1->two->path : pair1->one->path; one.path = pair1->one->path; a.path = (char *)path1; @@ -3180,7 +3180,7 @@ static int handle_content_merge(struct merge_options *opt, reason = _("submodule"); output(opt, 1, _("CONFLICT (%s): Merge conflict in %s"), reason, path); - if (rename_conflict_info && !df_conflict_remains) + if (ci && !df_conflict_remains) if (update_stages(opt, path, &one, &a, &b)) return -1; } @@ -3206,7 +3206,7 @@ static int handle_content_merge(struct merge_options *opt, } } - new_path = unique_path(opt, path, rename_conflict_info->branch1); + new_path = unique_path(opt, path, ci->branch1); if (is_dirty) { output(opt, 1, _("Refusing to lose dirty file at %s"), path); @@ -3251,8 +3251,8 @@ static int process_entry(struct merge_options *opt, entry->processed = 1; if (entry->rename_conflict_info) { - struct rename_conflict_info *conflict_info = entry->rename_conflict_info; - switch (conflict_info->rename_type) { + struct rename_conflict_info *ci = entry->rename_conflict_info; + switch (ci->rename_type) { case RENAME_NORMAL: case RENAME_ONE_FILE_TO_ONE: clean_merge = handle_rename_normal(opt, @@ -3260,13 +3260,11 @@ static int process_entry(struct merge_options *opt, o_oid, o_mode, a_oid, a_mode, b_oid, b_mode, - conflict_info); + ci); break; case RENAME_VIA_DIR: clean_merge = 1; - if (handle_rename_via_dir(opt, - conflict_info->pair1, - conflict_info->branch1)) + if (handle_rename_via_dir(opt, ci->pair1, ci->branch1)) clean_merge = -1; break; case RENAME_ADD: @@ -3276,19 +3274,17 @@ static int process_entry(struct merge_options *opt, * two-way merged cleanly with the added file, I * guess it's a clean merge? */ - clean_merge = handle_rename_add(opt, conflict_info); + clean_merge = handle_rename_add(opt, ci); break; case RENAME_DELETE: clean_merge = 0; - if (handle_rename_delete(opt, - conflict_info->pair1, - conflict_info->branch1, - conflict_info->branch2)) + if (handle_rename_delete(opt, ci->pair1, + ci->branch1, ci->branch2)) clean_merge = -1; break; case RENAME_ONE_FILE_TO_TWO: clean_merge = 0; - if (handle_rename_rename_1to2(opt, conflict_info)) + if (handle_rename_rename_1to2(opt, ci)) clean_merge = -1; break; case RENAME_TWO_FILES_TO_ONE: @@ -3298,8 +3294,7 @@ static int process_entry(struct merge_options *opt, * can then be two-way merged cleanly, I guess it's * a clean merge? */ - clean_merge = handle_rename_rename_2to1(opt, - conflict_info); + clean_merge = handle_rename_rename_2to1(opt, ci); break; default: entry->processed = 0; From patchwork Fri Apr 5 15:00:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887549 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E80FE17E9 for ; Fri, 5 Apr 2019 15:01:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CBE9928A4A for ; Fri, 5 Apr 2019 15:01:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C092228B72; Fri, 5 Apr 2019 15:01:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C2DC28B6B for ; Fri, 5 Apr 2019 15:01:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731336AbfDEPBB (ORCPT ); Fri, 5 Apr 2019 11:01:01 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45644 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731020AbfDEPBA (ORCPT ); Fri, 5 Apr 2019 11:01:00 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFL001918; Fri, 5 Apr 2019 08:00:42 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:41 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:42 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:39 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 449CD220CB29; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 06/15] merge-recursive: move some struct declarations together Date: Fri, 5 Apr 2019 08:00:17 -0700 Message-ID: <20190405150026.5260-7-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=4 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP These structs are related and reference each other, so move them together to make it easier for folks to determine what they hold and what their purpose is. Signed-off-by: Elijah Newren --- merge-recursive.c | 78 +++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index ea5646debd..c4a2ef2a37 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -196,18 +196,6 @@ enum rename_type { RENAME_TWO_FILES_TO_ONE }; -struct rename_conflict_info { - enum rename_type rename_type; - struct diff_filepair *pair1; - struct diff_filepair *pair2; - const char *branch1; - const char *branch2; - struct stage_data *dst_entry1; - struct stage_data *dst_entry2; - struct diff_filespec ren1_other; - struct diff_filespec ren2_other; -}; - /* * Since we want to write the index eventually, we cannot reuse the index * for these (temporary) data. @@ -221,6 +209,45 @@ struct stage_data { unsigned processed:1; }; +struct rename { + struct diff_filepair *pair; + /* + * Purpose of src_entry and dst_entry: + * + * If 'before' is renamed to 'after' then src_entry will contain + * the versions of 'before' from the merge_base, HEAD, and MERGE in + * stages 1, 2, and 3; dst_entry will contain the respective + * versions of 'after' in corresponding locations. Thus, we have a + * total of six modes and oids, though some will be null. (Stage 0 + * is ignored; we're interested in handling conflicts.) + * + * Since we don't turn on break-rewrites by default, neither + * src_entry nor dst_entry can have all three of their stages have + * non-null oids, meaning at most four of the six will be non-null. + * Also, since this is a rename, both src_entry and dst_entry will + * have at least one non-null oid, meaning at least two will be + * non-null. Of the six oids, a typical rename will have three be + * non-null. Only two implies a rename/delete, and four implies a + * rename/add. + */ + struct stage_data *src_entry; + struct stage_data *dst_entry; + unsigned add_turned_into_rename:1; + unsigned processed:1; +}; + +struct rename_conflict_info { + enum rename_type rename_type; + struct diff_filepair *pair1; + struct diff_filepair *pair2; + const char *branch1; + const char *branch2; + struct stage_data *dst_entry1; + struct stage_data *dst_entry2; + struct diff_filespec ren1_other; + struct diff_filespec ren2_other; +}; + static inline void setup_rename_conflict_info(enum rename_type rename_type, struct diff_filepair *pair1, struct diff_filepair *pair2, @@ -645,33 +672,6 @@ static void record_df_conflict_files(struct merge_options *opt, string_list_clear(&df_sorted_entries, 0); } -struct rename { - struct diff_filepair *pair; - /* - * Purpose of src_entry and dst_entry: - * - * If 'before' is renamed to 'after' then src_entry will contain - * the versions of 'before' from the merge_base, HEAD, and MERGE in - * stages 1, 2, and 3; dst_entry will contain the respective - * versions of 'after' in corresponding locations. Thus, we have a - * total of six modes and oids, though some will be null. (Stage 0 - * is ignored; we're interested in handling conflicts.) - * - * Since we don't turn on break-rewrites by default, neither - * src_entry nor dst_entry can have all three of their stages have - * non-null oids, meaning at most four of the six will be non-null. - * Also, since this is a rename, both src_entry and dst_entry will - * have at least one non-null oid, meaning at least two will be - * non-null. Of the six oids, a typical rename will have three be - * non-null. Only two implies a rename/delete, and four implies a - * rename/add. - */ - struct stage_data *src_entry; - struct stage_data *dst_entry; - unsigned add_turned_into_rename:1; - unsigned processed:1; -}; - static int update_stages(struct merge_options *opt, const char *path, const struct diff_filespec *o, const struct diff_filespec *a, From patchwork Fri Apr 5 15:00:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A7A81515 for ; Fri, 5 Apr 2019 15:01:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5ECBF28A5B for ; Fri, 5 Apr 2019 15:01:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D19A28B64; Fri, 5 Apr 2019 15:01:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8AFE928B53 for ; Fri, 5 Apr 2019 15:01:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731354AbfDEPBD (ORCPT ); Fri, 5 Apr 2019 11:01:03 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45636 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731248AbfDEPA7 (ORCPT ); Fri, 5 Apr 2019 11:00:59 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwOXD001899; Fri, 5 Apr 2019 08:00:44 -0700 Received: from mail.palantir.com ([198.97.14.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf4a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:42 -0700 Received: from dc-prod-exch-01.YOJOE.local (10.193.18.14) by dc-prod-exch-01.YOJOE.local (10.193.18.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 11:00:40 -0400 Received: from smtp-transport.yojoe.local (10.129.56.124) by dc-prod-exch-01.YOJOE.local (10.193.18.14) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 11:00:40 -0400 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 4987A220CB2B; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 07/15] merge-recursive: shrink rename_conflict_info Date: Fri, 5 Apr 2019 08:00:18 -0700 Message-ID: <20190405150026.5260-8-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=924 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The rename_conflict_info struct used both a pair and a stage_data which were taken from a rename struct. Just use the original rename struct. This will also allow us to start making other simplifications to the code. Signed-off-by: Elijah Newren --- merge-recursive.c | 120 +++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 70 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index c4a2ef2a37..e05f8f22f5 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -238,24 +238,20 @@ struct rename { struct rename_conflict_info { enum rename_type rename_type; - struct diff_filepair *pair1; - struct diff_filepair *pair2; + struct rename *ren1; + struct rename *ren2; const char *branch1; const char *branch2; - struct stage_data *dst_entry1; - struct stage_data *dst_entry2; struct diff_filespec ren1_other; struct diff_filespec ren2_other; }; static inline void setup_rename_conflict_info(enum rename_type rename_type, - struct diff_filepair *pair1, - struct diff_filepair *pair2, + struct merge_options *opt, + struct rename *ren1, + struct rename *ren2, const char *branch1, const char *branch2, - struct stage_data *dst_entry1, - struct stage_data *dst_entry2, - struct merge_options *opt, struct stage_data *src_entry1, struct stage_data *src_entry2) { @@ -269,31 +265,27 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, * ensure that branch1 == opt->branch1. So, simply flip arguments * around if we don't have that. */ - if (dst_entry2 && branch1 != opt->branch1) { + if (ren2 && branch1 != opt->branch1) { setup_rename_conflict_info(rename_type, - pair2, pair1, - branch2, branch1, - dst_entry2, dst_entry1, opt, + ren2, ren1, + branch2, branch1, src_entry2, src_entry1); return; } ci = xcalloc(1, sizeof(struct rename_conflict_info)); ci->rename_type = rename_type; - ci->pair1 = pair1; + ci->ren1 = ren1; + ci->ren2 = ren2; ci->branch1 = branch1; ci->branch2 = branch2; - ci->dst_entry1 = dst_entry1; - dst_entry1->rename_conflict_info = ci; - dst_entry1->processed = 0; + ci->ren1->dst_entry->processed = 0; + ci->ren1->dst_entry->rename_conflict_info = ci; - assert(!pair2 == !dst_entry2); - if (dst_entry2) { - ci->dst_entry2 = dst_entry2; - ci->pair2 = pair2; - dst_entry2->rename_conflict_info = ci; + if (ren2) { + ci->ren2->dst_entry->rename_conflict_info = ci; } /* @@ -305,7 +297,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, rename_type == RENAME_TWO_FILES_TO_ONE) { ostage1 = opt->branch1 == branch1 ? 3 : 2; - ci->ren1_other.path = pair1->one->path; + ci->ren1_other.path = ren1->pair->one->path; oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid); ci->ren1_other.mode = src_entry1->stages[ostage1].mode; } @@ -313,7 +305,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, if (rename_type == RENAME_TWO_FILES_TO_ONE) { ostage2 = ostage1 ^ 1; - ci->ren2_other.path = pair2->one->path; + ci->ren2_other.path = ren2->pair->one->path; oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid); ci->ren2_other.mode = src_entry2->stages[ostage2].mode; } @@ -1694,8 +1686,8 @@ static int handle_rename_add(struct merge_options *opt, struct rename_conflict_info *ci) { /* a was renamed to c, and a separate c was added. */ - struct diff_filespec *a = ci->pair1->one; - struct diff_filespec *c = ci->pair1->two; + struct diff_filespec *a = ci->ren1->pair->one; + struct diff_filespec *c = ci->ren1->pair->two; char *path = c->path; char *prev_path_desc; struct merge_file_info mfi; @@ -1718,8 +1710,8 @@ static int handle_rename_add(struct merge_options *opt, c->path, a->path, NULL, ci->branch1, ci->branch2, &mfi.oid, mfi.mode, - &ci->dst_entry1->stages[other_stage].oid, - ci->dst_entry1->stages[other_stage].mode); + &ci->ren1->dst_entry->stages[other_stage].oid, + ci->ren1->dst_entry->stages[other_stage].mode); } static char *find_path_for_conflict(struct merge_options *opt, @@ -1750,9 +1742,9 @@ static int handle_rename_rename_1to2(struct merge_options *opt, struct merge_file_info mfi; struct diff_filespec other; struct diff_filespec *add; - struct diff_filespec *o = ci->pair1->one; - struct diff_filespec *a = ci->pair1->two; - struct diff_filespec *b = ci->pair2->two; + struct diff_filespec *o = ci->ren1->pair->one; + struct diff_filespec *a = ci->ren1->pair->two; + struct diff_filespec *b = ci->ren2->pair->two; char *path_desc; output(opt, 1, _("CONFLICT (rename/rename): " @@ -1788,14 +1780,14 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * such cases, we should keep the added file around, * resolving the conflict at that path in its favor. */ - add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); + add = filespec_from_entry(&other, ci->ren1->dst_entry, 2 ^ 1); if (add) { if (update_file(opt, 0, &add->oid, add->mode, a->path)) return -1; } else remove_file_from_index(opt->repo->index, a->path); - add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); + add = filespec_from_entry(&other, ci->ren2->dst_entry, 3 ^ 1); if (add) { if (update_file(opt, 0, &add->oid, add->mode, b->path)) return -1; @@ -1808,7 +1800,7 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * rename/add collision. If not, we can write the file out * to the specified location. */ - add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); + add = filespec_from_entry(&other, ci->ren1->dst_entry, 2 ^ 1); if (add) { if (handle_file_collision(opt, a->path, NULL, NULL, @@ -1827,7 +1819,7 @@ static int handle_rename_rename_1to2(struct merge_options *opt, return -1; } - add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); + add = filespec_from_entry(&other, ci->ren2->dst_entry, 3 ^ 1); if (add) { if (handle_file_collision(opt, b->path, NULL, NULL, @@ -1854,10 +1846,10 @@ static int handle_rename_rename_2to1(struct merge_options *opt, struct rename_conflict_info *ci) { /* Two files, a & b, were renamed to the same thing, c. */ - struct diff_filespec *a = ci->pair1->one; - struct diff_filespec *b = ci->pair2->one; - struct diff_filespec *c1 = ci->pair1->two; - struct diff_filespec *c2 = ci->pair2->two; + struct diff_filespec *a = ci->ren1->pair->one; + struct diff_filespec *b = ci->ren2->pair->one; + struct diff_filespec *c1 = ci->ren1->pair->two; + struct diff_filespec *c2 = ci->ren2->pair->two; char *path = c1->path; /* == c2->path */ char *path_side_1_desc; char *path_side_2_desc; @@ -2732,13 +2724,11 @@ static int process_renames(struct merge_options *opt, ren2->pair->two); } setup_rename_conflict_info(rename_type, - ren1->pair, - ren2->pair, + opt, + ren1, + ren2, branch1, branch2, - ren1->dst_entry, - ren2->dst_entry, - opt, NULL, NULL); } else if ((lookup = string_list_lookup(renames2Dst, ren1_dst))) { @@ -2759,13 +2749,11 @@ static int process_renames(struct merge_options *opt, ren2->src_entry->processed = 1; setup_rename_conflict_info(RENAME_TWO_FILES_TO_ONE, - ren1->pair, - ren2->pair, + opt, + ren1, + ren2, branch1, branch2, - ren1->dst_entry, - ren2->dst_entry, - opt, ren1->src_entry, ren2->src_entry); @@ -2802,24 +2790,20 @@ static int process_renames(struct merge_options *opt, if (oid_eq(&src_other.oid, &null_oid) && ren1->add_turned_into_rename) { setup_rename_conflict_info(RENAME_VIA_DIR, - ren1->pair, + opt, + ren1, NULL, branch1, branch2, - ren1->dst_entry, - NULL, - opt, NULL, NULL); } else if (oid_eq(&src_other.oid, &null_oid)) { setup_rename_conflict_info(RENAME_DELETE, - ren1->pair, + opt, + ren1, NULL, branch1, branch2, - ren1->dst_entry, - NULL, - opt, NULL, NULL); } else if ((dst_other.mode == ren1->pair->two->mode) && @@ -2848,13 +2832,11 @@ static int process_renames(struct merge_options *opt, * file, then the merge will be clean. */ setup_rename_conflict_info(RENAME_ADD, - ren1->pair, + opt, + ren1, NULL, branch1, branch2, - ren1->dst_entry, - NULL, - opt, ren1->src_entry, NULL); } else @@ -2876,13 +2858,11 @@ static int process_renames(struct merge_options *opt, } update_entry(ren1->dst_entry, o, a, b); setup_rename_conflict_info(RENAME_NORMAL, - ren1->pair, + opt, + ren1, NULL, branch1, NULL, - ren1->dst_entry, - NULL, - opt, NULL, NULL); } @@ -3119,15 +3099,15 @@ static int handle_content_merge(struct merge_options *opt, b.mode = b_mode; if (ci) { - struct diff_filepair *pair1 = ci->pair1; + struct diff_filepair *pair1 = ci->ren1->pair; path1 = (opt->branch1 == ci->branch1) ? pair1->two->path : pair1->one->path; - /* If ci->pair2 != NULL, we are in + /* If ci->ren2->pair != NULL, we are in * RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a * normal rename. */ - path2 = (ci->pair2 || + path2 = ((ci->ren2 && ci->ren2->pair) || opt->branch2 == ci->branch1) ? pair1->two->path : pair1->one->path; one.path = pair1->one->path; @@ -3264,7 +3244,7 @@ static int process_entry(struct merge_options *opt, break; case RENAME_VIA_DIR: clean_merge = 1; - if (handle_rename_via_dir(opt, ci->pair1, ci->branch1)) + if (handle_rename_via_dir(opt, ci->ren1->pair, ci->branch1)) clean_merge = -1; break; case RENAME_ADD: @@ -3278,7 +3258,7 @@ static int process_entry(struct merge_options *opt, break; case RENAME_DELETE: clean_merge = 0; - if (handle_rename_delete(opt, ci->pair1, + if (handle_rename_delete(opt, ci->ren1->pair, ci->branch1, ci->branch2)) clean_merge = -1; break; From patchwork Fri Apr 5 15:00:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887557 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B13FB139A for ; Fri, 5 Apr 2019 15:01:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 95F24289B8 for ; Fri, 5 Apr 2019 15:01:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A1B028B64; Fri, 5 Apr 2019 15:01:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05ECF289B8 for ; Fri, 5 Apr 2019 15:01:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731357AbfDEPBF (ORCPT ); Fri, 5 Apr 2019 11:01:05 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45656 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728743AbfDEPBD (ORCPT ); Fri, 5 Apr 2019 11:01:03 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFM001918; Fri, 5 Apr 2019 08:00:43 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:42 -0700 Received: from sj-prod-exch-02.YOJOE.local (10.129.18.29) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:42 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 08:00:42 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 51824220CB2C; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 08/15] merge-recursive: remove ren[12]_other fields from rename_conflict_info Date: Fri, 5 Apr 2019 08:00:19 -0700 Message-ID: <20190405150026.5260-9-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The ren1_other and ren2_other fields were synthesized from information in ren1->src_entry and ren2->src_entry. Since we already have the necessary information in ren1 and ren2, just use those. Signed-off-by: Elijah Newren --- merge-recursive.c | 71 ++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index e05f8f22f5..e66b47cfa1 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -242,8 +242,6 @@ struct rename_conflict_info { struct rename *ren2; const char *branch1; const char *branch2; - struct diff_filespec ren1_other; - struct diff_filespec ren2_other; }; static inline void setup_rename_conflict_info(enum rename_type rename_type, @@ -251,11 +249,8 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, struct rename *ren1, struct rename *ren2, const char *branch1, - const char *branch2, - struct stage_data *src_entry1, - struct stage_data *src_entry2) + const char *branch2) { - int ostage1 = 0, ostage2; struct rename_conflict_info *ci; /* @@ -269,8 +264,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, setup_rename_conflict_info(rename_type, opt, ren2, ren1, - branch2, branch1, - src_entry2, src_entry1); + branch2, branch1); return; } @@ -287,28 +281,6 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, if (ren2) { ci->ren2->dst_entry->rename_conflict_info = ci; } - - /* - * For each rename, there could have been - * modifications on the side of history where that - * file was not renamed. - */ - if (rename_type == RENAME_ADD || - rename_type == RENAME_TWO_FILES_TO_ONE) { - ostage1 = opt->branch1 == branch1 ? 3 : 2; - - ci->ren1_other.path = ren1->pair->one->path; - oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid); - ci->ren1_other.mode = src_entry1->stages[ostage1].mode; - } - - if (rename_type == RENAME_TWO_FILES_TO_ONE) { - ostage2 = ostage1 ^ 1; - - ci->ren2_other.path = ren2->pair->one->path; - oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid); - ci->ren2_other.mode = src_entry2->stages[ostage2].mode; - } } static int show(struct merge_options *opt, int v) @@ -1688,6 +1660,7 @@ static int handle_rename_add(struct merge_options *opt, /* a was renamed to c, and a separate c was added. */ struct diff_filespec *a = ci->ren1->pair->one; struct diff_filespec *c = ci->ren1->pair->two; + struct diff_filespec tmp; char *path = c->path; char *prev_path_desc; struct merge_file_info mfi; @@ -1699,8 +1672,12 @@ static int handle_rename_add(struct merge_options *opt, a->path, c->path, ci->branch1, c->path, ci->branch2); + filespec_from_entry(&tmp, ci->ren1->src_entry, other_stage); + tmp.path = a->path; + prev_path_desc = xstrfmt("version of %s from %s", path, a->path); - if (merge_mode_and_contents(opt, a, c, &ci->ren1_other, prev_path_desc, + if (merge_mode_and_contents(opt, a, c, &tmp, + prev_path_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi)) return -1; @@ -1850,6 +1827,7 @@ static int handle_rename_rename_2to1(struct merge_options *opt, struct diff_filespec *b = ci->ren2->pair->one; struct diff_filespec *c1 = ci->ren1->pair->two; struct diff_filespec *c2 = ci->ren2->pair->two; + struct diff_filespec tmp1, tmp2; char *path = c1->path; /* == c2->path */ char *path_side_1_desc; char *path_side_2_desc; @@ -1862,12 +1840,17 @@ static int handle_rename_rename_2to1(struct merge_options *opt, a->path, c1->path, ci->branch1, b->path, c2->path, ci->branch2); + filespec_from_entry(&tmp1, ci->ren1->src_entry, 3); + tmp1.path = a->path; + filespec_from_entry(&tmp2, ci->ren2->src_entry, 2); + tmp2.path = b->path; + path_side_1_desc = xstrfmt("version of %s from %s", path, a->path); path_side_2_desc = xstrfmt("version of %s from %s", path, b->path); - if (merge_mode_and_contents(opt, a, c1, &ci->ren1_other, path_side_1_desc, + if (merge_mode_and_contents(opt, a, c1, &tmp1, path_side_1_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi_c1) || - merge_mode_and_contents(opt, b, &ci->ren2_other, c2, path_side_2_desc, + merge_mode_and_contents(opt, b, &tmp2, c2, path_side_2_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi_c2)) return -1; @@ -2728,9 +2711,7 @@ static int process_renames(struct merge_options *opt, ren1, ren2, branch1, - branch2, - NULL, - NULL); + branch2); } else if ((lookup = string_list_lookup(renames2Dst, ren1_dst))) { /* Two different files renamed to the same thing */ char *ren2_dst; @@ -2753,9 +2734,7 @@ static int process_renames(struct merge_options *opt, ren1, ren2, branch1, - branch2, - ren1->src_entry, - ren2->src_entry); + branch2); } else { /* Renamed in 1, maybe changed in 2 */ @@ -2794,18 +2773,14 @@ static int process_renames(struct merge_options *opt, ren1, NULL, branch1, - branch2, - NULL, - NULL); + branch2); } else if (oid_eq(&src_other.oid, &null_oid)) { setup_rename_conflict_info(RENAME_DELETE, opt, ren1, NULL, branch1, - branch2, - NULL, - NULL); + branch2); } else if ((dst_other.mode == ren1->pair->two->mode) && oid_eq(&dst_other.oid, &ren1->pair->two->oid)) { /* @@ -2836,9 +2811,7 @@ static int process_renames(struct merge_options *opt, ren1, NULL, branch1, - branch2, - ren1->src_entry, - NULL); + branch2); } else try_merge = 1; @@ -2862,8 +2835,6 @@ static int process_renames(struct merge_options *opt, ren1, NULL, branch1, - NULL, - NULL, NULL); } } From patchwork Fri Apr 5 15:00:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887553 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9C4D139A for ; Fri, 5 Apr 2019 15:01:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE22628B64 for ; Fri, 5 Apr 2019 15:01:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B2DEE28B68; Fri, 5 Apr 2019 15:01:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DCF8128B77 for ; Fri, 5 Apr 2019 15:01:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731348AbfDEPBC (ORCPT ); Fri, 5 Apr 2019 11:01:02 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45630 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731229AbfDEPA7 (ORCPT ); Fri, 5 Apr 2019 11:00:59 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFN001918; Fri, 5 Apr 2019 08:00:44 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:43 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:43 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:40 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 612CA220CB2D; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 09/15] merge-recursive: track branch where rename occurred in rename struct Date: Fri, 5 Apr 2019 08:00:20 -0700 Message-ID: <20190405150026.5260-10-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=13 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We previously tracked the branch associated with a rename in a separate field in rename_conflict_info, but since it is directly associated with the rename it makes more sense to move it into the rename struct. Signed-off-by: Elijah Newren --- merge-recursive.c | 113 +++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 71 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index e66b47cfa1..f85c276f35 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -211,6 +211,7 @@ struct stage_data { struct rename { struct diff_filepair *pair; + const char *branch; /* branch that the rename occurred on */ /* * Purpose of src_entry and dst_entry: * @@ -240,16 +241,12 @@ struct rename_conflict_info { enum rename_type rename_type; struct rename *ren1; struct rename *ren2; - const char *branch1; - const char *branch2; }; static inline void setup_rename_conflict_info(enum rename_type rename_type, struct merge_options *opt, struct rename *ren1, - struct rename *ren2, - const char *branch1, - const char *branch2) + struct rename *ren2) { struct rename_conflict_info *ci; @@ -260,11 +257,8 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, * ensure that branch1 == opt->branch1. So, simply flip arguments * around if we don't have that. */ - if (ren2 && branch1 != opt->branch1) { - setup_rename_conflict_info(rename_type, - opt, - ren2, ren1, - branch2, branch1); + if (ren2 && ren1->branch != opt->branch1) { + setup_rename_conflict_info(rename_type, opt, ren2, ren1); return; } @@ -272,8 +266,6 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, ci->rename_type = rename_type; ci->ren1 = ren1; ci->ren2 = ren2; - ci->branch1 = branch1; - ci->branch2 = branch2; ci->ren1->dst_entry->processed = 0; ci->ren1->dst_entry->rename_conflict_info = ci; @@ -1665,12 +1657,15 @@ static int handle_rename_add(struct merge_options *opt, char *prev_path_desc; struct merge_file_info mfi; - int other_stage = (ci->branch1 == opt->branch1 ? 3 : 2); + const char *rename_branch = ci->ren1->branch; + const char *add_branch = (opt->branch1 == rename_branch ? + opt->branch2 : opt->branch1); + int other_stage = (ci->ren1->branch == opt->branch1 ? 3 : 2); output(opt, 1, _("CONFLICT (rename/add): " "Rename %s->%s in %s. Added %s in %s"), - a->path, c->path, ci->branch1, - c->path, ci->branch2); + a->path, c->path, rename_branch, + c->path, add_branch); filespec_from_entry(&tmp, ci->ren1->src_entry, other_stage); tmp.path = a->path; @@ -1685,7 +1680,7 @@ static int handle_rename_add(struct merge_options *opt, return handle_file_collision(opt, c->path, a->path, NULL, - ci->branch1, ci->branch2, + rename_branch, add_branch, &mfi.oid, mfi.mode, &ci->ren1->dst_entry->stages[other_stage].oid, ci->ren1->dst_entry->stages[other_stage].mode); @@ -1727,14 +1722,14 @@ static int handle_rename_rename_1to2(struct merge_options *opt, output(opt, 1, _("CONFLICT (rename/rename): " "Rename \"%s\"->\"%s\" in branch \"%s\" " "rename \"%s\"->\"%s\" in \"%s\"%s"), - o->path, a->path, ci->branch1, - o->path, b->path, ci->branch2, + o->path, a->path, ci->ren1->branch, + o->path, b->path, ci->ren2->branch, opt->call_depth ? _(" (left unresolved)") : ""); path_desc = xstrfmt("%s and %s, both renamed from %s", a->path, b->path, o->path); if (merge_mode_and_contents(opt, o, a, b, path_desc, - ci->branch1, ci->branch2, + ci->ren1->branch, ci->ren2->branch, opt->call_depth * 2, &mfi)) return -1; free(path_desc); @@ -1781,14 +1776,15 @@ static int handle_rename_rename_1to2(struct merge_options *opt, if (add) { if (handle_file_collision(opt, a->path, NULL, NULL, - ci->branch1, ci->branch2, + ci->ren1->branch, + ci->ren2->branch, &mfi.oid, mfi.mode, &add->oid, add->mode) < 0) return -1; } else { char *new_path = find_path_for_conflict(opt, a->path, - ci->branch1, - ci->branch2); + ci->ren1->branch, + ci->ren2->branch); if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : a->path)) return -1; free(new_path); @@ -1800,14 +1796,15 @@ static int handle_rename_rename_1to2(struct merge_options *opt, if (add) { if (handle_file_collision(opt, b->path, NULL, NULL, - ci->branch1, ci->branch2, + ci->ren1->branch, + ci->ren2->branch, &add->oid, add->mode, &mfi.oid, mfi.mode) < 0) return -1; } else { char *new_path = find_path_for_conflict(opt, b->path, - ci->branch2, - ci->branch1); + ci->ren2->branch, + ci->ren1->branch); if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : b->path)) return -1; free(new_path); @@ -1837,8 +1834,8 @@ static int handle_rename_rename_2to1(struct merge_options *opt, output(opt, 1, _("CONFLICT (rename/rename): " "Rename %s->%s in %s. " "Rename %s->%s in %s"), - a->path, c1->path, ci->branch1, - b->path, c2->path, ci->branch2); + a->path, c1->path, ci->ren1->branch, + b->path, c2->path, ci->ren2->branch); filespec_from_entry(&tmp1, ci->ren1->src_entry, 3); tmp1.path = a->path; @@ -1858,7 +1855,7 @@ static int handle_rename_rename_2to1(struct merge_options *opt, free(path_side_2_desc); return handle_file_collision(opt, path, a->path, b->path, - ci->branch1, ci->branch2, + ci->ren1->branch, ci->ren2->branch, &mfi_c1.oid, mfi_c1.mode, &mfi_c2.oid, mfi_c2.mode); } @@ -2542,6 +2539,7 @@ static void apply_directory_rename_modifications(struct merge_options *opt, * information; tree is always equal to either a_tree or b_tree. */ static struct string_list *get_renames(struct merge_options *opt, + const char *branch, struct diff_queue_struct *pairs, struct hashmap *dir_renames, struct hashmap *dir_rename_exclusions, @@ -2585,6 +2583,7 @@ static struct string_list *get_renames(struct merge_options *opt, re->processed = 0; re->add_turned_into_rename = 0; re->pair = pair; + re->branch = branch; item = string_list_lookup(entries, re->pair->one->path); if (!item) re->src_entry = insert_stage_data(re->pair->one->path, @@ -2639,7 +2638,6 @@ static int process_renames(struct merge_options *opt, for (i = 0, j = 0; i < a_renames->nr || j < b_renames->nr;) { struct string_list *renames1, *renames2Dst; struct rename *ren1 = NULL, *ren2 = NULL; - const char *branch1, *branch2; const char *ren1_src, *ren1_dst; struct string_list_item *lookup; @@ -2660,13 +2658,9 @@ static int process_renames(struct merge_options *opt, if (ren1) { renames1 = a_renames; renames2Dst = &b_by_dst; - branch1 = opt->branch1; - branch2 = opt->branch2; } else { renames1 = b_renames; renames2Dst = &a_by_dst; - branch1 = opt->branch2; - branch2 = opt->branch1; SWAP(ren2, ren1); } @@ -2706,12 +2700,7 @@ static int process_renames(struct merge_options *opt, ren1->pair->two, ren2->pair->two); } - setup_rename_conflict_info(rename_type, - opt, - ren1, - ren2, - branch1, - branch2); + setup_rename_conflict_info(rename_type, opt, ren1, ren2); } else if ((lookup = string_list_lookup(renames2Dst, ren1_dst))) { /* Two different files renamed to the same thing */ char *ren2_dst; @@ -2730,11 +2719,7 @@ static int process_renames(struct merge_options *opt, ren2->src_entry->processed = 1; setup_rename_conflict_info(RENAME_TWO_FILES_TO_ONE, - opt, - ren1, - ren2, - branch1, - branch2); + opt, ren1, ren2); } else { /* Renamed in 1, maybe changed in 2 */ @@ -2769,18 +2754,10 @@ static int process_renames(struct merge_options *opt, if (oid_eq(&src_other.oid, &null_oid) && ren1->add_turned_into_rename) { setup_rename_conflict_info(RENAME_VIA_DIR, - opt, - ren1, - NULL, - branch1, - branch2); + opt, ren1, NULL); } else if (oid_eq(&src_other.oid, &null_oid)) { setup_rename_conflict_info(RENAME_DELETE, - opt, - ren1, - NULL, - branch1, - branch2); + opt, ren1, NULL); } else if ((dst_other.mode == ren1->pair->two->mode) && oid_eq(&dst_other.oid, &ren1->pair->two->oid)) { /* @@ -2807,11 +2784,7 @@ static int process_renames(struct merge_options *opt, * file, then the merge will be clean. */ setup_rename_conflict_info(RENAME_ADD, - opt, - ren1, - NULL, - branch1, - branch2); + opt, ren1, NULL); } else try_merge = 1; @@ -2831,11 +2804,7 @@ static int process_renames(struct merge_options *opt, } update_entry(ren1->dst_entry, o, a, b); setup_rename_conflict_info(RENAME_NORMAL, - opt, - ren1, - NULL, - branch1, - NULL); + opt, ren1, NULL); } } } @@ -2904,13 +2873,13 @@ static int detect_and_process_renames(struct merge_options *opt, dir_rename_init(dir_re_merge); } - ri->head_renames = get_renames(opt, head_pairs, + ri->head_renames = get_renames(opt, opt->branch1, head_pairs, dir_re_merge, dir_re_head, head, common, head, merge, entries, &clean); if (clean < 0) goto cleanup; - ri->merge_renames = get_renames(opt, merge_pairs, + ri->merge_renames = get_renames(opt, opt->branch2, merge_pairs, dir_re_head, dir_re_merge, merge, common, head, merge, entries, &clean); @@ -3072,14 +3041,14 @@ static int handle_content_merge(struct merge_options *opt, if (ci) { struct diff_filepair *pair1 = ci->ren1->pair; - path1 = (opt->branch1 == ci->branch1) ? + path1 = (opt->branch1 == ci->ren1->branch) ? pair1->two->path : pair1->one->path; /* If ci->ren2->pair != NULL, we are in * RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a * normal rename. */ path2 = ((ci->ren2 && ci->ren2->pair) || - opt->branch2 == ci->branch1) ? + opt->branch2 == ci->ren1->branch) ? pair1->two->path : pair1->one->path; one.path = pair1->one->path; a.path = (char *)path1; @@ -3157,7 +3126,7 @@ static int handle_content_merge(struct merge_options *opt, } } - new_path = unique_path(opt, path, ci->branch1); + new_path = unique_path(opt, path, ci->ren1->branch); if (is_dirty) { output(opt, 1, _("Refusing to lose dirty file at %s"), path); @@ -3215,7 +3184,8 @@ static int process_entry(struct merge_options *opt, break; case RENAME_VIA_DIR: clean_merge = 1; - if (handle_rename_via_dir(opt, ci->ren1->pair, ci->branch1)) + if (handle_rename_via_dir(opt, ci->ren1->pair, + ci->ren1->branch)) clean_merge = -1; break; case RENAME_ADD: @@ -3230,7 +3200,8 @@ static int process_entry(struct merge_options *opt, case RENAME_DELETE: clean_merge = 0; if (handle_rename_delete(opt, ci->ren1->pair, - ci->branch1, ci->branch2)) + ci->ren1->branch, + ci->ren1->branch == opt->branch1 ? opt->branch2 : opt->branch1)) clean_merge = -1; break; case RENAME_ONE_FILE_TO_TWO: From patchwork Fri Apr 5 15:00:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887569 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B859F1515 for ; Fri, 5 Apr 2019 15:01:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9C08A28B6B for ; Fri, 5 Apr 2019 15:01:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A83128B78; Fri, 5 Apr 2019 15:01:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 35B1728B6B for ; Fri, 5 Apr 2019 15:01:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731315AbfDEPA6 (ORCPT ); Fri, 5 Apr 2019 11:00:58 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45622 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726291AbfDEPA5 (ORCPT ); Fri, 5 Apr 2019 11:00:57 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFP001918; Fri, 5 Apr 2019 08:00:45 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:44 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:43 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:40 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 68D09220CB2E; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 10/15] merge-recursive: cleanup handle_rename_* function signatures Date: Fri, 5 Apr 2019 08:00:21 -0700 Message-ID: <20190405150026.5260-11-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=13 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=844 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Instead of passing various bits and pieces of 'ci', just pass it directly. Signed-off-by: Elijah Newren --- merge-recursive.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index f85c276f35..ada1c19ed2 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1357,8 +1357,7 @@ static int merge_mode_and_contents(struct merge_options *opt, } static int handle_rename_via_dir(struct merge_options *opt, - struct diff_filepair *pair, - const char *rename_branch) + struct rename_conflict_info *ci) { /* * Handle file adds that need to be renamed due to directory rename @@ -1366,10 +1365,11 @@ static int handle_rename_via_dir(struct merge_options *opt, * there is no content merge to do; just move the file into the * desired final location. */ - const struct diff_filespec *dest = pair->two; + const struct rename *ren = ci->ren1; + const struct diff_filespec *dest = ren->pair->two; if (!opt->call_depth && would_lose_untracked(opt, dest->path)) { - char *alt_path = unique_path(opt, dest->path, rename_branch); + char *alt_path = unique_path(opt, dest->path, ren->branch); output(opt, 1, _("Error: Refusing to lose untracked file at %s; " "writing to %s instead."), @@ -1383,8 +1383,8 @@ static int handle_rename_via_dir(struct merge_options *opt, return -1; free(alt_path); return update_stages(opt, dest->path, NULL, - rename_branch == opt->branch1 ? dest : NULL, - rename_branch == opt->branch1 ? NULL : dest); + ren->branch == opt->branch1 ? dest : NULL, + ren->branch == opt->branch1 ? NULL : dest); } /* Update dest->path both in index and in worktree */ @@ -1476,12 +1476,14 @@ static int handle_change_delete(struct merge_options *opt, } static int handle_rename_delete(struct merge_options *opt, - struct diff_filepair *pair, - const char *rename_branch, - const char *delete_branch) + struct rename_conflict_info *ci) { - const struct diff_filespec *orig = pair->one; - const struct diff_filespec *dest = pair->two; + const struct rename *ren = ci->ren1; + const struct diff_filespec *orig = ren->pair->one; + const struct diff_filespec *dest = ren->pair->two; + const char *rename_branch = ren->branch; + const char *delete_branch = (opt->branch1 == ren->branch ? + opt->branch2 : opt->branch1); if (handle_change_delete(opt, opt->call_depth ? orig->path : dest->path, @@ -3184,8 +3186,7 @@ static int process_entry(struct merge_options *opt, break; case RENAME_VIA_DIR: clean_merge = 1; - if (handle_rename_via_dir(opt, ci->ren1->pair, - ci->ren1->branch)) + if (handle_rename_via_dir(opt, ci)) clean_merge = -1; break; case RENAME_ADD: @@ -3199,9 +3200,7 @@ static int process_entry(struct merge_options *opt, break; case RENAME_DELETE: clean_merge = 0; - if (handle_rename_delete(opt, ci->ren1->pair, - ci->ren1->branch, - ci->ren1->branch == opt->branch1 ? opt->branch2 : opt->branch1)) + if (handle_rename_delete(opt, ci)) clean_merge = -1; break; case RENAME_ONE_FILE_TO_TWO: From patchwork Fri Apr 5 15:00:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887575 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7A03E1515 for ; Fri, 5 Apr 2019 15:01:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F0CA28B6E for ; Fri, 5 Apr 2019 15:01:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4357428B79; Fri, 5 Apr 2019 15:01:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F399F28B6E for ; Fri, 5 Apr 2019 15:01:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731393AbfDEPBR (ORCPT ); Fri, 5 Apr 2019 11:01:17 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40246 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731383AbfDEPBO (ORCPT ); Fri, 5 Apr 2019 11:01:14 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSnx001751; Fri, 5 Apr 2019 08:00:48 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:46 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:40 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:40 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 794C7220CB2F; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 11/15] merge-recursive: switch from (oid,mode) pairs to a diff_filespec Date: Fri, 5 Apr 2019 08:00:22 -0700 Message-ID: <20190405150026.5260-12-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=13 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There was a significant inconsistency in the various parts of the API used in merge-recursive; many places used a pair of (oid, mode) to track file version/contents, while other parts used a diff_filespec (which have an oid and mode embedded in it). This inconsistency caused lots of places to need to pack and unpack data to call into other functions. This has been the subject of some past cleanups (see e.g. commit 0270a07ad0b2 ("merge-recursive: remove final remaining caller of merge_file_one()", 2018-09-19)), but let's just remove the underlying mess altogether by switching to use diff_filespec. Signed-off-by: Elijah Newren --- merge-recursive.c | 483 +++++++++++++++++++++------------------------- 1 file changed, 215 insertions(+), 268 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index ada1c19ed2..1d2c9e1772 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -201,10 +201,7 @@ enum rename_type { * for these (temporary) data. */ struct stage_data { - struct { - unsigned short mode; - struct object_id oid; - } stages[4]; + struct diff_filespec stages[4]; /* mostly for oid & mode; maybe path */ struct rename_conflict_info *rename_conflict_info; unsigned processed:1; }; @@ -269,7 +266,6 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, ci->ren1->dst_entry->processed = 0; ci->ren1->dst_entry->rename_conflict_info = ci; - if (ren2) { ci->ren2->dst_entry->rename_conflict_info = ci; } @@ -326,14 +322,14 @@ static void output_commit_title(struct merge_options *opt, struct commit *commit } static int add_cacheinfo(struct merge_options *opt, - unsigned int mode, const struct object_id *oid, + const struct diff_filespec *blob, const char *path, int stage, int refresh, int options) { struct index_state *istate = opt->repo->index; struct cache_entry *ce; int ret; - ce = make_cache_entry(istate, mode, oid ? oid : &null_oid, path, stage, 0); + ce = make_cache_entry(istate, blob->mode, &blob->oid, path, stage, 0); if (!ce) return err(opt, _("add_cacheinfo failed for path '%s'; merge aborting."), path); @@ -464,15 +460,14 @@ static void get_files_dirs(struct merge_options *opt, struct tree *tree) static int get_tree_entry_if_blob(const struct object_id *tree, const char *path, - struct object_id *hashy, - unsigned short *mode_o) + struct diff_filespec *dfs) { int ret; - ret = get_tree_entry(tree, path, hashy, mode_o); - if (S_ISDIR(*mode_o)) { - oidcpy(hashy, &null_oid); - *mode_o = 0; + ret = get_tree_entry(tree, path, &dfs->oid, &dfs->mode); + if (S_ISDIR(dfs->mode)) { + oidcpy(&dfs->oid, &null_oid); + dfs->mode = 0; } return ret; } @@ -487,12 +482,9 @@ static struct stage_data *insert_stage_data(const char *path, { struct string_list_item *item; struct stage_data *e = xcalloc(1, sizeof(struct stage_data)); - get_tree_entry_if_blob(&o->object.oid, path, - &e->stages[1].oid, &e->stages[1].mode); - get_tree_entry_if_blob(&a->object.oid, path, - &e->stages[2].oid, &e->stages[2].mode); - get_tree_entry_if_blob(&b->object.oid, path, - &e->stages[3].oid, &e->stages[3].mode); + get_tree_entry_if_blob(&o->object.oid, path, &e->stages[1]); + get_tree_entry_if_blob(&a->object.oid, path, &e->stages[2]); + get_tree_entry_if_blob(&b->object.oid, path, &e->stages[3]); item = string_list_insert(entries, path); item->util = e; return e; @@ -648,13 +640,13 @@ static int update_stages(struct merge_options *opt, const char *path, if (remove_file_from_index(opt->repo->index, path)) return -1; if (o) - if (add_cacheinfo(opt, o->mode, &o->oid, path, 1, 0, options)) + if (add_cacheinfo(opt, o, path, 1, 0, options)) return -1; if (a) - if (add_cacheinfo(opt, a->mode, &a->oid, path, 2, 0, options)) + if (add_cacheinfo(opt, a, path, 2, 0, options)) return -1; if (b) - if (add_cacheinfo(opt, b->mode, &b->oid, path, 3, 0, options)) + if (add_cacheinfo(opt, b, path, 3, 0, options)) return -1; return 0; } @@ -767,7 +759,7 @@ static int dir_in_way(struct index_state *istate, const char *path, * and its oid and mode match the specified values */ static int was_tracked_and_matches(struct merge_options *opt, const char *path, - const struct object_id *oid, unsigned mode) + const struct diff_filespec *blob) { int pos = index_name_pos(&opt->orig_index, path, strlen(path)); struct cache_entry *ce; @@ -778,7 +770,7 @@ static int was_tracked_and_matches(struct merge_options *opt, const char *path, /* See if the file we were tracking before matches */ ce = opt->orig_index.cache[pos]; - return (oid_eq(&ce->oid, oid) && ce->ce_mode == mode); + return (oid_eq(&ce->oid, &blob->oid) && ce->ce_mode == blob->mode); } /* @@ -903,8 +895,7 @@ static int make_room_for_path(struct merge_options *opt, const char *path) } static int update_file_flags(struct merge_options *opt, - const struct object_id *oid, - unsigned mode, + const struct diff_filespec *contents, const char *path, int update_cache, int update_wd) @@ -919,7 +910,7 @@ static int update_file_flags(struct merge_options *opt, void *buf; unsigned long size; - if (S_ISGITLINK(mode)) { + if (S_ISGITLINK(contents->mode)) { /* * We may later decide to recursively descend into * the submodule directory and update its index @@ -929,14 +920,16 @@ static int update_file_flags(struct merge_options *opt, goto update_index; } - buf = read_object_file(oid, &type, &size); + buf = read_object_file(&contents->oid, &type, &size); if (!buf) - return err(opt, _("cannot read object %s '%s'"), oid_to_hex(oid), path); + return err(opt, _("cannot read object %s '%s'"), + oid_to_hex(&contents->oid), path); if (type != OBJ_BLOB) { - ret = err(opt, _("blob expected for %s '%s'"), oid_to_hex(oid), path); + ret = err(opt, _("blob expected for %s '%s'"), + oid_to_hex(&contents->oid), path); goto free_buf; } - if (S_ISREG(mode)) { + if (S_ISREG(contents->mode)) { struct strbuf strbuf = STRBUF_INIT; if (convert_to_working_tree(opt->repo->index, path, buf, size, &strbuf)) { free(buf); @@ -949,12 +942,11 @@ static int update_file_flags(struct merge_options *opt, update_wd = 0; goto free_buf; } - if (S_ISREG(mode) || (!has_symlinks && S_ISLNK(mode))) { + if (S_ISREG(contents->mode) || + (!has_symlinks && S_ISLNK(contents->mode))) { int fd; - if (mode & 0100) - mode = 0777; - else - mode = 0666; + int mode = (contents->mode & 0100 ? 0777 : 0666); + fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode); if (fd < 0) { ret = err(opt, _("failed to open '%s': %s"), @@ -963,7 +955,7 @@ static int update_file_flags(struct merge_options *opt, } write_in_full(fd, buf, size); close(fd); - } else if (S_ISLNK(mode)) { + } else if (S_ISLNK(contents->mode)) { char *lnk = xmemdupz(buf, size); safe_create_leading_directories_const(path); unlink(path); @@ -974,13 +966,13 @@ static int update_file_flags(struct merge_options *opt, } else ret = err(opt, _("do not know what to do with %06o %s '%s'"), - mode, oid_to_hex(oid), path); + contents->mode, oid_to_hex(&contents->oid), path); free_buf: free(buf); } update_index: if (!ret && update_cache) - if (add_cacheinfo(opt, mode, oid, path, 0, update_wd, + if (add_cacheinfo(opt, contents, path, 0, update_wd, ADD_CACHE_OK_TO_ADD)) return -1; return ret; @@ -988,18 +980,17 @@ static int update_file_flags(struct merge_options *opt, static int update_file(struct merge_options *opt, int clean, - const struct object_id *oid, - unsigned mode, + const struct diff_filespec *contents, const char *path) { - return update_file_flags(opt, oid, mode, path, opt->call_depth || clean, !opt->call_depth); + return update_file_flags(opt, contents, path, + opt->call_depth || clean, !opt->call_depth); } /* Low level file merging, update and removal */ struct merge_file_info { - struct object_id oid; - unsigned mode; + struct diff_filespec blob; /* mostly use oid & mode; sometimes path */ unsigned clean:1, merge:1; }; @@ -1039,6 +1030,7 @@ static int merge_3way(struct merge_options *opt, } } + assert(a->path && b->path); if (strcmp(a->path, b->path) || (opt->ancestor != NULL && strcmp(a->path, o->path) != 0)) { base_name = opt->ancestor == NULL ? NULL : @@ -1140,6 +1132,11 @@ static void print_commit(struct commit *commit) strbuf_release(&sb); } +static int is_valid(const struct diff_filespec *dfs) +{ + return dfs->mode != 0 && !is_null_oid(&dfs->oid); +} + static int merge_submodule(struct merge_options *opt, struct object_id *result, const char *path, const struct object_id *base, const struct object_id *a, @@ -1278,11 +1275,11 @@ static int merge_mode_and_contents(struct merge_options *opt, if ((S_IFMT & a->mode) != (S_IFMT & b->mode)) { result->clean = 0; if (S_ISREG(a->mode)) { - result->mode = a->mode; - oidcpy(&result->oid, &a->oid); + result->blob.mode = a->mode; + oidcpy(&result->blob.oid, &a->oid); } else { - result->mode = b->mode; - oidcpy(&result->oid, &b->oid); + result->blob.mode = b->mode; + oidcpy(&result->blob.oid, &b->oid); } } else { if (!oid_eq(&a->oid, &o->oid) && !oid_eq(&b->oid, &o->oid)) @@ -1292,9 +1289,9 @@ static int merge_mode_and_contents(struct merge_options *opt, * Merge modes */ if (a->mode == b->mode || a->mode == o->mode) - result->mode = b->mode; + result->blob.mode = b->mode; else { - result->mode = a->mode; + result->blob.mode = a->mode; if (b->mode != o->mode) { result->clean = 0; result->merge = 1; @@ -1302,9 +1299,9 @@ static int merge_mode_and_contents(struct merge_options *opt, } if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &o->oid)) - oidcpy(&result->oid, &b->oid); + oidcpy(&result->blob.oid, &b->oid); else if (oid_eq(&b->oid, &o->oid)) - oidcpy(&result->oid, &a->oid); + oidcpy(&result->blob.oid, &a->oid); else if (S_ISREG(a->mode)) { mmbuffer_t result_buf; int ret = 0, merge_status; @@ -1318,7 +1315,7 @@ static int merge_mode_and_contents(struct merge_options *opt, if (!ret && write_object_file(result_buf.ptr, result_buf.size, - blob_type, &result->oid)) + blob_type, &result->blob.oid)) ret = err(opt, _("Unable to add %s to database"), a->path); @@ -1327,7 +1324,7 @@ static int merge_mode_and_contents(struct merge_options *opt, return ret; result->clean = (merge_status == 0); } else if (S_ISGITLINK(a->mode)) { - result->clean = merge_submodule(opt, &result->oid, + result->clean = merge_submodule(opt, &result->blob.oid, o->path, &o->oid, &a->oid, @@ -1335,15 +1332,15 @@ static int merge_mode_and_contents(struct merge_options *opt, } else if (S_ISLNK(a->mode)) { switch (opt->recursive_variant) { case MERGE_RECURSIVE_NORMAL: - oidcpy(&result->oid, &a->oid); + oidcpy(&result->blob.oid, &a->oid); if (!oid_eq(&a->oid, &b->oid)) result->clean = 0; break; case MERGE_RECURSIVE_OURS: - oidcpy(&result->oid, &a->oid); + oidcpy(&result->blob.oid, &a->oid); break; case MERGE_RECURSIVE_THEIRS: - oidcpy(&result->oid, &b->oid); + oidcpy(&result->blob.oid, &b->oid); break; } } else @@ -1379,7 +1376,7 @@ static int handle_rename_via_dir(struct merge_options *opt, * index. Instead, write to dest->path for the index but * only at the higher appropriate stage. */ - if (update_file(opt, 0, &dest->oid, dest->mode, alt_path)) + if (update_file(opt, 0, dest, alt_path)) return -1; free(alt_path); return update_stages(opt, dest->path, NULL, @@ -1388,16 +1385,15 @@ static int handle_rename_via_dir(struct merge_options *opt, } /* Update dest->path both in index and in worktree */ - if (update_file(opt, 1, &dest->oid, dest->mode, dest->path)) + if (update_file(opt, 1, dest, dest->path)) return -1; return 0; } static int handle_change_delete(struct merge_options *opt, const char *path, const char *old_path, - const struct object_id *o_oid, int o_mode, - const struct object_id *changed_oid, - int changed_mode, + const struct diff_filespec *o, + const struct diff_filespec *changed, const char *change_branch, const char *delete_branch, const char *change, const char *change_past) @@ -1419,7 +1415,7 @@ static int handle_change_delete(struct merge_options *opt, */ ret = remove_file_from_index(opt->repo->index, path); if (!ret) - ret = update_file(opt, 0, o_oid, o_mode, update_path); + ret = update_file(opt, 0, o, update_path); } else { /* * Despite the four nearly duplicate messages and argument @@ -1468,7 +1464,7 @@ static int handle_change_delete(struct merge_options *opt, * and update_wd=0, but that's a no-op. */ if (change_branch != opt->branch1 || alt_path) - ret = update_file(opt, 0, changed_oid, changed_mode, update_path); + ret = update_file(opt, 0, changed, update_path); } free(alt_path); @@ -1488,8 +1484,7 @@ static int handle_rename_delete(struct merge_options *opt, if (handle_change_delete(opt, opt->call_depth ? orig->path : dest->path, opt->call_depth ? NULL : orig->path, - &orig->oid, orig->mode, - &dest->oid, dest->mode, + orig, dest, rename_branch, delete_branch, _("rename"), _("renamed"))) return -1; @@ -1502,31 +1497,16 @@ static int handle_rename_delete(struct merge_options *opt, rename_branch == opt->branch1 ? NULL : dest); } -static struct diff_filespec *filespec_from_entry(struct diff_filespec *target, - struct stage_data *entry, - int stage) -{ - struct object_id *oid = &entry->stages[stage].oid; - unsigned mode = entry->stages[stage].mode; - if (mode == 0 || is_null_oid(oid)) - return NULL; - oidcpy(&target->oid, oid); - target->mode = mode; - return target; -} - static int handle_file_collision(struct merge_options *opt, const char *collide_path, const char *prev_path1, const char *prev_path2, const char *branch1, const char *branch2, - const struct object_id *a_oid, - unsigned int a_mode, - const struct object_id *b_oid, - unsigned int b_mode) + struct diff_filespec *a, + struct diff_filespec *b) { struct merge_file_info mfi; - struct diff_filespec null, a, b; + struct diff_filespec null; char *alt_path = NULL; const char *update_path = collide_path; @@ -1540,29 +1520,28 @@ static int handle_file_collision(struct merge_options *opt, return handle_file_collision(opt, collide_path, prev_path2, prev_path1, branch2, branch1, - b_oid, b_mode, - a_oid, a_mode); + b, a); } /* * In the recursive case, we just opt to undo renames */ if (opt->call_depth && (prev_path1 || prev_path2)) { - /* Put first file (a_oid, a_mode) in its original spot */ + /* Put first file (a->oid, a->mode) in its original spot */ if (prev_path1) { - if (update_file(opt, 1, a_oid, a_mode, prev_path1)) + if (update_file(opt, 1, a, prev_path1)) return -1; } else { - if (update_file(opt, 1, a_oid, a_mode, collide_path)) + if (update_file(opt, 1, a, collide_path)) return -1; } - /* Put second file (b_oid, b_mode) in its original spot */ + /* Put second file (b->oid, b->mode) in its original spot */ if (prev_path2) { - if (update_file(opt, 1, b_oid, b_mode, prev_path2)) + if (update_file(opt, 1, b, prev_path2)) return -1; } else { - if (update_file(opt, 1, b_oid, b_mode, collide_path)) + if (update_file(opt, 1, b, collide_path)) return -1; } @@ -1616,26 +1595,18 @@ static int handle_file_collision(struct merge_options *opt, } /* Store things in diff_filespecs for functions that need it */ - memset(&a, 0, sizeof(struct diff_filespec)); - memset(&b, 0, sizeof(struct diff_filespec)); - null.path = a.path = b.path = (char *)collide_path; + null.path = (char *)collide_path; oidcpy(&null.oid, &null_oid); null.mode = 0; - oidcpy(&a.oid, a_oid); - a.mode = a_mode; - a.oid_valid = 1; - oidcpy(&b.oid, b_oid); - b.mode = b_mode; - b.oid_valid = 1; - - if (merge_mode_and_contents(opt, &null, &a, &b, collide_path, + + if (merge_mode_and_contents(opt, &null, a, b, collide_path, branch1, branch2, opt->call_depth * 2, &mfi)) return -1; mfi.clean &= !alt_path; - if (update_file(opt, mfi.clean, &mfi.oid, mfi.mode, update_path)) + if (update_file(opt, mfi.clean, &mfi.blob, update_path)) return -1; if (!mfi.clean && !opt->call_depth && - update_stages(opt, collide_path, NULL, &a, &b)) + update_stages(opt, collide_path, NULL, a, b)) return -1; free(alt_path); /* @@ -1654,7 +1625,6 @@ static int handle_rename_add(struct merge_options *opt, /* a was renamed to c, and a separate c was added. */ struct diff_filespec *a = ci->ren1->pair->one; struct diff_filespec *c = ci->ren1->pair->two; - struct diff_filespec tmp; char *path = c->path; char *prev_path_desc; struct merge_file_info mfi; @@ -1669,23 +1639,21 @@ static int handle_rename_add(struct merge_options *opt, a->path, c->path, rename_branch, c->path, add_branch); - filespec_from_entry(&tmp, ci->ren1->src_entry, other_stage); - tmp.path = a->path; - prev_path_desc = xstrfmt("version of %s from %s", path, a->path); - if (merge_mode_and_contents(opt, a, c, &tmp, + if (merge_mode_and_contents(opt, a, c, + &ci->ren1->src_entry->stages[other_stage], prev_path_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi)) return -1; free(prev_path_desc); + ci->ren1->dst_entry->stages[other_stage].path = mfi.blob.path = c->path; return handle_file_collision(opt, c->path, a->path, NULL, rename_branch, add_branch, - &mfi.oid, mfi.mode, - &ci->ren1->dst_entry->stages[other_stage].oid, - ci->ren1->dst_entry->stages[other_stage].mode); + &mfi.blob, + &ci->ren1->dst_entry->stages[other_stage]); } static char *find_path_for_conflict(struct merge_options *opt, @@ -1714,7 +1682,6 @@ static int handle_rename_rename_1to2(struct merge_options *opt, { /* One file was renamed in both branches, but to different names. */ struct merge_file_info mfi; - struct diff_filespec other; struct diff_filespec *add; struct diff_filespec *o = ci->ren1->pair->one; struct diff_filespec *a = ci->ren1->pair->two; @@ -1743,7 +1710,7 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * pathname and then either rename the add-source file to that * unique path, or use that unique path instead of src here. */ - if (update_file(opt, 0, &mfi.oid, mfi.mode, o->path)) + if (update_file(opt, 0, &mfi.blob, o->path)) return -1; /* @@ -1754,16 +1721,16 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * such cases, we should keep the added file around, * resolving the conflict at that path in its favor. */ - add = filespec_from_entry(&other, ci->ren1->dst_entry, 2 ^ 1); - if (add) { - if (update_file(opt, 0, &add->oid, add->mode, a->path)) + add = &ci->ren1->dst_entry->stages[2 ^ 1]; + if (is_valid(add)) { + if (update_file(opt, 0, add, a->path)) return -1; } else remove_file_from_index(opt->repo->index, a->path); - add = filespec_from_entry(&other, ci->ren2->dst_entry, 3 ^ 1); - if (add) { - if (update_file(opt, 0, &add->oid, add->mode, b->path)) + add = &ci->ren2->dst_entry->stages[3 ^ 1]; + if (is_valid(add)) { + if (update_file(opt, 0, add, b->path)) return -1; } else @@ -1774,40 +1741,42 @@ static int handle_rename_rename_1to2(struct merge_options *opt, * rename/add collision. If not, we can write the file out * to the specified location. */ - add = filespec_from_entry(&other, ci->ren1->dst_entry, 2 ^ 1); - if (add) { + add = &ci->ren1->dst_entry->stages[2 ^ 1]; + if (is_valid(add)) { + add->path = mfi.blob.path = a->path; if (handle_file_collision(opt, a->path, NULL, NULL, ci->ren1->branch, ci->ren2->branch, - &mfi.oid, mfi.mode, - &add->oid, add->mode) < 0) + &mfi.blob, add) < 0) return -1; } else { char *new_path = find_path_for_conflict(opt, a->path, ci->ren1->branch, ci->ren2->branch); - if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : a->path)) + if (update_file(opt, 0, &mfi.blob, + new_path ? new_path : a->path)) return -1; free(new_path); if (update_stages(opt, a->path, NULL, a, NULL)) return -1; } - add = filespec_from_entry(&other, ci->ren2->dst_entry, 3 ^ 1); - if (add) { + add = &ci->ren2->dst_entry->stages[3 ^ 1]; + if (is_valid(add)) { + add->path = mfi.blob.path = b->path; if (handle_file_collision(opt, b->path, NULL, NULL, ci->ren1->branch, ci->ren2->branch, - &add->oid, add->mode, - &mfi.oid, mfi.mode) < 0) + add, &mfi.blob) < 0) return -1; } else { char *new_path = find_path_for_conflict(opt, b->path, ci->ren2->branch, ci->ren1->branch); - if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path ? new_path : b->path)) + if (update_file(opt, 0, &mfi.blob, + new_path ? new_path : b->path)) return -1; free(new_path); if (update_stages(opt, b->path, NULL, NULL, b)) @@ -1826,12 +1795,12 @@ static int handle_rename_rename_2to1(struct merge_options *opt, struct diff_filespec *b = ci->ren2->pair->one; struct diff_filespec *c1 = ci->ren1->pair->two; struct diff_filespec *c2 = ci->ren2->pair->two; - struct diff_filespec tmp1, tmp2; char *path = c1->path; /* == c2->path */ char *path_side_1_desc; char *path_side_2_desc; struct merge_file_info mfi_c1; struct merge_file_info mfi_c2; + int ostage1, ostage2; output(opt, 1, _("CONFLICT (rename/rename): " "Rename %s->%s in %s. " @@ -1839,27 +1808,31 @@ static int handle_rename_rename_2to1(struct merge_options *opt, a->path, c1->path, ci->ren1->branch, b->path, c2->path, ci->ren2->branch); - filespec_from_entry(&tmp1, ci->ren1->src_entry, 3); - tmp1.path = a->path; - filespec_from_entry(&tmp2, ci->ren2->src_entry, 2); - tmp2.path = b->path; - path_side_1_desc = xstrfmt("version of %s from %s", path, a->path); path_side_2_desc = xstrfmt("version of %s from %s", path, b->path); - if (merge_mode_and_contents(opt, a, c1, &tmp1, path_side_1_desc, + ostage1 = ci->ren1->branch == opt->branch1 ? 3 : 2; + ostage2 = ostage1 ^ 1; + ci->ren1->src_entry->stages[ostage1].path = a->path; + ci->ren2->src_entry->stages[ostage2].path = b->path; + if (merge_mode_and_contents(opt, a, c1, + &ci->ren1->src_entry->stages[ostage1], + path_side_1_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi_c1) || - merge_mode_and_contents(opt, b, &tmp2, c2, path_side_2_desc, + merge_mode_and_contents(opt, b, + &ci->ren2->src_entry->stages[ostage2], + c2, path_side_2_desc, opt->branch1, opt->branch2, 1 + opt->call_depth * 2, &mfi_c2)) return -1; free(path_side_1_desc); free(path_side_2_desc); + mfi_c1.blob.path = path; + mfi_c2.blob.path = path; return handle_file_collision(opt, path, a->path, b->path, ci->ren1->branch, ci->ren2->branch, - &mfi_c1.oid, mfi_c1.mode, - &mfi_c2.oid, mfi_c2.mode); + &mfi_c1.blob, &mfi_c2.blob); } /* @@ -2722,7 +2695,6 @@ static int process_renames(struct merge_options *opt, setup_rename_conflict_info(RENAME_TWO_FILES_TO_ONE, opt, ren1, ren2); - } else { /* Renamed in 1, maybe changed in 2 */ /* we only use sha1 and mode of these */ @@ -2771,8 +2743,7 @@ static int process_renames(struct merge_options *opt, * update_file(). */ if (update_file_flags(opt, - &ren1->pair->two->oid, - ren1->pair->two->mode, + ren1->pair->two, ren1_dst, 1, /* update_cache */ 0 /* update_wd */)) @@ -2923,11 +2894,6 @@ static void final_cleanup_renames(struct rename_info *re_info) final_cleanup_rename(re_info->merge_renames); } -static struct object_id *stage_oid(const struct object_id *oid, unsigned mode) -{ - return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid; -} - static int read_oid_strbuf(struct merge_options *opt, const struct object_id *oid, struct strbuf *dst) @@ -2947,10 +2913,8 @@ static int read_oid_strbuf(struct merge_options *opt, } static int blob_unchanged(struct merge_options *opt, - const struct object_id *o_oid, - unsigned o_mode, - const struct object_id *a_oid, - unsigned a_mode, + const struct diff_filespec *o, + const struct diff_filespec *a, int renormalize, const char *path) { struct strbuf obuf = STRBUF_INIT; @@ -2958,16 +2922,15 @@ static int blob_unchanged(struct merge_options *opt, int ret = 0; /* assume changed for safety */ const struct index_state *idx = opt->repo->index; - if (a_mode != o_mode) + if (a->mode != o->mode) return 0; - if (oid_eq(o_oid, a_oid)) + if (oid_eq(&o->oid, &a->oid)) return 1; if (!renormalize) return 0; - assert(o_oid && a_oid); - if (read_oid_strbuf(opt, o_oid, &obuf) || - read_oid_strbuf(opt, a_oid, &abuf)) + if (read_oid_strbuf(opt, &o->oid, &obuf) || + read_oid_strbuf(opt, &a->oid, &abuf)) goto error_return; /* * Note: binary | is used so that both renormalizations are @@ -2986,30 +2949,26 @@ static int blob_unchanged(struct merge_options *opt, static int handle_modify_delete(struct merge_options *opt, const char *path, - struct object_id *o_oid, int o_mode, - struct object_id *a_oid, int a_mode, - struct object_id *b_oid, int b_mode) + const struct diff_filespec *o, + const struct diff_filespec *a, + const struct diff_filespec *b) { const char *modify_branch, *delete_branch; - struct object_id *changed_oid; - int changed_mode; + const struct diff_filespec *changed; - if (a_oid) { + if (is_valid(a)) { modify_branch = opt->branch1; delete_branch = opt->branch2; - changed_oid = a_oid; - changed_mode = a_mode; + changed = a; } else { modify_branch = opt->branch2; delete_branch = opt->branch1; - changed_oid = b_oid; - changed_mode = b_mode; + changed = b; } return handle_change_delete(opt, path, NULL, - o_oid, o_mode, - changed_oid, changed_mode, + o, changed, modify_branch, delete_branch, _("modify"), _("modified")); } @@ -3017,50 +2976,24 @@ static int handle_modify_delete(struct merge_options *opt, static int handle_content_merge(struct merge_options *opt, const char *path, int is_dirty, - struct object_id *o_oid, int o_mode, - struct object_id *a_oid, int a_mode, - struct object_id *b_oid, int b_mode, + const struct diff_filespec *o, + const struct diff_filespec *a, + const struct diff_filespec *b, struct rename_conflict_info *ci) { const char *reason = _("content"); - const char *path1 = NULL, *path2 = NULL; struct merge_file_info mfi; - struct diff_filespec one, a, b; unsigned df_conflict_remains = 0; - if (!o_oid) { + if (!is_valid(o)) reason = _("add/add"); - o_oid = (struct object_id *)&null_oid; - } - one.path = a.path = b.path = (char *)path; - oidcpy(&one.oid, o_oid); - one.mode = o_mode; - oidcpy(&a.oid, a_oid); - a.mode = a_mode; - oidcpy(&b.oid, b_oid); - b.mode = b_mode; - - if (ci) { - struct diff_filepair *pair1 = ci->ren1->pair; - - path1 = (opt->branch1 == ci->ren1->branch) ? - pair1->two->path : pair1->one->path; - /* If ci->ren2->pair != NULL, we are in - * RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a - * normal rename. - */ - path2 = ((ci->ren2 && ci->ren2->pair) || - opt->branch2 == ci->ren1->branch) ? - pair1->two->path : pair1->one->path; - one.path = pair1->one->path; - a.path = (char *)path1; - b.path = (char *)path2; - - if (dir_in_way(opt->repo->index, path, !opt->call_depth, - S_ISGITLINK(pair1->two->mode))) - df_conflict_remains = 1; - } - if (merge_mode_and_contents(opt, &one, &a, &b, path, + + assert(o->path && a->path && b->path); + if (ci && dir_in_way(opt->repo->index, path, !opt->call_depth, + S_ISGITLINK(ci->ren1->pair->two->mode))) + df_conflict_remains = 1; + + if (merge_mode_and_contents(opt, o, a, b, path, opt->branch1, opt->branch2, opt->call_depth * 2, &mfi)) return -1; @@ -3071,14 +3004,13 @@ static int handle_content_merge(struct merge_options *opt, * b) The merge matches what was in HEAD (content, mode, pathname) * c) The target path is usable (i.e. not involved in D/F conflict) */ - if (mfi.clean && - was_tracked_and_matches(opt, path, &mfi.oid, mfi.mode) && + if (mfi.clean && was_tracked_and_matches(opt, path, &mfi.blob) && !df_conflict_remains) { int pos; struct cache_entry *ce; output(opt, 3, _("Skipped %s (merged same as existing)"), path); - if (add_cacheinfo(opt, mfi.mode, &mfi.oid, path, + if (add_cacheinfo(opt, &mfi.blob, path, 0, (!opt->call_depth && !is_dirty), 0)) return -1; /* @@ -3098,12 +3030,12 @@ static int handle_content_merge(struct merge_options *opt, } if (!mfi.clean) { - if (S_ISGITLINK(mfi.mode)) + if (S_ISGITLINK(mfi.blob.mode)) reason = _("submodule"); output(opt, 1, _("CONFLICT (%s): Merge conflict in %s"), reason, path); if (ci && !df_conflict_remains) - if (update_stages(opt, path, &one, &a, &b)) + if (update_stages(opt, path, o, a, b)) return -1; } @@ -3113,17 +3045,14 @@ static int handle_content_merge(struct merge_options *opt, remove_file_from_index(opt->repo->index, path); } else { if (!mfi.clean) { - if (update_stages(opt, path, &one, &a, &b)) + if (update_stages(opt, path, o, a, b)) return -1; } else { int file_from_stage2 = was_tracked(opt, path); - struct diff_filespec merged; - oidcpy(&merged.oid, &mfi.oid); - merged.mode = mfi.mode; if (update_stages(opt, path, NULL, - file_from_stage2 ? &merged : NULL, - file_from_stage2 ? NULL : &merged)) + file_from_stage2 ? &mfi.blob : NULL, + file_from_stage2 ? NULL : &mfi.blob)) return -1; } @@ -3134,28 +3063,27 @@ static int handle_content_merge(struct merge_options *opt, path); } output(opt, 1, _("Adding as %s instead"), new_path); - if (update_file(opt, 0, &mfi.oid, mfi.mode, new_path)) { + if (update_file(opt, 0, &mfi.blob, new_path)) { free(new_path); return -1; } free(new_path); mfi.clean = 0; - } else if (update_file(opt, mfi.clean, &mfi.oid, mfi.mode, path)) + } else if (update_file(opt, mfi.clean, &mfi.blob, path)) return -1; return !is_dirty && mfi.clean; } static int handle_rename_normal(struct merge_options *opt, const char *path, - struct object_id *o_oid, unsigned int o_mode, - struct object_id *a_oid, unsigned int a_mode, - struct object_id *b_oid, unsigned int b_mode, + const struct diff_filespec *o, + const struct diff_filespec *a, + const struct diff_filespec *b, struct rename_conflict_info *ci) { /* Merge the content and write it out */ return handle_content_merge(opt, path, was_dirty(opt, path), - o_oid, o_mode, a_oid, a_mode, b_oid, b_mode, - ci); + o, a, b, ci); } /* Per entry merge function */ @@ -3164,24 +3092,36 @@ static int process_entry(struct merge_options *opt, { int clean_merge = 1; int normalize = opt->renormalize; - unsigned o_mode = entry->stages[1].mode; - unsigned a_mode = entry->stages[2].mode; - unsigned b_mode = entry->stages[3].mode; - struct object_id *o_oid = stage_oid(&entry->stages[1].oid, o_mode); - struct object_id *a_oid = stage_oid(&entry->stages[2].oid, a_mode); - struct object_id *b_oid = stage_oid(&entry->stages[3].oid, b_mode); + + struct diff_filespec *o = &entry->stages[1]; + struct diff_filespec *a = &entry->stages[2]; + struct diff_filespec *b = &entry->stages[3]; + int o_valid = is_valid(o); + int a_valid = is_valid(a); + int b_valid = is_valid(b); + o->path = a->path = b->path = (char*)path; entry->processed = 1; if (entry->rename_conflict_info) { struct rename_conflict_info *ci = entry->rename_conflict_info; + struct diff_filespec *temp; + + /* + * For cases with a single rename, {o,a,b}->path have all been + * set to the rename target path; we need to set two of these + * back to the rename source. + * For rename/rename conflicts, we'll manually fix paths below. + */ + temp = (opt->branch1 == ci->ren1->branch) ? b : a; + o->path = temp->path = ci->ren1->pair->one->path; + if (ci->ren2) { + assert(opt->branch1 == ci->ren1->branch); + } + switch (ci->rename_type) { case RENAME_NORMAL: case RENAME_ONE_FILE_TO_ONE: - clean_merge = handle_rename_normal(opt, - path, - o_oid, o_mode, - a_oid, a_mode, - b_oid, b_mode, + clean_merge = handle_rename_normal(opt, path, o, a, b, ci); break; case RENAME_VIA_DIR: @@ -3204,11 +3144,27 @@ static int process_entry(struct merge_options *opt, clean_merge = -1; break; case RENAME_ONE_FILE_TO_TWO: + /* + * Manually fix up paths; note: + * ren[12]->pair->one->path are equal. + */ + o->path = ci->ren1->pair->one->path; + a->path = ci->ren1->pair->two->path; + b->path = ci->ren2->pair->two->path; + clean_merge = 0; if (handle_rename_rename_1to2(opt, ci)) clean_merge = -1; break; case RENAME_TWO_FILES_TO_ONE: + /* + * Manually fix up paths; note, + * ren[12]->pair->two->path are actually equal. + */ + o->path = NULL; + a->path = ci->ren1->pair->two->path; + b->path = ci->ren2->pair->two->path; + /* * Probably unclean merge, but if the two renamed * files merge cleanly and the two resulting files @@ -3221,57 +3177,53 @@ static int process_entry(struct merge_options *opt, entry->processed = 0; break; } - } else if (o_oid && (!a_oid || !b_oid)) { + } else if (o_valid && (!a_valid || !b_valid)) { /* Case A: Deleted in one */ - if ((!a_oid && !b_oid) || - (!b_oid && blob_unchanged(opt, o_oid, o_mode, a_oid, a_mode, normalize, path)) || - (!a_oid && blob_unchanged(opt, o_oid, o_mode, b_oid, b_mode, normalize, path))) { + if ((!a_valid && !b_valid) || + (!b_valid && blob_unchanged(opt, o, a, normalize, path)) || + (!a_valid && blob_unchanged(opt, o, b, normalize, path))) { /* Deleted in both or deleted in one and * unchanged in the other */ - if (a_oid) + if (a_valid) output(opt, 2, _("Removing %s"), path); /* do not touch working file if it did not exist */ - remove_file(opt, 1, path, !a_oid); + remove_file(opt, 1, path, !a_valid); } else { /* Modify/delete; deleted side may have put a directory in the way */ clean_merge = 0; - if (handle_modify_delete(opt, path, o_oid, o_mode, - a_oid, a_mode, b_oid, b_mode)) + if (handle_modify_delete(opt, path, o, a, b)) clean_merge = -1; } - } else if ((!o_oid && a_oid && !b_oid) || - (!o_oid && !a_oid && b_oid)) { + } else if ((!o_valid && a_valid && !b_valid) || + (!o_valid && !a_valid && b_valid)) { /* Case B: Added in one. */ /* [nothing|directory] -> ([nothing|directory], file) */ const char *add_branch; const char *other_branch; - unsigned mode; - const struct object_id *oid; const char *conf; + const struct diff_filespec *contents; - if (a_oid) { + if (a_valid) { add_branch = opt->branch1; other_branch = opt->branch2; - mode = a_mode; - oid = a_oid; + contents = a; conf = _("file/directory"); } else { add_branch = opt->branch2; other_branch = opt->branch1; - mode = b_mode; - oid = b_oid; + contents = b; conf = _("directory/file"); } if (dir_in_way(opt->repo->index, path, - !opt->call_depth && !S_ISGITLINK(a_mode), + !opt->call_depth && !S_ISGITLINK(a->mode), 0)) { char *new_path = unique_path(opt, path, add_branch); clean_merge = 0; output(opt, 1, _("CONFLICT (%s): There is a directory with name %s in %s. " "Adding %s as %s"), conf, path, other_branch, path, new_path); - if (update_file(opt, 0, oid, mode, new_path)) + if (update_file(opt, 0, contents, new_path)) clean_merge = -1; else if (opt->call_depth) remove_file_from_index(opt->repo->index, path); @@ -3279,11 +3231,11 @@ static int process_entry(struct merge_options *opt, } else { output(opt, 2, _("Adding %s"), path); /* do not overwrite file if already present */ - if (update_file_flags(opt, oid, mode, path, 1, !a_oid)) + if (update_file_flags(opt, contents, path, 1, !a_valid)) clean_merge = -1; } - } else if (a_oid && b_oid) { - if (!o_oid) { + } else if (a_valid && b_valid) { + if (!o_valid) { /* Case C: Added in both (check for same permissions) */ output(opt, 1, _("CONFLICT (add/add): Merge conflict in %s"), @@ -3292,24 +3244,19 @@ static int process_entry(struct merge_options *opt, path, NULL, NULL, opt->branch1, opt->branch2, - a_oid, a_mode, - b_oid, b_mode); + a, b); } else { /* case D: Modified in both, but differently. */ int is_dirty = 0; /* unpack_trees would have bailed if dirty */ - clean_merge = handle_content_merge(opt, path, - is_dirty, - o_oid, o_mode, - a_oid, a_mode, - b_oid, b_mode, - NULL); + clean_merge = handle_content_merge(opt, path, is_dirty, + o, a, b, NULL); } - } else if (!o_oid && !a_oid && !b_oid) { + } else if (!o_valid && !a_valid && !b_valid) { /* * this entry was deleted altogether. a_mode == 0 means * we had that path and want to actively remove it. */ - remove_file(opt, 1, path, !a_mode); + remove_file(opt, 1, path, !a->mode); } else BUG("fatal merge failure, shouldn't happen."); From patchwork Fri Apr 5 15:00:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887561 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E64CE1515 for ; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C205128B6B for ; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B669528B78; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 46B9328B6B for ; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731323AbfDEPA6 (ORCPT ); Fri, 5 Apr 2019 11:00:58 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40160 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731140AbfDEPA5 (ORCPT ); Fri, 5 Apr 2019 11:00:57 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSnu001751; Fri, 5 Apr 2019 08:00:44 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:44 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:40 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:40 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 8B92C220CB30; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 12/15] t6043: fix copied test description to match its purpose Date: Fri, 5 Apr 2019 08:00:23 -0700 Message-ID: <20190405150026.5260-13-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=438 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Elijah Newren --- t/t6043-merge-rename-directories.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh index 62c564707b..fe205be607 100755 --- a/t/t6043-merge-rename-directories.sh +++ b/t/t6043-merge-rename-directories.sh @@ -3910,7 +3910,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' ' # To which, I can do no more than shrug my shoulders and say that # even simple rules give weird results when given weird inputs. -test_expect_success '12b-setup: Moving one directory hierarchy into another' ' +test_expect_success '12b-setup: Moving two directory hierarchies into each other' ' test_create_repo 12b && ( cd 12b && @@ -3940,7 +3940,7 @@ test_expect_success '12b-setup: Moving one directory hierarchy into another' ' ) ' -test_expect_success '12b-check: Moving one directory hierarchy into another' ' +test_expect_success '12b-check: Moving two directory hierarchies into each other' ' ( cd 12b && From patchwork Fri Apr 5 15:00:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887563 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1AE0317E9 for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F2B9D28B6E for ; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E753528B64; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 68E9828B53 for ; Fri, 5 Apr 2019 15:01:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731373AbfDEPBI (ORCPT ); Fri, 5 Apr 2019 11:01:08 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:45682 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731362AbfDEPBH (ORCPT ); Fri, 5 Apr 2019 11:01:07 -0400 Received: from pps.filterd (m0131697.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwPFQ001918; Fri, 5 Apr 2019 08:00:46 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg26mf48-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:45 -0700 Received: from sj-prod-exch-02.YOJOE.local (10.129.18.29) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 5 Apr 2019 08:00:43 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 08:00:43 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id 9A59D220CB31; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 13/15] merge-recursive: track information associated with directory renames Date: Fri, 5 Apr 2019 08:00:24 -0700 Message-ID: <20190405150026.5260-14-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Directory rename detection previously silently applied. In order to allow printing information about paths that changed or printing a conflict notification (and only doing so near other potential conflict messages associated with the paths), save this information inside the rename struct for later use. A subsequent patch will make use of the additional information. Signed-off-by: Elijah Newren --- merge-recursive.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 1d2c9e1772..938a526b20 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -207,8 +207,16 @@ struct stage_data { }; struct rename { + unsigned processed:1; struct diff_filepair *pair; const char *branch; /* branch that the rename occurred on */ + /* + * If directory rename detection affected this rename, what was its + * original type ('A' or 'R') and it's original destination before + * the directory rename (otherwise, '\0' and NULL for these two vars). + */ + char dir_rename_original_type; + char *dir_rename_original_dest; /* * Purpose of src_entry and dst_entry: * @@ -230,8 +238,6 @@ struct rename { */ struct stage_data *src_entry; struct stage_data *dst_entry; - unsigned add_turned_into_rename:1; - unsigned processed:1; }; struct rename_conflict_info { @@ -2484,16 +2490,18 @@ static void apply_directory_rename_modifications(struct merge_options *opt, &re->dst_entry->stages[stage].oid, &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; - } + /* + * Record the original change status (or 'type' of change). If it + * was originally an add ('A'), this lets us differentiate later + * between a RENAME_DELETE conflict and RENAME_VIA_DIR (they + * otherwise look the same). If it was originally a rename ('R'), + * this lets us remember and report accurately about the transitive + * renaming that occurred via the directory rename detection. Also, + * record the original destination name. + */ + re->dir_rename_original_type = pair->status; + re->dir_rename_original_dest = pair->two->path; + /* * We don't actually look at pair->status again, but it seems * pedagogically correct to adjust it. @@ -2556,9 +2564,10 @@ static struct string_list *get_renames(struct merge_options *opt, re = xmalloc(sizeof(*re)); re->processed = 0; - re->add_turned_into_rename = 0; re->pair = pair; re->branch = branch; + re->dir_rename_original_type = '\0'; + re->dir_rename_original_dest = NULL; item = string_list_lookup(entries, re->pair->one->path); if (!item) re->src_entry = insert_stage_data(re->pair->one->path, @@ -2726,7 +2735,7 @@ static int process_renames(struct merge_options *opt, try_merge = 0; if (oid_eq(&src_other.oid, &null_oid) && - ren1->add_turned_into_rename) { + ren1->dir_rename_original_type == 'A') { setup_rename_conflict_info(RENAME_VIA_DIR, opt, ren1, NULL); } else if (oid_eq(&src_other.oid, &null_oid)) { From patchwork Fri Apr 5 15:00:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887565 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 300BA139A for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1151528B79 for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 05A2728B75; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9F3F928A7E for ; Fri, 5 Apr 2019 15:01:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731375AbfDEPBI (ORCPT ); Fri, 5 Apr 2019 11:01:08 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40230 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731365AbfDEPBG (ORCPT ); Fri, 5 Apr 2019 11:01:06 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSnw001751; Fri, 5 Apr 2019 08:00:46 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:44 -0700 Received: from sj-prod-exch-02.YOJOE.local (10.129.18.29) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:40 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-02.YOJOE.local (10.129.18.29) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 5 Apr 2019 08:00:43 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id AB25A220CB32; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 14/15] merge-recursive: give callers of handle_content_merge() access to contents Date: Fri, 5 Apr 2019 08:00:25 -0700 Message-ID: <20190405150026.5260-15-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=13 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 mlxlogscore=882 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Pass a merge_file_info struct to handle_content_merge() so that the callers can access the oid and mode of the result afterward. Signed-off-by: Elijah Newren --- merge-recursive.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 938a526b20..2edfa01e43 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -2982,7 +2982,8 @@ static int handle_modify_delete(struct merge_options *opt, _("modify"), _("modified")); } -static int handle_content_merge(struct merge_options *opt, +static int handle_content_merge(struct merge_file_info *mfi, + struct merge_options *opt, const char *path, int is_dirty, const struct diff_filespec *o, @@ -2991,7 +2992,6 @@ static int handle_content_merge(struct merge_options *opt, struct rename_conflict_info *ci) { const char *reason = _("content"); - struct merge_file_info mfi; unsigned df_conflict_remains = 0; if (!is_valid(o)) @@ -3004,7 +3004,7 @@ static int handle_content_merge(struct merge_options *opt, if (merge_mode_and_contents(opt, o, a, b, path, opt->branch1, opt->branch2, - opt->call_depth * 2, &mfi)) + opt->call_depth * 2, mfi)) return -1; /* @@ -3013,13 +3013,13 @@ static int handle_content_merge(struct merge_options *opt, * b) The merge matches what was in HEAD (content, mode, pathname) * c) The target path is usable (i.e. not involved in D/F conflict) */ - if (mfi.clean && was_tracked_and_matches(opt, path, &mfi.blob) && + if (mfi->clean && was_tracked_and_matches(opt, path, &mfi->blob) && !df_conflict_remains) { int pos; struct cache_entry *ce; output(opt, 3, _("Skipped %s (merged same as existing)"), path); - if (add_cacheinfo(opt, &mfi.blob, path, + if (add_cacheinfo(opt, &mfi->blob, path, 0, (!opt->call_depth && !is_dirty), 0)) return -1; /* @@ -3035,11 +3035,11 @@ static int handle_content_merge(struct merge_options *opt, ce = opt->repo->index->cache[pos]; ce->ce_flags |= CE_SKIP_WORKTREE; } - return mfi.clean; + return mfi->clean; } - if (!mfi.clean) { - if (S_ISGITLINK(mfi.blob.mode)) + if (!mfi->clean) { + if (S_ISGITLINK(mfi->blob.mode)) reason = _("submodule"); output(opt, 1, _("CONFLICT (%s): Merge conflict in %s"), reason, path); @@ -3053,15 +3053,15 @@ static int handle_content_merge(struct merge_options *opt, if (opt->call_depth) { remove_file_from_index(opt->repo->index, path); } else { - if (!mfi.clean) { + if (!mfi->clean) { if (update_stages(opt, path, o, a, b)) return -1; } else { int file_from_stage2 = was_tracked(opt, path); if (update_stages(opt, path, NULL, - file_from_stage2 ? &mfi.blob : NULL, - file_from_stage2 ? NULL : &mfi.blob)) + file_from_stage2 ? &mfi->blob : NULL, + file_from_stage2 ? NULL : &mfi->blob)) return -1; } @@ -3072,15 +3072,15 @@ static int handle_content_merge(struct merge_options *opt, path); } output(opt, 1, _("Adding as %s instead"), new_path); - if (update_file(opt, 0, &mfi.blob, new_path)) { + if (update_file(opt, 0, &mfi->blob, new_path)) { free(new_path); return -1; } free(new_path); - mfi.clean = 0; - } else if (update_file(opt, mfi.clean, &mfi.blob, path)) + mfi->clean = 0; + } else if (update_file(opt, mfi->clean, &mfi->blob, path)) return -1; - return !is_dirty && mfi.clean; + return !is_dirty && mfi->clean; } static int handle_rename_normal(struct merge_options *opt, @@ -3091,7 +3091,8 @@ static int handle_rename_normal(struct merge_options *opt, struct rename_conflict_info *ci) { /* Merge the content and write it out */ - return handle_content_merge(opt, path, was_dirty(opt, path), + struct merge_file_info mfi; + return handle_content_merge(&mfi, opt, path, was_dirty(opt, path), o, a, b, ci); } @@ -3256,8 +3257,10 @@ static int process_entry(struct merge_options *opt, a, b); } else { /* case D: Modified in both, but differently. */ + struct merge_file_info mfi; int is_dirty = 0; /* unpack_trees would have bailed if dirty */ - clean_merge = handle_content_merge(opt, path, is_dirty, + clean_merge = handle_content_merge(&mfi, opt, path, + is_dirty, o, a, b, NULL); } } else if (!o_valid && !a_valid && !b_valid) { From patchwork Fri Apr 5 15:00:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 10887567 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5DBEC1908 for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 397F828A5B for ; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 37C9828B53; Fri, 5 Apr 2019 15:01:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFE8D28B70 for ; Fri, 5 Apr 2019 15:01:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731377AbfDEPBJ (ORCPT ); Fri, 5 Apr 2019 11:01:09 -0400 Received: from mx0a-00153501.pphosted.com ([67.231.148.48]:40226 "EHLO mx0a-00153501.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728743AbfDEPBH (ORCPT ); Fri, 5 Apr 2019 11:01:07 -0400 Received: from pps.filterd (m0096528.ppops.net [127.0.0.1]) by mx0a-00153501.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x35EwSo0001751; Fri, 5 Apr 2019 08:00:49 -0700 Received: from mail.palantir.com ([8.4.231.70]) by mx0a-00153501.pphosted.com with ESMTP id 2rmg324g4c-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=OK); Fri, 05 Apr 2019 08:00:48 -0700 Received: from sj-prod-exch-01.YOJOE.local (10.129.18.26) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1531.3; Fri, 5 Apr 2019 08:00:40 -0700 Received: from smtp-transport.yojoe.local (10.129.56.124) by sj-prod-exch-01.YOJOE.local (10.129.18.26) with Microsoft SMTP Server id 15.1.1531.3 via Frontend Transport; Fri, 5 Apr 2019 08:00:40 -0700 Received: from newren2-linux.yojoe.local (newren2-linux.pa.palantir.tech [10.100.71.66]) by smtp-transport.yojoe.local (Postfix) with ESMTPS id BCB81220CB33; Fri, 5 Apr 2019 08:00:39 -0700 (PDT) From: Elijah Newren To: CC: Junio C Hamano , Jeff King , Phillip Wood , Linus Nilsson , Elijah Newren Subject: [PATCH v3 15/15] merge-recursive: switch directory rename detection default Date: Fri, 5 Apr 2019 08:00:26 -0700 Message-ID: <20190405150026.5260-16-newren@gmail.com> X-Mailer: git-send-email 2.21.0.211.g719c25afaf.dirty In-Reply-To: <20190405150026.5260-1-newren@gmail.com> References: <20190330003336.21940-1-newren@gmail.com> <20190405150026.5260-1-newren@gmail.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-05_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=15 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904050102 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When all of x/a, x/b, and x/c have moved to z/a, z/b, and z/c on one branch, there is a question about whether x/d added on a different branch should remain at x/d or appear at z/d when the two branches are merged. There are different possible viewpoints here: A) The file was placed at x/d; it's unrelated to the other files in x/ so it doesn't matter that all the files from x/ moved to z/ on one branch; x/d should still remain at x/d. B) x/d is related to the other files in x/, and x/ was renamed to z/; therefore x/d should be moved to z/d. Since there was no ability to detect directory renames prior to git-2.18, users experienced (A) regardless of context. Choice (B) was implemented in git-2.18, with no option to go back to (A), and has been in use since. However, one user reported that the merge results did not match their expectations, making the change of default problematic, especially since there was no notice printed when directory rename detection moved files. Note that there is also a third possibility here: C) There are different answers depending on the context and content that cannot be determined by git, so this is a conflict. Use a higher stage in the index to record the conflict and notify the user of the potential issue instead of silently selecting a resolution for them. Add an option for users to specify their preference for whether to use directory rename detection, and default to (C). Even when directory rename detection is on, add notice messages about files moved into new directories. As a sidenote, x/d did not have to be a new file here; it could have already existed at some other path and been renamed to x/d, with directory rename detection just renaming it again to z/d. Thus, it's not just new files, but also a modification to all rename types (normal renames, rename/add, rename/delete, rename/rename(1to1), rename/rename(1to2), and rename/rename(2to1)). Signed-off-by: Elijah Newren --- Documentation/config/merge.txt | 19 +- merge-recursive.c | 146 ++++++-- t/t3401-rebase-and-am-rename.sh | 8 +- t/t6043-merge-rename-directories.sh | 458 ++++++++++++++++++++++--- t/t6046-merge-skip-unneeded-updates.sh | 8 +- 5 files changed, 552 insertions(+), 87 deletions(-) diff --git a/Documentation/config/merge.txt b/Documentation/config/merge.txt index d389c73929..6a313937f8 100644 --- a/Documentation/config/merge.txt +++ b/Documentation/config/merge.txt @@ -39,9 +39,22 @@ merge.renameLimit:: is turned off. merge.renames:: - Whether and how Git detects renames. If set to "false", - rename detection is disabled. If set to "true", basic rename - detection is enabled. Defaults to the value of diff.renames. + Whether Git detects renames. If set to "false", rename detection + is disabled. If set to "true", basic rename detection is enabled. + Defaults to the value of diff.renames. + +merge.directoryRenames:: + Whether Git detects directory renames, affecting what happens at + merge time to new files added to a directory on one side of + history when that directory was renamed on the other side of + history. If merge.directoryRenames is set to "false", directory + rename detection is disabled, meaning that such new files will be + left behind in the old directory. If set to "true", directory + rename detection is enabled, meaning that such new files will be + moved into the new directory. If set to "conflict", a conflict + will be reported for such paths. If merge.renames is false, + merge.directoryRenames is ignored and treated as false. Defaults + to "conflict". merge.renormalize:: Tell Git that canonical representation of files in the diff --git a/merge-recursive.c b/merge-recursive.c index 2edfa01e43..36af441faa 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1370,30 +1370,39 @@ static int handle_rename_via_dir(struct merge_options *opt, */ const struct rename *ren = ci->ren1; const struct diff_filespec *dest = ren->pair->two; + char *file_path = dest->path; + int mark_conflicted = (opt->detect_directory_renames == 1); + assert(ren->dir_rename_original_dest); if (!opt->call_depth && would_lose_untracked(opt, dest->path)) { - char *alt_path = unique_path(opt, dest->path, ren->branch); - + mark_conflicted = 1; + file_path = unique_path(opt, dest->path, ren->branch); output(opt, 1, _("Error: Refusing to lose untracked file at %s; " - "writing to %s instead."), - dest->path, alt_path); + "writing to %s instead."), + dest->path, file_path); + } + + if (mark_conflicted) { /* - * Write the file in worktree at alt_path, but not in the - * index. Instead, write to dest->path for the index but - * only at the higher appropriate stage. + * Write the file in worktree at file_path. In the index, + * only record the file at dest->path in the appropriate + * higher stage. */ - if (update_file(opt, 0, dest, alt_path)) + if (update_file(opt, 0, dest, file_path)) return -1; - free(alt_path); - return update_stages(opt, dest->path, NULL, - ren->branch == opt->branch1 ? dest : NULL, - ren->branch == opt->branch1 ? NULL : dest); + if (file_path != dest->path) + free(file_path); + if (update_stages(opt, dest->path, NULL, + ren->branch == opt->branch1 ? dest : NULL, + ren->branch == opt->branch1 ? NULL : dest)) + return -1; + return 0; /* not clean, but conflicted */ + } else { + /* Update dest->path both in index and in worktree */ + if (update_file(opt, 1, dest, dest->path)) + return -1; + return 1; /* clean */ } - - /* Update dest->path both in index and in worktree */ - if (update_file(opt, 1, dest, dest->path)) - return -1; - return 0; } static int handle_change_delete(struct merge_options *opt, @@ -3090,10 +3099,88 @@ static int handle_rename_normal(struct merge_options *opt, const struct diff_filespec *b, struct rename_conflict_info *ci) { - /* Merge the content and write it out */ + struct rename *ren = ci->ren1; struct merge_file_info mfi; - return handle_content_merge(&mfi, opt, path, was_dirty(opt, path), - o, a, b, ci); + int clean; + int side = (ren->branch == opt->branch1 ? 2 : 3); + + /* Merge the content and write it out */ + clean = handle_content_merge(&mfi, opt, path, was_dirty(opt, path), + o, a, b, ci); + + if (clean && opt->detect_directory_renames == 1 && + ren->dir_rename_original_dest) { + if (update_stages(opt, path, + NULL, + side == 2 ? &mfi.blob : NULL, + side == 2 ? NULL : &mfi.blob)) + return -1; + clean = 0; /* not clean, but conflicted */ + } + return clean; +} + +static void dir_rename_warning(const char *msg, + int is_add, + int clean, + struct merge_options *opt, + struct rename *ren) +{ + const char *other_branch; + other_branch = (ren->branch == opt->branch1 ? + opt->branch2 : opt->branch1); + if (is_add) { + output(opt, clean ? 2 : 1, msg, + ren->pair->one->path, ren->branch, + other_branch, ren->pair->two->path); + return; + } + output(opt, clean ? 2 : 1, msg, + ren->pair->one->path, ren->dir_rename_original_dest, ren->branch, + other_branch, ren->pair->two->path); +} +static int warn_about_dir_renamed_entries(struct merge_options *opt, + struct rename *ren) +{ + const char *msg; + int clean = 1, is_add; + + if (!ren) + return clean; + + /* Return early if ren was not affected/created by a directory rename */ + if (!ren->dir_rename_original_dest) + return clean; + + /* Sanity checks */ + assert(opt->detect_directory_renames > 0); + assert(ren->dir_rename_original_type == 'A' || + ren->dir_rename_original_type == 'R'); + + /* Check whether to treat directory renames as a conflict */ + clean = (opt->detect_directory_renames == 2); + + is_add = (ren->dir_rename_original_type == 'A'); + if (ren->dir_rename_original_type == 'A' && clean) { + msg = _("Path updated: %s added in %s inside a " + "directory that was renamed in %s; moving it to %s."); + } else if (ren->dir_rename_original_type == 'A' && !clean) { + msg = _("CONFLICT (file location): %s added in %s " + "inside a directory that was renamed in %s, " + "suggesting it should perhaps be moved to %s."); + } else if (ren->dir_rename_original_type == 'R' && clean) { + msg = _("Path updated: %s renamed to %s in %s, inside a " + "directory that was renamed in %s; moving it to %s."); + } else if (ren->dir_rename_original_type == 'R' && !clean) { + msg = _("CONFLICT (file location): %s renamed to %s in %s, " + "inside a directory that was renamed in %s, " + "suggesting it should perhaps be moved to %s."); + } else { + BUG("Impossible dir_rename_original_type/clean combination"); + } + dir_rename_warning(msg, is_add, clean, opt, ren); + + return clean; } /* Per entry merge function */ @@ -3115,6 +3202,10 @@ static int process_entry(struct merge_options *opt, if (entry->rename_conflict_info) { struct rename_conflict_info *ci = entry->rename_conflict_info; struct diff_filespec *temp; + int path_clean; + + path_clean = warn_about_dir_renamed_entries(opt, ci->ren1); + path_clean &= warn_about_dir_renamed_entries(opt, ci->ren2); /* * For cases with a single rename, {o,a,b}->path have all been @@ -3135,9 +3226,7 @@ static int process_entry(struct merge_options *opt, ci); break; case RENAME_VIA_DIR: - clean_merge = 1; - if (handle_rename_via_dir(opt, ci)) - clean_merge = -1; + clean_merge = handle_rename_via_dir(opt, ci); break; case RENAME_ADD: /* @@ -3187,6 +3276,8 @@ static int process_entry(struct merge_options *opt, entry->processed = 0; break; } + if (path_clean < clean_merge) + clean_merge = path_clean; } else if (o_valid && (!a_valid || !b_valid)) { /* Case A: Deleted in one */ if ((!a_valid && !b_valid) || @@ -3558,6 +3649,15 @@ static void merge_recursive_config(struct merge_options *opt) opt->merge_detect_rename = git_config_rename("merge.renames", value); free(value); } + if (!git_config_get_string("merge.directoryrenames", &value)) { + int boolval = git_parse_maybe_bool(value); + if (0 <= boolval) { + opt->detect_directory_renames = boolval ? 2 : 0; + } else if (!strcasecmp(value, "conflict")) { + opt->detect_directory_renames = 1; + } /* avoid erroring on values from future versions of git */ + free(value); + } git_config(git_xmerge_config, NULL); } diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh index e0b5111993..a0b9438b22 100755 --- a/t/t3401-rebase-and-am-rename.sh +++ b/t/t3401-rebase-and-am-rename.sh @@ -42,7 +42,7 @@ test_expect_success 'rebase --interactive: directory rename detected' ' git checkout B^0 && set_fake_editor && - FAKE_LINES="1" git rebase --interactive A && + FAKE_LINES="1" git -c merge.directoryRenames=true rebase --interactive A && git ls-files -s >out && test_line_count = 5 out && @@ -58,7 +58,7 @@ test_expect_failure 'rebase (am): directory rename detected' ' git checkout B^0 && - git rebase A && + git -c merge.directoryRenames=true rebase A && git ls-files -s >out && test_line_count = 5 out && @@ -74,7 +74,7 @@ test_expect_success 'rebase --merge: directory rename detected' ' git checkout B^0 && - git rebase --merge A && + git -c merge.directoryRenames=true rebase --merge A && git ls-files -s >out && test_line_count = 5 out && @@ -92,7 +92,7 @@ test_expect_failure 'am: directory rename detected' ' git format-patch -1 B && - git am --3way 0001*.patch && + git -c merge.directoryRenames=true am --3way 0001*.patch && git ls-files -s >out && test_line_count = 5 out && diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh index fe205be607..50b7543483 100755 --- a/t/t6043-merge-rename-directories.sh +++ b/t/t6043-merge-rename-directories.sh @@ -75,7 +75,7 @@ test_expect_success '1a-check: Simple directory rename detection' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 >out && git ls-files -s >out && test_line_count = 4 out && @@ -142,7 +142,7 @@ test_expect_success '1b-check: Merge a directory with another' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 4 out && @@ -201,7 +201,7 @@ test_expect_success '1c-check: Transitive renaming' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 >out && git ls-files -s >out && test_line_count = 3 out && @@ -270,7 +270,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/rename)" out && git ls-files -s >out && @@ -350,7 +350,7 @@ test_expect_success '1e-check: Renamed directory, with all files being renamed t git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -416,7 +416,7 @@ test_expect_success '1f-check: Split a directory into two other directories' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 6 out && @@ -497,7 +497,7 @@ test_expect_success '2a-check: Directory split into two on one side, with equal git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT.*directory rename split" out && git ls-files -s >out && @@ -559,7 +559,7 @@ test_expect_success '2b-check: Directory split into two on one side, with equal git checkout A^0 && - git merge -s recursive B^0 >out && + git -c merge.directoryRenames=true merge -s recursive B^0 >out && git ls-files -s >out && test_line_count = 3 out && @@ -640,7 +640,7 @@ test_expect_success '3a-check: Avoid implicit rename if involved as source on ot git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -705,7 +705,7 @@ test_expect_success '3b-check: Avoid implicit rename if involved as source on cu git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out && test_i18ngrep ! CONFLICT.*rename/rename.*y/d out && @@ -826,7 +826,7 @@ test_expect_success '4a-check: Directory split, with original directory still pr git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 5 out && @@ -915,7 +915,7 @@ test_expect_success '5a-check: Merge directories, other side adds files to origi git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT.*implicit dir rename" out && git ls-files -s >out && @@ -989,7 +989,7 @@ test_expect_success '5b-check: Rename/delete in order to get add/add/add conflic git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (add/add).* y/d" out && git ls-files -s >out && @@ -1069,7 +1069,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*z/d" out && test_i18ngrep "CONFLICT (add/add).* y/d" out && @@ -1153,7 +1153,7 @@ test_expect_success '5d-check: Directory/file/file conflict due to directory ren git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (file/directory).*y/d" out && git ls-files -s >out && @@ -1243,7 +1243,7 @@ test_expect_success '6a-check: Tricky rename/delete' ' git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out && git ls-files -s >out && @@ -1308,7 +1308,7 @@ test_expect_success '6b-check: Same rename done on both sides' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -1370,7 +1370,7 @@ test_expect_success '6c-check: Rename only done on same side' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -1432,7 +1432,7 @@ test_expect_success '6d-check: We do not always want transitive renaming' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -1495,7 +1495,7 @@ test_expect_success '6e-check: Add/add from one side' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 4 out && @@ -1591,7 +1591,7 @@ test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/rename).*z/b.*y/b.*w/b" out && test_i18ngrep "CONFLICT (rename/rename).*z/c.*y/c.*x/c" out && @@ -1663,7 +1663,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/rename)" out && git ls-files -s >out && @@ -1740,7 +1740,7 @@ test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out && git ls-files -s >out && @@ -1804,7 +1804,7 @@ test_expect_success '7d-check: transitive rename involved in rename/delete; how git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out && git ls-files -s >out && @@ -1894,7 +1894,7 @@ test_expect_success '7e-check: transitive rename in rename/delete AND dirs in th git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out && git ls-files -s >out && @@ -1985,7 +1985,7 @@ test_expect_success '8a-check: Dual-directory rename, one into the others way' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 6 out && @@ -2063,7 +2063,7 @@ test_expect_success '8b-check: Dual-directory rename, one into the others way, w git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 6 out && @@ -2135,7 +2135,7 @@ test_expect_success '8c-check: modify/delete or rename+modify/delete' ' git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "CONFLICT (modify/delete).* z/d" out && git ls-files -s >out && @@ -2212,7 +2212,7 @@ test_expect_success '8d-check: rename/delete...or not?' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -2287,7 +2287,7 @@ test_expect_success '8e-check: Both sides rename, one side adds to original dire git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out && test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out && @@ -2374,7 +2374,7 @@ test_expect_success '9a-check: Inner renamed directory within outer renamed dire git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 7 out && @@ -2444,7 +2444,7 @@ test_expect_success '9b-check: Transitive rename with content merge' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -2534,7 +2534,7 @@ test_expect_success '9c-check: Doubly transitive rename?' ' git checkout A^0 && - git merge -s recursive B^0 >out && + git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out && git ls-files -s >out && @@ -2622,7 +2622,7 @@ test_expect_success '9d-check: N-way transitive rename?' ' git checkout A^0 && - git merge -s recursive B^0 >out && + git -c merge.directoryRenames=true merge -s recursive B^0 >out && test_i18ngrep "WARNING: Avoiding applying z -> y rename to z/t" out && test_i18ngrep "WARNING: Avoiding applying y -> x rename to y/a" out && test_i18ngrep "WARNING: Avoiding applying x -> w rename to x/b" out && @@ -2704,7 +2704,7 @@ test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' ' git checkout A^0 && - test_must_fail git merge -s recursive B^0 >out && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out && grep "CONFLICT (implicit dir rename): Cannot map more than one path to combined/yo" out >error_line && grep -q dir1/yo error_line && grep -q dir2/yo error_line && @@ -2782,7 +2782,7 @@ test_expect_success '9f-check: Renamed directory that only contained immediate s git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 4 out && @@ -2849,7 +2849,7 @@ test_expect_failure '9g-check: Renamed directory that only contained immediate s git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 4 out && @@ -2918,7 +2918,7 @@ test_expect_success '9h-check: Avoid dir rename on merely modified path' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 3 out && @@ -2993,7 +2993,7 @@ test_expect_success '10a-check: Overwrite untracked with normal rename/delete' ' echo very >z/c && echo important >z/d && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "The following untracked working tree files would be overwritten by merge" err && git ls-files -s >out && @@ -3061,7 +3061,7 @@ test_expect_success '10b-check: Overwrite untracked with dir rename + delete' ' echo important >y/d && echo contents >y/e && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/delete).*Version B\^0 of y/d left in tree at y/d~B\^0" out && test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B\^0 instead" out && @@ -3137,7 +3137,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2) git checkout A^0 && echo important >y/c && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/rename)" out && test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B\^0 instead" out && @@ -3174,7 +3174,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2) mkdir y && echo important >y/c && - test_must_fail git merge -s recursive A^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err && test_i18ngrep "CONFLICT (rename/rename)" out && test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~HEAD instead" out && @@ -3249,7 +3249,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' ' git checkout A^0 && echo important >y/wham && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/rename)" out && test_i18ngrep "Refusing to lose untracked file at y/wham" out && @@ -3327,7 +3327,7 @@ test_expect_failure '10e-check: Does git complain about untracked file that is n mkdir z && echo random >z/c && - git merge -s recursive B^0 >out 2>err && + git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err && git ls-files -s >out && @@ -3407,7 +3407,7 @@ test_expect_success '11a-check: Avoid losing dirty contents with simple rename' git checkout A^0 && echo stuff >>z/c && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "Refusing to lose dirty file at z/c" out && test_seq 1 10 >expected && @@ -3479,7 +3479,7 @@ test_expect_success '11b-check: Avoid losing dirty file involved in directory re git checkout A^0 && echo stuff >>z/c && - git merge -s recursive B^0 >out 2>err && + git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "Refusing to lose dirty file at z/c" out && grep -q stuff z/c && @@ -3554,7 +3554,7 @@ test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conf git checkout A^0 && echo stuff >>y/c && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "following files would be overwritten by merge" err && grep -q stuff y/c && @@ -3621,7 +3621,7 @@ test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conf git checkout A^0 && echo stuff >>z/c && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "Refusing to lose dirty file at z/c" out && grep -q stuff z/c && @@ -3700,7 +3700,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena git checkout A^0 && echo mods >>y/c && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/rename)" out && test_i18ngrep "Refusing to lose dirty file at y/c" out && @@ -3782,7 +3782,7 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena git checkout A^0 && echo important >>y/wham && - test_must_fail git merge -s recursive B^0 >out 2>err && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/rename)" out && test_i18ngrep "Refusing to lose dirty file at y/wham" out && @@ -3870,7 +3870,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' ' git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 6 out && @@ -3946,7 +3946,7 @@ test_expect_success '12b-check: Moving two directory hierarchies into each other git checkout A^0 && - git merge -s recursive B^0 && + git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -s >out && test_line_count = 4 out && @@ -4016,7 +4016,7 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c git checkout A^0 && - test_must_fail git merge -s recursive B^0 && + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 && git ls-files -u >out && test_line_count = 12 out && @@ -4051,4 +4051,356 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c ) ' +########################################################################### +# SECTION 13: Checking informational and conflict messages +# +# A year after directory rename detection became the default, it was +# instead decided to report conflicts on the pathname on the basis that +# some users may expect the new files added or moved into a directory to +# be unrelated to all the other files in that directory, and thus that +# directory rename detection is unexpected. Test that the messages printed +# match our expectation. +########################################################################### + +# Testcase 13a, Basic directory rename with newly added files +# Commit O: z/{b,c} +# Commit A: y/{b,c} +# Commit B: z/{b,c,d,e/f} +# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f + +test_expect_success '13a-setup: messages for newly added files' ' + test_create_repo 13a && + ( + cd 13a && + + mkdir z && + echo b >z/b && + echo c >z/c && + git add z && + test_tick && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv z y && + test_tick && + git commit -m "A" && + + git checkout B && + echo d >z/d && + mkdir z/e && + echo f >z/e/f && + git add z/d z/e/f && + test_tick && + git commit -m "B" + ) +' + +test_expect_success '13a-check(conflict): messages for newly added files' ' + ( + cd 13a && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out 2>err && + + test_i18ngrep CONFLICT..file.location.*z/e/f.added.in.B^0.*y/e/f out && + test_i18ngrep CONFLICT..file.location.*z/d.added.in.B^0.*y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/[de]" paths && + + test_path_is_missing z/d && + test_path_is_file y/d && + test_path_is_missing z/e/f && + test_path_is_file y/e/f + ) +' + +test_expect_success '13a-check(info): messages for newly added files' ' + ( + cd 13a && + + git reset --hard && + git checkout A^0 && + + git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && + + test_i18ngrep Path.updated:.*z/e/f.added.in.B^0.*y/e/f out && + test_i18ngrep Path.updated:.*z/d.added.in.B^0.*y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/[de]" paths && + + test_path_is_missing z/d && + test_path_is_file y/d && + test_path_is_missing z/e/f && + test_path_is_file y/e/f + ) +' + +# Testcase 13b, Transitive rename with conflicted content merge and default +# "conflict" setting +# (Related to testcase 1c, 9b) +# Commit O: z/{b,c}, x/d_1 +# Commit A: y/{b,c}, x/d_2 +# Commit B: z/{b,c,d_3} +# Expected: y/{b,c,d_merged}, with two conflict messages for y/d, +# one about content, and one about file location + +test_expect_success '13b-setup: messages for transitive rename with conflicted content' ' + test_create_repo 13b && + ( + cd 13b && + + mkdir x && + mkdir z && + test_seq 1 10 >x/d && + echo b >z/b && + echo c >z/c && + git add x z && + test_tick && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv z y && + echo 11 >>x/d && + git add x/d && + test_tick && + git commit -m "A" && + + git checkout B && + echo eleven >>x/d && + git mv x/d z/d && + git add z/d && + test_tick && + git commit -m "B" + ) +' + +test_expect_success '13b-check(conflict): messages for transitive rename with conflicted content' ' + ( + cd 13b && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out 2>err && + + test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out && + test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/d" paths && + + test_path_is_missing z/d && + test_path_is_file y/d + ) +' + +test_expect_success '13b-check(info): messages for transitive rename with conflicted content' ' + ( + cd 13b && + + git reset --hard && + git checkout A^0 && + + test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && + + test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out && + test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/d" paths && + + test_path_is_missing z/d && + test_path_is_file y/d + ) +' + +# Testcase 13c, Rename/rename(1to1) due to directory rename +# Commit O: z/{b,c}, x/{d,e} +# Commit A: y/{b,c,d}, x/e +# Commit B: z/{b,c,d}, x/e +# Expected: y/{b,c,d}, with info or conflict messages for d ( +# A: renamed x/d -> z/d; B: renamed z/ -> y/ AND renamed x/d to y/d +# One could argue A had partial knowledge of what was done with +# d and B had full knowledge, but that's a slippery slope as +# shown in testcase 13d. + +test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive rename' ' + test_create_repo 13c && + ( + cd 13c && + + mkdir x && + mkdir z && + test_seq 1 10 >x/d && + echo e >x/e && + echo b >z/b && + echo c >z/c && + git add x z && + test_tick && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv z y && + git mv x/d y/ && + test_tick && + git commit -m "A" && + + git checkout B && + git mv x/d z/d && + git add z/d && + test_tick && + git commit -m "B" + ) +' + +test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via transitive rename' ' + ( + cd 13c && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out 2>err && + + test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/d" paths && + + test_path_is_missing z/d && + test_path_is_file y/d + ) +' + +test_expect_success '13c-check(info): messages for rename/rename(1to1) via transitive rename' ' + ( + cd 13c && + + git reset --hard && + git checkout A^0 && + + git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && + + test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out && + + git ls-files >paths && + ! grep z/ paths && + grep "y/d" paths && + + test_path_is_missing z/d && + test_path_is_file y/d + ) +' + +# Testcase 13d, Rename/rename(1to1) due to directory rename on both sides +# Commit O: a/{z,y}, b/x, c/w +# Commit A: a/z, b/{y,x}, d/w +# Commit B: a/z, d/x, c/{y,w} +# Expected: a/z, d/{y,x,w} with no file location conflict for x +# Easy cases: +# * z is always in a; so it stays in a. +# * x starts in b, only modified on one side to move into d/ +# * w starts in c, only modified on one side to move into d/ +# Hard case: +# * A renames a/y to b/y, and B renames b/->d/ => a/y -> d/y +# * B renames a/y to c/y, and A renames c/->d/ => a/y -> d/y +# No conflict in where a/y ends up, so put it in d/y. + +test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transitive rename' ' + test_create_repo 13d && + ( + cd 13d && + + mkdir a && + mkdir b && + mkdir c && + echo z >a/z && + echo y >a/y && + echo x >b/x && + echo w >c/w && + git add a b c && + test_tick && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv a/y b/ && + git mv c/ d/ && + test_tick && + git commit -m "A" && + + git checkout B && + git mv a/y c/ && + git mv b/ d/ && + test_tick && + git commit -m "B" + ) +' + +test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via dual transitive rename' ' + ( + cd 13d && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out 2>err && + + test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.b/y.*moved.to.d/y out && + test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.c/y.*moved.to.d/y out && + + git ls-files >paths && + ! grep b/ paths && + ! grep c/ paths && + grep "d/y" paths && + + test_path_is_missing b/y && + test_path_is_missing c/y && + test_path_is_file d/y + ) +' + +test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual transitive rename' ' + ( + cd 13d && + + git reset --hard && + git checkout A^0 && + + git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && + + test_i18ngrep Path.updated.*a/y.renamed.to.b/y.*moving.it.to.d/y out && + test_i18ngrep Path.updated.*a/y.renamed.to.c/y.*moving.it.to.d/y out && + + git ls-files >paths && + ! grep b/ paths && + ! grep c/ paths && + grep "d/y" paths && + + test_path_is_missing b/y && + test_path_is_missing c/y && + test_path_is_file d/y + ) +' + test_done diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh index 38e24f787c..3a47623ed3 100755 --- a/t/t6046-merge-skip-unneeded-updates.sh +++ b/t/t6046-merge-skip-unneeded-updates.sh @@ -466,7 +466,7 @@ test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' git checkout A^0 && - GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && + GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep ! "Skipped bar/bq" out && test_must_be_empty err && @@ -495,7 +495,7 @@ test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' git checkout B^0 && - GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err && + GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err && test_i18ngrep ! "Skipped bar/bq" out && test_must_be_empty err && @@ -560,7 +560,7 @@ test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' git checkout A^0 && - GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && + GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && test_i18ngrep ! "Skipped bar/bq" out && test_must_be_empty err && @@ -589,7 +589,7 @@ test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' git checkout B^0 && - GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err && + GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err && test_i18ngrep ! "Skipped bar/bq" out && test_must_be_empty err &&