From patchwork Tue Dec 15 18:27:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F4BBC4361B for ; Tue, 15 Dec 2020 18:28:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D4BD22B2D for ; Tue, 15 Dec 2020 18:28:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731440AbgLOS2v (ORCPT ); Tue, 15 Dec 2020 13:28:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729368AbgLOS2v (ORCPT ); Tue, 15 Dec 2020 13:28:51 -0500 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E8B0C0617A7 for ; Tue, 15 Dec 2020 10:28:10 -0800 (PST) Received: by mail-wm1-x341.google.com with SMTP id c133so146404wme.4 for ; Tue, 15 Dec 2020 10:28:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=bjCZpoR7X/4iQp728JJIq89yo2vC+dnNlcpJ/DFfq80=; b=XYtK0NQGnoYEexS+augD5TzBI/8dAhhlZfIkc3ZfEfKXv98nay9zWVozs6qZHHtVEz bgCsvPUF3B5Keyrnm1DocYEpiupoUDdwYlcrBtCkRE+hvMz0Q+4nMEAjXaiWdEZ22H3O vk8dkilIR9kjdCPbJanX7fFpvJ7PA4AJMBncnbMK2c3JBDKq6oUQK9tT5qyne9kZsVug +0K1SkbVa//OoXG/C3HMT6DfMV+ImeN3PSB7B5WBNleIUvsNaG6ziMuZfMDC+3Clq6JH blaqzRaonVt/pI8jz9uwHlcbScUhypUDQvop1sIMy6mtvqO98wDkGDtlgBrRb/Utm01E B7Tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=bjCZpoR7X/4iQp728JJIq89yo2vC+dnNlcpJ/DFfq80=; b=XIaeJvsG1s1dBMB/rWa6Wms5Jl5LfaigMfvL8pT8U7UDTfINtizShIqaB68UabYIlj Y7NY8rseRkNYCzumjB8X8OJ+Uu87h/jKW/NjY9jgbhZF7lZfkU2ydrKsTUKZFpqqtCw+ gbsq+aNHYkN2IB6LAB6XZ+8l1Z2vUvP4tOmAJRV6PpA8e9hFAMbVtD0KSN5iEZPtCaOz 3sUQnS+nRMxZEYBDA1kHWGgWz2agfPQsz2TGobL7+Ix7Qrpo49ElMMBYLpRdraRnezLy BR6gVdVQ8nbMNp4020PB1VuyS1KFAuT5IP3WAJU5vwLYYnSEfuUbQmi7i5kymLr+wrqT 6c+g== X-Gm-Message-State: AOAM530CI1WnPZuKIs4h0mFi87/cftAkWcjHyid4zRvdOJnffy4N0J60 TFm0kXkUN+B4/kMj7VcTy9Lu2XyvkIA= X-Google-Smtp-Source: ABdhPJzuxcPEP/XneYACh+M15+VIrvzd2cjfRC1yKKMfDeE6t1BFky3YMzsoMnaVu4wMgBQszWANxA== X-Received: by 2002:a1c:a5d4:: with SMTP id o203mr171965wme.41.1608056889107; Tue, 15 Dec 2020 10:28:09 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z15sm40476857wrv.67.2020.12.15.10.28.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:08 -0800 (PST) Message-Id: <78621ca07887e39a41ad9cff7b8dd5dcc9b33fbc.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:27:56 +0000 Subject: [PATCH v3 01/11] merge-ort: add basic data structures for handling renames Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This will grow later, but we only need a few fields for basic rename handling. Signed-off-by: Elijah Newren --- merge-ort.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/merge-ort.c b/merge-ort.c index 414e7b7eeac..1c1a7fa4bf1 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -46,6 +46,25 @@ enum merge_side { MERGE_SIDE2 = 2 }; +struct rename_info { + /* + * pairs: pairing of filenames from diffcore_rename() + * + * Index 1 and 2 correspond to sides 1 & 2 as used in + * conflict_info.stages. Index 0 unused. + */ + struct diff_queue_struct pairs[3]; + + /* + * needed_limit: value needed for inexact rename detection to run + * + * If the current rename limit wasn't high enough for inexact + * rename detection to run, this records the limit needed. Otherwise, + * this value remains 0. + */ + int needed_limit; +}; + struct merge_options_internal { /* * paths: primary data structure in all of merge ort. @@ -113,6 +132,11 @@ struct merge_options_internal { */ struct strmap output; + /* + * renames: various data relating to rename detection + */ + struct rename_info renames; + /* * current_dir_name: temporary var used in collect_merge_info_callback() * From patchwork Tue Dec 15 18:27:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 687E7C4361B for ; Tue, 15 Dec 2020 18:28:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3CAD222B2D for ; Tue, 15 Dec 2020 18:28:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731550AbgLOS2w (ORCPT ); Tue, 15 Dec 2020 13:28:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729368AbgLOS2v (ORCPT ); Tue, 15 Dec 2020 13:28:51 -0500 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BE6BC0617B0 for ; Tue, 15 Dec 2020 10:28:11 -0800 (PST) Received: by mail-wm1-x344.google.com with SMTP id x22so141043wmc.5 for ; Tue, 15 Dec 2020 10:28:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=SI+l5g9wGTUq3i9Ft6Oc+PNP4QnKTKBpBnZ3lsTnHgU=; b=qj4I0LRtP0oHjb/Fa/MTThmh5E52ddF6UPm3GHm033UD2hes4ckG1bTjKhsLqurQiw OOI8CBlyLp74cge3rTNQ1CCCL4vToolnjLAtw0LrRsvPESfo0/8sYYwiAtlt+u2z+bzp M69cgBri7sxlVaqHBEdFEY3cbKAjzPKjD01dfo5t8vs6ZlPxBuUJUKrXsk5Vis2v3gAG kihLVNSex+tz7pSdrvpDF1Mjfch0unImunsTOc/LoxSpdGJW1I76E4sfVcOOpmaEFqoP 80LEhB2iyw9+QpEtTkZG+XjgYuyy3cqE2ZpROeQqSTolSuRG8L+8MuyypvXiqe5V4QPo uopw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=SI+l5g9wGTUq3i9Ft6Oc+PNP4QnKTKBpBnZ3lsTnHgU=; b=BbGMInaKq2drRzIkXNm5YwKOrWupmgSbmI+QvULTAsOJeFiJeuTpff2FmaQFE9wkir fQaB0pZG5VvLu9zKrJV3YQvpJICGMGisqYrzW2Eu28Pn4digFlGXnteCjdQ74RM/HEVw smY55TyPpu7dkmIaUNlEws32GNE/XnwnI5iddZwINjOrqhhfQJGztaIERK9kYoAuAtsn 7HkRWuCz5aJ3C4Y1L6j6IUSuqvsBi8M/o354P+TIqBDIImG4JHHT70BdtHco6I/QVct4 LrpvodsqPkWsxSJkotyi4vdMVhH0v/LT90ncKJWpNEMDNupA5bGoBd9sZSsreEJ66dTv LsvA== X-Gm-Message-State: AOAM53379XCWhx2TTvfoD/RtqTpRP+2r3/Ji2Djw8GNlNh6ToSmT30fH 7J0fMQj/2mvr5HanDSj/cIjn7usOjpI= X-Google-Smtp-Source: ABdhPJyZLi/01WOI/RHuge3cm8tesbvLIBZh9S2kDom1rmOQ7uVrxFK+XRIJpZKzL9Tuni867uFSqA== X-Received: by 2002:a7b:c45a:: with SMTP id l26mr164963wmi.91.1608056890000; Tue, 15 Dec 2020 10:28:10 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p19sm45213178wrg.18.2020.12.15.10.28.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:09 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 15 Dec 2020 18:27:57 +0000 Subject: [PATCH v3 02/11] merge-ort: add initial outline for basic rename detection Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Signed-off-by: Elijah Newren --- merge-ort.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 1c1a7fa4bf1..8552f5e2318 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -644,20 +644,72 @@ static int handle_content_merge(struct merge_options *opt, /*** Function Grouping: functions related to regular rename detection ***/ +static int process_renames(struct merge_options *opt, + struct diff_queue_struct *renames) +{ + die("Not yet implemented."); +} + +static int compare_pairs(const void *a_, const void *b_) +{ + die("Not yet implemented."); +} + +/* Call diffcore_rename() to compute which files have changed on given side */ +static void detect_regular_renames(struct merge_options *opt, + struct tree *merge_base, + struct tree *side, + unsigned side_index) +{ + die("Not yet implemented."); +} + +/* + * Get information of all renames which occurred in 'side_pairs', discarding + * non-renames. + */ +static int collect_renames(struct merge_options *opt, + struct diff_queue_struct *result, + unsigned side_index) +{ + die("Not yet implemented."); +} + static int detect_and_process_renames(struct merge_options *opt, struct tree *merge_base, struct tree *side1, struct tree *side2) { - int clean = 1; + struct diff_queue_struct combined; + struct rename_info *renames = &opt->priv->renames; + int s, clean = 1; + + memset(&combined, 0, sizeof(combined)); + + detect_regular_renames(opt, merge_base, side1, MERGE_SIDE1); + detect_regular_renames(opt, merge_base, side2, MERGE_SIDE2); + + ALLOC_GROW(combined.queue, + renames->pairs[1].nr + renames->pairs[2].nr, + combined.alloc); + clean &= collect_renames(opt, &combined, MERGE_SIDE1); + clean &= collect_renames(opt, &combined, MERGE_SIDE2); + QSORT(combined.queue, combined.nr, compare_pairs); + + clean &= process_renames(opt, &combined); + + /* Free memory for renames->pairs[] and combined */ + for (s = MERGE_SIDE1; s <= MERGE_SIDE2; s++) { + free(renames->pairs[s].queue); + DIFF_QUEUE_CLEAR(&renames->pairs[s]); + } + if (combined.nr) { + int i; + for (i = 0; i < combined.nr; i++) + diff_free_filepair(combined.queue[i]); + free(combined.queue); + } - /* - * Rename detection works by detecting file similarity. Here we use - * a really easy-to-implement scheme: files are similar IFF they have - * the same filename. Therefore, by this scheme, there are no renames. - * - * TODO: Actually implement a real rename detection scheme. - */ return clean; } From patchwork Tue Dec 15 18:27:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21E8BC4361B for ; Tue, 15 Dec 2020 18:29:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE68F22B40 for ; Tue, 15 Dec 2020 18:29:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729856AbgLOS3H (ORCPT ); Tue, 15 Dec 2020 13:29:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729368AbgLOS2w (ORCPT ); Tue, 15 Dec 2020 13:28:52 -0500 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A87DC06138C for ; Tue, 15 Dec 2020 10:28:12 -0800 (PST) Received: by mail-wm1-x341.google.com with SMTP id a6so154824wmc.2 for ; Tue, 15 Dec 2020 10:28:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=2EJEhCVyrWEW/1Rsba7YQOxkLZkc7V5Ocg8faa9cQT0=; b=gWdNbwjh7nurrknTa9TtkPyrP42nDGF4+QzNZ5i4Wi1P60vUIelvmItW36zCSdNrdb Vag9+CfB/Xp28u2vj/PqB02wpDqcXsgX7AoiSsx7VZUNhJZuRXlfu50UAodFy+Bsb456 S+9jVO5vbMPOGTCQvZMhbJ0G1ZYxSl6TbyNyW1ErAXbFpOOzU/9aFRcRTvs2jTrGhxYQ 1sYxv3QoieNBfK6IHOxXIQPc0kbz7lWImexwVMFbkJ+2KGxmUlRtnk5aE9kxG4rhD+se fiBh8VHI671nzS38KIV9JmkeKRDIQGHtoVXL8cfdQIrfVOTOtTQibEte1tvk8jxNh8Wz 6rUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=2EJEhCVyrWEW/1Rsba7YQOxkLZkc7V5Ocg8faa9cQT0=; b=EMDF8WFRejA5sdE2TGF0RwVYShc2ceHkvlc/tuZLgTDhIaaWkQplDMuWLX7FGpiY/1 J8FjMZPleJ7d2NnmkLvZror2VuLGtv2H5lYIV8SiGY24eRly4766w1j1ONhZHiTPDxdl oi8oMSLCJfAhomagklo1SoZ+P42haRZnAHbGYEXZ+BF67OAn3cfEw93YM1rMONG38XiX lXxJUwVfFb8JEa4MU6VCYvgYzFz2JTz7Agor15Q4H5nB4Cc/x95zXwFbEJ5gSlQ2ElnE 2JxWvhQ7QvI1hv8IeCwAkOVOjHl5B0T/o8kxZvTUUBXIiaVyLhdE9jAVlVZdm6597dwN 7t9g== X-Gm-Message-State: AOAM530/N1Vc1YnzuZtC/nvBvK7RV/D/+Yyj2l4jMuNdgI9LzkDhCCrO I4JdOAOdhqrdlsLPVz1dhaptf8B3Qfo= X-Google-Smtp-Source: ABdhPJyu0flIWfoZbRvwVKqsJVTVuvQnFNrfkTbmTd/FV3FwHqnCf1qxCwqQaBjjwL7mpvKPDfzDuQ== X-Received: by 2002:a1c:4483:: with SMTP id r125mr196162wma.80.1608056890874; Tue, 15 Dec 2020 10:28:10 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h15sm37212400wru.4.2020.12.15.10.28.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:10 -0800 (PST) Message-Id: <620fc64032d26e374b2fb52a044564725e023f0f.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:27:58 +0000 Subject: [PATCH v3 03/11] merge-ort: implement detect_regular_renames() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Based heavily on merge-recursive's get_diffpairs() function, and also includes the necessary paired call to diff_warn_rename_limit() so that users will be warned if merge.renameLimit is not sufficiently large for rename detection to run. Signed-off-by: Elijah Newren --- merge-ort.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index 8552f5e2318..66f84d39b43 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -661,7 +661,33 @@ static void detect_regular_renames(struct merge_options *opt, struct tree *side, unsigned side_index) { - die("Not yet implemented."); + struct diff_options diff_opts; + struct rename_info *renames = &opt->priv->renames; + + repo_diff_setup(opt->repo, &diff_opts); + diff_opts.flags.recursive = 1; + diff_opts.flags.rename_empty = 0; + diff_opts.detect_rename = DIFF_DETECT_RENAME; + diff_opts.rename_limit = opt->rename_limit; + if (opt->rename_limit <= 0) + diff_opts.rename_limit = 1000; + diff_opts.rename_score = opt->rename_score; + diff_opts.show_rename_progress = opt->show_rename_progress; + diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; + diff_setup_done(&diff_opts); + diff_tree_oid(&merge_base->object.oid, &side->object.oid, "", + &diff_opts); + diffcore_std(&diff_opts); + + if (diff_opts.needed_rename_limit > renames->needed_limit) + renames->needed_limit = diff_opts.needed_rename_limit; + + renames->pairs[side_index] = diff_queued_diff; + + diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; + diff_queued_diff.nr = 0; + diff_queued_diff.queue = NULL; + diff_flush(&diff_opts); } /* @@ -1406,6 +1432,10 @@ void merge_switch_to_result(struct merge_options *opt, printf("%s", sb->buf); } string_list_clear(&olist, 0); + + /* Also include needed rename limit adjustment now */ + diff_warn_rename_limit("merge.renamelimit", + opti->renames.needed_limit, 0); } merge_finalize(opt, result); From patchwork Tue Dec 15 18:27:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C62EC4361B for ; Tue, 15 Dec 2020 18:29:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F3EB422B2D for ; Tue, 15 Dec 2020 18:29:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730781AbgLOS32 (ORCPT ); Tue, 15 Dec 2020 13:29:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729693AbgLOS3F (ORCPT ); Tue, 15 Dec 2020 13:29:05 -0500 Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 35242C061282 for ; Tue, 15 Dec 2020 10:28:13 -0800 (PST) Received: by mail-wm1-x343.google.com with SMTP id a3so137517wmb.5 for ; Tue, 15 Dec 2020 10:28:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=lTMgcVB6vgszaz4Tdvquin0z9C4VpWH2bLbPz0t6/YU=; b=pZC0afmh6Jz8fgGmCwHSQfq2nPfs0+AVqBlq1jHS8AlQOyq6CXeTUd2Y6T5dSITtGo Q+3lOtjSio1/QBZal7BE7CGyENIWZ+tSofuvJWVuTZYwa3zRrL54rsXZzuUqTi1FRUNy 1OR1SG7l/lkYwIzjVrnq1ekbVHvHDpj0E6dcJXfhvdCsFZXx9DLwarZxZz2lsdOr6ZEf jBm5NRaWnax1E+g5KuubIHT3W5rn0rhueFydly3CEf8nSKyi7rRWKDKIeLCt+fVqzwqn slj5LcoadXmNtrnYtXPPr0YLWHwmOyyw54Qxta09y1t6zPJkeoO94Fcctj+FJkTgzbVX dKig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=lTMgcVB6vgszaz4Tdvquin0z9C4VpWH2bLbPz0t6/YU=; b=dJXFEGL80s5dNTzLTY9Hv5uhWwQ9+V99G0A7MjES5hi4NQfs36C5FLohsgTgIAuPOr er2HB4FaEBuo2WJt/f7KOofWQCX94rVMgm2jdGwWrL+rjj+hMdXbqvLelMvprrRntKza 4hY75rvo7a4xfjtKmKIB44dpyDFQFUAadmgyID85O1N+PoLIWHLU/JESGIliTDa35n7p cWAkqo4BavPb7L508MOj+hZYPmX36jrxf2g2XIPdPMzOYO8nYsPSn3biwT4h9TpzxOY5 4NeEV5fYL4ezl1tgmE/+zrC+nfQubNRvB+iHPGexk50CCSfoU6KexJn8V4WrYdojqJhQ C5qA== X-Gm-Message-State: AOAM5334A7PXMVRj7by8ZSHPMPuLBSLGPF1couDGLDlh1YK1GBskk8BC e9XwwsAUVeUGnNtqHp6LNMw6o182URg= X-Google-Smtp-Source: ABdhPJwMhIRvBYjxCCRwDUgrKlQpGFyW+f3+uXgQTiqGiLUwipVk5tKxlLv0YjuON/YA+jKGYQLcxw== X-Received: by 2002:a1c:1bcd:: with SMTP id b196mr203490wmb.70.1608056891792; Tue, 15 Dec 2020 10:28:11 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l5sm28508589wrv.44.2020.12.15.10.28.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:11 -0800 (PST) Message-Id: <9382dc4d50b3cf675d607cf5d39be08542d8147e.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:27:59 +0000 Subject: [PATCH v3 04/11] merge-ort: implement compare_pairs() and collect_renames() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Signed-off-by: Elijah Newren --- merge-ort.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 66f84d39b43..10550c542b8 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -652,7 +652,10 @@ static int process_renames(struct merge_options *opt, static int compare_pairs(const void *a_, const void *b_) { - die("Not yet implemented."); + const struct diff_filepair *a = *((const struct diff_filepair **)a_); + const struct diff_filepair *b = *((const struct diff_filepair **)b_); + + return strcmp(a->one->path, b->one->path); } /* Call diffcore_rename() to compute which files have changed on given side */ @@ -698,7 +701,35 @@ static int collect_renames(struct merge_options *opt, struct diff_queue_struct *result, unsigned side_index) { - die("Not yet implemented."); + int i, clean = 1; + struct diff_queue_struct *side_pairs; + struct rename_info *renames = &opt->priv->renames; + + side_pairs = &renames->pairs[side_index]; + + for (i = 0; i < side_pairs->nr; ++i) { + struct diff_filepair *p = side_pairs->queue[i]; + + if (p->status != 'R') { + diff_free_filepair(p); + continue; + } + + /* + * p->score comes back from diffcore_rename_extended() with + * the similarity of the renamed file. The similarity is + * was used to determine that the two files were related + * and are a rename, which we have already used, but beyond + * that we have no use for the similarity. So p->score is + * now irrelevant. However, process_renames() will need to + * know which side of the merge this rename was associated + * with, so overwrite p->score with that value. + */ + p->score = side_index; + result->queue[result->nr++] = p; + } + + return clean; } static int detect_and_process_renames(struct merge_options *opt, From patchwork Tue Dec 15 18:28:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7496C4361B for ; Tue, 15 Dec 2020 18:29:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8508422B40 for ; Tue, 15 Dec 2020 18:29:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730242AbgLOS3S (ORCPT ); Tue, 15 Dec 2020 13:29:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51164 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729716AbgLOS3F (ORCPT ); Tue, 15 Dec 2020 13:29:05 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F8A8C061285 for ; Tue, 15 Dec 2020 10:28:14 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id a6so154898wmc.2 for ; Tue, 15 Dec 2020 10:28:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ZmaFFlhRcNBXHdv7esqe3Jf3vYqKLnuvVwTH5JzTLmk=; b=b5tKyfHHrutQm3nsreHOHLTesZUp/wgN2G0/AlFQ0qK4WSbDbOUb23Cc3FRMAAHexr vXDI1WzhtFYZPbRIGbQbolixzdhDK4DT49ri5B6ve3vpI5paBRsSokZZ5NOEzPEtrmQ9 rR43O+7/FOUtfTEM0u0l7HvYPU95rOYjntcbxUicf6FoundTvIMdfrjaLM7Jy2AWC51V QmHlBQYtkicJL3+6s2pJI3JledNCrDsvSHWTATpW/iF8PllhPBzrku2dIMTOj0+to00Z HbwXgLK9BdYI7SoDR+T2N5nOEqSm+/kqqOVNmgZLiHcRU7XyX2pzYSgAiZqwxYKBbMeO vcHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ZmaFFlhRcNBXHdv7esqe3Jf3vYqKLnuvVwTH5JzTLmk=; b=plVf/CmDSrv8qfkq1d/VZn8Z+uXqNZz0u+DuqJEoQglr5KlMpZOqpyidrp1Ijxm8XJ ZRmJBp5kVYu2KOuWamnBvdGOE+Y/nlD3hzTzFi7MeH8sLstP5VVogv7JFxXsprwagkUI XTXKTdc8xLTO5OIVolPpKDNx8463LlnVPL+pS8gjYV6/eekUrM4AephAShdkLreILNiL HXN5v79Moc0ShwaPaktJj3xXkZGCbtmejtCQKBPaEtU9vNfLulqYahuSmWSUa0lSa/+j +7KV4pZzFv4YFH6fWHi49Z3agbs8GAStB56l95CeU2W9IPw91ZsYY25vtppgcdrMm1Yp nNSw== X-Gm-Message-State: AOAM5335ILUgSKkpZvKUM8gtecLUBywn4JsOkbfsgHBAUmXhwstOotca /ynDTZu1cp28wvEb4B/y1PRbV/VGmtA= X-Google-Smtp-Source: ABdhPJw60yb9/FrqZgS5Q7cKUOzRXvx/oLHl17aPeyqHvRroi0zLNsQ352fwYEQE88XowY/GgueKOw== X-Received: by 2002:a05:600c:220b:: with SMTP id z11mr209329wml.64.1608056892605; Tue, 15 Dec 2020 10:28:12 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q12sm39488205wmc.45.2020.12.15.10.28.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:12 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:00 +0000 Subject: [PATCH v3 05/11] merge-ort: add basic outline for process_renames() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Add code which determines which kind of special rename case each rename corresponds to, but leave the handling of each type unimplemented for now. Future commits will implement each one. There is some tenuous resemblance to merge-recursive's process_renames(), but comparing the two is very unlikely to yield any insights. merge-ort's process_renames() is a bit complex and I would prefer if I could simplify it more, but it is far easier to grok than merge-recursive's function of the same name in my opinion. Plus, merge-ort handles more rename conflict types than merge-recursive does. Signed-off-by: Elijah Newren --- merge-ort.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index 10550c542b8..ebe275ef73c 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -647,7 +647,103 @@ static int handle_content_merge(struct merge_options *opt, static int process_renames(struct merge_options *opt, struct diff_queue_struct *renames) { - die("Not yet implemented."); + int clean_merge = 1, i; + + for (i = 0; i < renames->nr; ++i) { + const char *oldpath = NULL, *newpath; + struct diff_filepair *pair = renames->queue[i]; + struct conflict_info *oldinfo = NULL, *newinfo = NULL; + struct strmap_entry *old_ent, *new_ent; + unsigned int old_sidemask; + int target_index, other_source_index; + int source_deleted, collision, type_changed; + + old_ent = strmap_get_entry(&opt->priv->paths, pair->one->path); + oldpath = old_ent->key; + oldinfo = old_ent->value; + + new_ent = strmap_get_entry(&opt->priv->paths, pair->two->path); + newpath = new_ent->key; + newinfo = new_ent->value; + + /* + * diff_filepairs have copies of pathnames, thus we have to + * use standard 'strcmp()' (negated) instead of '=='. + */ + if (i + 1 < renames->nr && + !strcmp(oldpath, renames->queue[i+1]->one->path)) { + /* Handle rename/rename(1to2) or rename/rename(1to1) */ + const char *pathnames[3]; + + pathnames[0] = oldpath; + pathnames[1] = newpath; + pathnames[2] = renames->queue[i+1]->two->path; + + if (!strcmp(pathnames[1], pathnames[2])) { + /* Both sides renamed the same way. */ + die("Not yet implemented"); + + /* We handled both renames, i.e. i+1 handled */ + i++; + /* Move to next rename */ + continue; + } + + /* This is a rename/rename(1to2) */ + die("Not yet implemented"); + + i++; /* We handled both renames, i.e. i+1 handled */ + continue; + } + + VERIFY_CI(oldinfo); + VERIFY_CI(newinfo); + target_index = pair->score; /* from collect_renames() */ + assert(target_index == 1 || target_index == 2); + other_source_index = 3 - target_index; + old_sidemask = (1 << other_source_index); /* 2 or 4 */ + source_deleted = (oldinfo->filemask == 1); + collision = ((newinfo->filemask & old_sidemask) != 0); + type_changed = !source_deleted && + (S_ISREG(oldinfo->stages[other_source_index].mode) != + S_ISREG(newinfo->stages[target_index].mode)); + if (type_changed && collision) { + /* special handling so later blocks can handle this */ + die("Not yet implemented"); + } + + assert(source_deleted || oldinfo->filemask & old_sidemask); + + /* Need to check for special types of rename conflicts... */ + if (collision && !source_deleted) { + /* collision: rename/add or rename/rename(2to1) */ + die("Not yet implemented"); + } else if (collision && source_deleted) { + /* rename/add/delete or rename/rename(2to1)/delete */ + die("Not yet implemented"); + } else { + /* a few different cases... */ + if (type_changed) { + /* rename vs. typechange */ + die("Not yet implemented"); + } else if (source_deleted) { + /* rename/delete */ + die("Not yet implemented"); + } else { + /* normal rename */ + die("Not yet implemented"); + } + } + + if (!type_changed) { + /* Mark the original as resolved by removal */ + oldinfo->merged.is_null = 1; + oldinfo->merged.clean = 1; + } + + } + + return clean_merge; } static int compare_pairs(const void *a_, const void *b_) From patchwork Tue Dec 15 18:28:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2787EC2BB48 for ; Tue, 15 Dec 2020 18:33:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5C5122B43 for ; Tue, 15 Dec 2020 18:33:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731656AbgLOScl (ORCPT ); Tue, 15 Dec 2020 13:32:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731097AbgLOS3a (ORCPT ); Tue, 15 Dec 2020 13:29:30 -0500 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0AA01C061248 for ; Tue, 15 Dec 2020 10:28:15 -0800 (PST) Received: by mail-wr1-x441.google.com with SMTP id 91so20834397wrj.7 for ; Tue, 15 Dec 2020 10:28:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=Mh8IztlLSQ78+8Nle71vq0UevQhQMFaqx6Tg45EiziI=; b=kIKU8YQbLtlVNcWpqpHUh0KgDsLyNv1Hqxh4pxTWfWNHovEJv5W4xLQGZdYF4VUMKK STHxo1eV3CJy80fEM/APnOR2cImQvufHWIN0JPG8BgMhHYfOpN2G8c3FoCl/LnfQGWsr wBOOLD9XL67OmEmu+ppoLLUCLJ+hqJNh1/HtZeWbOFukfgbbO8Tl17baAc58G0fMeCND iRXJJTgxp7dTbhRGJ2Pa9Hj9Y45M1gVBWMZiK/uB1khZOFlfhRpU+rJtgKzQF4EdO0HI iX3xNdfEtQ6RtyKn5AnTZefBapf+hQq4X+trSzQ24DxjQikunKUqJYOgB5Mnj9Y/H9YV zCsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=Mh8IztlLSQ78+8Nle71vq0UevQhQMFaqx6Tg45EiziI=; b=rRtztWhhhUFulGJd//ITRhJV19BEh7XHZnJHWrmW7k0jGwmI6lwz6lRKrggkeIM7RX OvG0o12Rz0x7CT5smfEwci5LSNXCigDBxnoV1LgWrHMWV0HIuNax2aMe0aB4UBFYQh0l L9BD49j1ItN4R0JXkK8LOYAt9hHrGSbZFceRdPVpRwjN16tp6j+tnZmqe6HOhL3yzr0P qJHy7injQtOq2c5G9hzUJp30fOpTFcPPaooym984J53sekOLBVuEpyJeeFpnaHaXAKCr /qkQqSWKxJwVXaA9e3e6a7DwNOT6dUU8fsfnwKDo1oW89adXP2PcHNV819o3k0RK/FmD 3PQA== X-Gm-Message-State: AOAM532nC8+xYBLU4LB0wvOrrtaHDbR3syFoWNZ6NBatsoFz5ogUBQo9 cV39nYave43LFIs6de1tWhGs9Him2RI= X-Google-Smtp-Source: ABdhPJylQmn+pAunLEVFbnHUKolQgrZf34ZAMToT+Q0Xpy1pj10XqhfinJggzZcLkZSpx6HxU9oz/g== X-Received: by 2002:adf:fb49:: with SMTP id c9mr4056285wrs.72.1608056893540; Tue, 15 Dec 2020 10:28:13 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p9sm32320460wmm.17.2020.12.15.10.28.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:13 -0800 (PST) Message-Id: <7ec51feb4189209bab7912d457a2f54fd0a3cc0e.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:01 +0000 Subject: [PATCH v3 06/11] merge-ort: add implementation of both sides renaming identically Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement rename/rename(1to1) handling, i.e. both sides of history renaming a file but renaming the same way. This code replaces the following from merge-recurisve.c: * all the 1to1 code in process_renames() * the RENAME_ONE_FILE_TO_ONE case of process_entry() Also, there is some shared code from merge-recursive.c for multiple different rename cases which we will no longer need for this case (or other rename cases): * handle_rename_normal() * setup_rename_conflict_info() The consolidation of four separate codepaths into one is made possible by a change in design: process_renames() tweaks the conflict_info entries within opt->priv->paths such that process_entry() can then handle all the non-rename conflict types (directory/file, modify/delete, etc.) orthogonally. This means we're much less likely to miss special implementation of some kind of combination of conflict types (see commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'", 2020-11-18), especially commit ef52778708 ("merge tests: expect improved directory/file conflict handling in ort", 2020-10-26) for more details). That, together with letting worktree/index updating be handled orthogonally in the merge_switch_to_result() function, dramatically simplifies the code for various special rename cases. Signed-off-by: Elijah Newren --- merge-ort.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index ebe275ef73c..da3715baa63 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -674,14 +674,30 @@ static int process_renames(struct merge_options *opt, !strcmp(oldpath, renames->queue[i+1]->one->path)) { /* Handle rename/rename(1to2) or rename/rename(1to1) */ const char *pathnames[3]; + struct version_info merged; + struct conflict_info *base, *side1, *side2; pathnames[0] = oldpath; pathnames[1] = newpath; pathnames[2] = renames->queue[i+1]->two->path; + base = strmap_get(&opt->priv->paths, pathnames[0]); + side1 = strmap_get(&opt->priv->paths, pathnames[1]); + side2 = strmap_get(&opt->priv->paths, pathnames[2]); + + VERIFY_CI(base); + VERIFY_CI(side1); + VERIFY_CI(side2); + if (!strcmp(pathnames[1], pathnames[2])) { - /* Both sides renamed the same way. */ - die("Not yet implemented"); + /* Both sides renamed the same way */ + assert(side1 == side2); + memcpy(&side1->stages[0], &base->stages[0], + sizeof(merged)); + side1->filemask |= (1 << MERGE_BASE); + /* Mark base as resolved by removal */ + base->merged.is_null = 1; + base->merged.clean = 1; /* We handled both renames, i.e. i+1 handled */ i++; From patchwork Tue Dec 15 18:28:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63C40C4361B for ; Tue, 15 Dec 2020 18:33:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D8B2227C3 for ; Tue, 15 Dec 2020 18:33:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731667AbgLOScl (ORCPT ); Tue, 15 Dec 2020 13:32:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731252AbgLOS3b (ORCPT ); Tue, 15 Dec 2020 13:29:31 -0500 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34048C0611C5 for ; Tue, 15 Dec 2020 10:28:16 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id c5so17197952wrp.6 for ; Tue, 15 Dec 2020 10:28:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=jqrshys1PBZBm3tZpHK86UWzCXBVH+6N8C7lohnC76k=; b=Isk7qSbm+47mHJsEF6XGNrmSS+VTQVjFxcEjXIkah6P7iPDpcCnDjCrdWDoVYAiiHX azCUtY531GIUp+nfEvWOFxDKg0RuP6jAtKbPYU8fyUCnswSbFrzI8x+cUCCSK73RjvhF yrQKdqFJSGbvG6gfkPSKU3B2q32PcPCrj3coZvvvWFh0u7w4TnGu2L5GBy/O+bp98wds hw+F9uxxSKQoG7BO68KLJc2QkctlUeiD6dZrOiyp8GzF62KS0iXbh5pSzFk3Avdz587z 4eLjed9nakcL09m000M9H7VZpZgoS2har3GaRtfon6ex2CAeP8h9lW/HNyPLTJS+fYFg Rzaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=jqrshys1PBZBm3tZpHK86UWzCXBVH+6N8C7lohnC76k=; b=DoATyscG6gvNvoGRGqejin8WOdBRyECCh3+CBtCZSYc1ZqmpruP9Dj87w3Tyspl2dn HT2+nA02DVOoMSzcfpBGXTU9pi/i61vAnbvPXQRvhfLNiZpQs89Q7v7aedJhsHQRvjAa jq4pO6zbveYlAXZl3V4XSFn4JoThzBupxwEaEoERfEtQ9U8ZHMqGbTs8E8wBq1exNxdD XM8UmGLjMk/1QNKiHHN9EFqLgzhOyNQm4biW605mfPfqEm9n/YX36YyWiW9rbuPIFiEe JJ421jMORUC3XUpQVcoOydtXi5w7tDVvKakjjZTCrWhXP344L0EeSlWbY2MDakG9vOKj 6jAw== X-Gm-Message-State: AOAM530+XExe6UAaFAa6PaOGmv6MhNMWrhdoLGPk0H95kq7sz4CoxFX0 O5PhEk4YKx9UxGi+kAuytY3PLFflFP8= X-Google-Smtp-Source: ABdhPJxi2CCCwmDOSjxlt3kg75LxraT3Uk54eij/z5IPmKYF/a8W+oB6vlSlyoEpLx/KN7SJClGt7g== X-Received: by 2002:adf:fb05:: with SMTP id c5mr6058121wrr.69.1608056894473; Tue, 15 Dec 2020 10:28:14 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q73sm39341506wme.44.2020.12.15.10.28.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:14 -0800 (PST) Message-Id: In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:02 +0000 Subject: [PATCH v3 07/11] merge-ort: add implementation of both sides renaming differently Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement rename/rename(1to2) handling, i.e. both sides of history renaming a file and rename it differently. This code replaces the following from merge-recurisve.c: * all the 1to2 code in process_renames() * the RENAME_ONE_FILE_TO_TWO case of process_entry() * handle_rename_rename_1to2() Also, there is some shared code from merge-recursive.c for multiple different rename cases which we will no longer need for this case (or other rename cases): * handle_file_collision() * setup_rename_conflict_info() The consolidation of five separate codepaths into one is made possible by a change in design: process_renames() tweaks the conflict_info entries within opt->priv->paths such that process_entry() can then handle all the non-rename conflict types (directory/file, modify/delete, etc.) orthogonally. This means we're much less likely to miss special implementation of some kind of combination of conflict types (see commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'", 2020-11-18), especially commit ef52778708 ("merge tests: expect improved directory/file conflict handling in ort", 2020-10-26) for more details). That, together with letting worktree/index updating be handled orthogonally in the merge_switch_to_result() function, dramatically simplifies the code for various special rename cases. To be fair, there is a _slight_ tweak to process_entry() here to make sure that the two different paths aren't marked as clean but are left in a conflicted state. So process_renames() and process_entry() aren't quite entirely orthogonal, but they are pretty close. Signed-off-by: Elijah Newren --- merge-ort.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index da3715baa63..19477cfae60 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -676,6 +676,7 @@ static int process_renames(struct merge_options *opt, const char *pathnames[3]; struct version_info merged; struct conflict_info *base, *side1, *side2; + unsigned was_binary_blob = 0; pathnames[0] = oldpath; pathnames[1] = newpath; @@ -706,7 +707,58 @@ static int process_renames(struct merge_options *opt, } /* This is a rename/rename(1to2) */ - die("Not yet implemented"); + clean_merge = handle_content_merge(opt, + pair->one->path, + &base->stages[0], + &side1->stages[1], + &side2->stages[2], + pathnames, + 1 + 2 * opt->priv->call_depth, + &merged); + if (!clean_merge && + merged.mode == side1->stages[1].mode && + oideq(&merged.oid, &side1->stages[1].oid)) + was_binary_blob = 1; + memcpy(&side1->stages[1], &merged, sizeof(merged)); + if (was_binary_blob) { + /* + * Getting here means we were attempting to + * merge a binary blob. + * + * Since we can't merge binaries, + * handle_content_merge() just takes one + * side. But we don't want to copy the + * contents of one side to both paths. We + * used the contents of side1 above for + * side1->stages, let's use the contents of + * side2 for side2->stages below. + */ + oidcpy(&merged.oid, &side2->stages[2].oid); + merged.mode = side2->stages[2].mode; + } + memcpy(&side2->stages[2], &merged, sizeof(merged)); + + side1->path_conflict = 1; + side2->path_conflict = 1; + /* + * TODO: For renames we normally remove the path at the + * old name. It would thus seem consistent to do the + * same for rename/rename(1to2) cases, but we haven't + * done so traditionally and a number of the regression + * tests now encode an expectation that the file is + * left there at stage 1. If we ever decide to change + * this, add the following two lines here: + * base->merged.is_null = 1; + * base->merged.clean = 1; + * and remove the setting of base->path_conflict to 1. + */ + base->path_conflict = 1; + path_msg(opt, oldpath, 0, + _("CONFLICT (rename/rename): %s renamed to " + "%s in %s and to %s in %s."), + pathnames[0], + pathnames[1], opt->branch1, + pathnames[2], opt->branch2); i++; /* We handled both renames, i.e. i+1 handled */ continue; @@ -1291,13 +1343,13 @@ static void process_entry(struct merge_options *opt, int side = (ci->filemask == 4) ? 2 : 1; ci->merged.result.mode = ci->stages[side].mode; oidcpy(&ci->merged.result.oid, &ci->stages[side].oid); - ci->merged.clean = !ci->df_conflict; + ci->merged.clean = !ci->df_conflict && !ci->path_conflict; } else if (ci->filemask == 1) { /* Deleted on both sides */ ci->merged.is_null = 1; ci->merged.result.mode = 0; oidcpy(&ci->merged.result.oid, &null_oid); - ci->merged.clean = 1; + ci->merged.clean = !ci->path_conflict; } /* From patchwork Tue Dec 15 18:28:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95A3EC2BB48 for ; Tue, 15 Dec 2020 18:33:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 668A622B47 for ; Tue, 15 Dec 2020 18:33:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731562AbgLOSct (ORCPT ); Tue, 15 Dec 2020 13:32:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731267AbgLOS3b (ORCPT ); Tue, 15 Dec 2020 13:29:31 -0500 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC5F1C0611CA for ; Tue, 15 Dec 2020 10:28:16 -0800 (PST) Received: by mail-wr1-x436.google.com with SMTP id m5so20823301wrx.9 for ; Tue, 15 Dec 2020 10:28:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=9dXUSfk4gXDbJgWZJ+YVJrGIa/oWkxkwmFfnDNWUNoI=; b=obA2UbWBb0kAy6qMpGHy4xFTh+SV9F+L+b0whgeP3+pNzAYEz/XT+Yedi+70DGmU6H pv1+42vgGpi4fRo3HioPaQmY/ayMNbrDrFs7eDBCZrl/XSIfD2x05krx0KpF0ScrOhCR lYj3vSR3LHBhEaxzOHXK7VNSm3iyy7+qQDl9wbPqXvMLcdFo1ye7qNpU1wMkwptmI7VI VLHk55hsFGis5+XADqRwbT0VTk6nW/6y77koijhjRyUPvr3X7eer0QcNvoRSUL5Xk4oq QcEGW0YWuV2VkpskdAOC9RM7MLH1Y3JnyBjzhkSBrNVVbqMhDc7QTPStGCGCd4RPRslc OChg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=9dXUSfk4gXDbJgWZJ+YVJrGIa/oWkxkwmFfnDNWUNoI=; b=oiwTnxRnlhhjznzv9okm5H3x7T3XydTBDznPPONTGvbIh5Afoc1ZuMSkKg0AsVKkOi t2U6eKwBuagsEGMZsIOEChREl3qa5MMdGaVC21Q5Vr/BbHsB4l5HeptHRx5KStb89xzu OPnZg37scmylYPpLrRB8XuxrXSXH9zflp2g7lAYABP7e8r9y5yt1Bb+Z1NAjEfTxX81K otnEzi5YGk08Bw5y4re9FrAC/rc69uzsPdxGUFr62LI9qNRD8chmvyjzCc9Fdbr1LS6A R2w9VOvT1a5XoQLYYPE1oh7g2WS7XwqNCefixaqnPGH+XgSypTnUaFPT6y86duGfd2k7 LoMQ== X-Gm-Message-State: AOAM533AaPhsUHE2DH6FdVWP+n67v2B+lwokOhl8UA/UMBXwz/OiFMj8 cusJbZlqjxfbwsmKzKMuMPJ/8SL0Kr4= X-Google-Smtp-Source: ABdhPJw7tQG2PQC4mezMUbDnFw2HZWVjrsBTjyn548Ni2ghYRaaoYw4PqbJ2czwxUitIKD1blQdCfw== X-Received: by 2002:adf:fd0c:: with SMTP id e12mr33786397wrr.61.1608056895389; Tue, 15 Dec 2020 10:28:15 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t10sm38218819wrp.39.2020.12.15.10.28.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:14 -0800 (PST) Message-Id: <6b79da5e8a40e768b91d0742aff2919a0095a3f9.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:03 +0000 Subject: [PATCH v3 08/11] merge-ort: add implementation of rename/delete conflicts Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement rename/delete conflicts, i.e. one side renames a file and the other deletes the file. This code replaces the following from merge-recurisve.c: * the code relevant to RENAME_DELETE in process_renames() * the RENAME_DELETE case of process_entry() * handle_rename_delete() Also, there is some shared code from merge-recursive.c for multiple different rename cases which we will no longer need for this case (or other rename cases): * handle_change_delete() * setup_rename_conflict_info() The consolidation of five separate codepaths into one is made possible by a change in design: process_renames() tweaks the conflict_info entries within opt->priv->paths such that process_entry() can then handle all the non-rename conflict types (directory/file, modify/delete, etc.) orthogonally. This means we're much less likely to miss special implementation of some kind of combination of conflict types (see commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'", 2020-11-18), especially commit ef52778708 ("merge tests: expect improved directory/file conflict handling in ort", 2020-10-26) for more details). That, together with letting worktree/index updating be handled orthogonally in the merge_switch_to_result() function, dramatically simplifies the code for various special rename cases. To be fair, there is a _slight_ tweak to process_entry() here, because rename/delete cases will also trigger the modify/delete codepath. However, we only want a modify/delete message to be printed for a rename/delete conflict if there is a content change in the renamed file in addition to the rename. So process_renames() and process_entry() aren't quite fully orthogonal, but they are pretty close. Signed-off-by: Elijah Newren --- merge-ort.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 19477cfae60..a10c3f5046f 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -657,6 +657,7 @@ static int process_renames(struct merge_options *opt, unsigned int old_sidemask; int target_index, other_source_index; int source_deleted, collision, type_changed; + const char *rename_branch = NULL, *delete_branch = NULL; old_ent = strmap_get_entry(&opt->priv->paths, pair->one->path); oldpath = old_ent->key; @@ -779,6 +780,15 @@ static int process_renames(struct merge_options *opt, /* special handling so later blocks can handle this */ die("Not yet implemented"); } + if (source_deleted) { + if (target_index == 1) { + rename_branch = opt->branch1; + delete_branch = opt->branch2; + } else { + rename_branch = opt->branch2; + delete_branch = opt->branch1; + } + } assert(source_deleted || oldinfo->filemask & old_sidemask); @@ -790,13 +800,26 @@ static int process_renames(struct merge_options *opt, /* rename/add/delete or rename/rename(2to1)/delete */ die("Not yet implemented"); } else { - /* a few different cases... */ + /* + * a few different cases...start by copying the + * existing stage(s) from oldinfo over the newinfo + * and update the pathname(s). + */ + memcpy(&newinfo->stages[0], &oldinfo->stages[0], + sizeof(newinfo->stages[0])); + newinfo->filemask |= (1 << MERGE_BASE); + newinfo->pathnames[0] = oldpath; if (type_changed) { /* rename vs. typechange */ die("Not yet implemented"); } else if (source_deleted) { /* rename/delete */ - die("Not yet implemented"); + newinfo->path_conflict = 1; + path_msg(opt, newpath, 0, + _("CONFLICT (rename/delete): %s renamed" + " to %s in %s, but deleted in %s."), + oldpath, newpath, + rename_branch, delete_branch); } else { /* normal rename */ die("Not yet implemented"); @@ -1332,12 +1355,21 @@ static void process_entry(struct merge_options *opt, modify_branch = (side == 1) ? opt->branch1 : opt->branch2; delete_branch = (side == 1) ? opt->branch2 : opt->branch1; - path_msg(opt, path, 0, - _("CONFLICT (modify/delete): %s deleted in %s " - "and modified in %s. Version %s of %s left " - "in tree."), - path, delete_branch, modify_branch, - modify_branch, path); + if (ci->path_conflict && + oideq(&ci->stages[0].oid, &ci->stages[side].oid)) { + /* + * This came from a rename/delete; no action to take, + * but avoid printing "modify/delete" conflict notice + * since the contents were not modified. + */ + } else { + path_msg(opt, path, 0, + _("CONFLICT (modify/delete): %s deleted in %s " + "and modified in %s. Version %s of %s left " + "in tree."), + path, delete_branch, modify_branch, + modify_branch, path); + } } else if (ci->filemask == 2 || ci->filemask == 4) { /* Added on one side */ int side = (ci->filemask == 4) ? 2 : 1; From patchwork Tue Dec 15 18:28:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A22D9C2BBCF for ; Tue, 15 Dec 2020 18:31:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7E05122B2D for ; Tue, 15 Dec 2020 18:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731501AbgLOS3h (ORCPT ); Tue, 15 Dec 2020 13:29:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731330AbgLOS3c (ORCPT ); Tue, 15 Dec 2020 13:29:32 -0500 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCE06C0611CB for ; Tue, 15 Dec 2020 10:28:17 -0800 (PST) Received: by mail-wm1-x330.google.com with SMTP id a3so137719wmb.5 for ; Tue, 15 Dec 2020 10:28:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=1Hl5t6ldWvNNCki4XoGnclhpcPrhke0r9Tp4YSPkKKE=; b=c0RP6SyQ5zg2BtOTlqbqXRNT27Fy/p+szQx2W32MCEjsdIJDfVB2zHgU+jXsmOD0Pc GljzsbZwVmkOpZZ3Ch8yF4fgOGX+4y0gZp5pVm+gNtYO8UeWgIUHq/+35IRdweNiyhPu C3feRvCl2WmNLWA1HBqaTp1QFvDXKyzI/qhhzwCsRrlkDPalWvpKcGiJATYk9uEBLp/3 EhI8hYzdFq1KhajBxxET2faxum9KR22Aiuj+KZztXmTQxm2Y1qH8e7jM1MQ4NzijRXrd goUuAlEUUhZbnfg1MuMYtBeR8aVEkkjaZnMIqnJf66NLX71YwEGPqHTIZwxpK3skTX9C gBnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=1Hl5t6ldWvNNCki4XoGnclhpcPrhke0r9Tp4YSPkKKE=; b=Lfyj90+dKYOA8NJlpB/d92cGNPDJE3faQAJr3YS2aT6a656m/AaQ5DHLMeMfgpTcmd ZwbIGxOqV1JzciCy+3rC7+tNcLtKxdr9+Dw7xkzzonh7Lhr/YtKnkLzUjUlmZNKHw7cm 7lH4mjcdeinXtaBEp1lAoY3DjUdfnZ7UyqH0EJD3JLeV16/rJ0j9oX4SP8h2tB+nH2rK vdstSA7r0WAyS5anvm7qPiWuDjqJojByvCT6T7aFDqm9UYpIQNQmseZ+vaAhEJW7Estx UAqEAcajt7cFG80w6a/2SkFJkSo9bit/NXklqKYXRjlXXY7gJOCQdMIw0ETMGlqxrnlr S8rQ== X-Gm-Message-State: AOAM533TxCnSQ61HYen3uXnzOQaR+widlMjrIXpiOLDfYyiRajqUeA8Y cTL0xzc+VJRP1Ar32tp6Si3uE+dhPL0= X-Google-Smtp-Source: ABdhPJxUgdBfDht3MF+yOA3iJIe8du6HagVSY4bMh0NeBagCpXALjFNv0vGURO5s1A9pm6fmzNIc/w== X-Received: by 2002:a1c:bb07:: with SMTP id l7mr182736wmf.9.1608056896279; Tue, 15 Dec 2020 10:28:16 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id u66sm38747651wmg.2.2020.12.15.10.28.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:15 -0800 (PST) Message-Id: <065fc0396dcb0dac080fd921209f77b824eee633.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:04 +0000 Subject: [PATCH v3 09/11] merge-ort: add implementation of rename collisions Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement rename/rename(2to1) and rename/add handling, i.e. a file is renamed into a location where another file is added (with that other file either being a plain add or itself coming from a rename). Note that rename collisions can also have a special case stacked on top: the file being renamed on one side of history is deleted on the other (yielding either a rename/add/delete conflict or perhaps a rename/rename(2to1)/delete[/delete]) conflict. One thing to note here is that when there is a double rename, the code in question only handles one of them at a time; a later iteration through the loop will handle the other. After they've both been handled, process_entry()'s normal add/add code can handle the collision. This code replaces the following from merge-recurisve.c: * all the 2to1 code in process_renames() * the RENAME_TWO_FILES_TO_ONE case of process_entry() * handle_rename_rename_2to1() * handle_rename_add() Also, there is some shared code from merge-recursive.c for multiple different rename cases which we will no longer need for this case (or other rename cases): * handle_file_collision() * setup_rename_conflict_info() The consolidation of six separate codepaths into one is made possible by a change in design: process_renames() tweaks the conflict_info entries within opt->priv->paths such that process_entry() can then handle all the non-rename conflict types (directory/file, modify/delete, etc.) orthogonally. This means we're much less likely to miss special implementation of some kind of combination of conflict types (see commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'", 2020-11-18), especially commit ef52778708 ("merge tests: expect improved directory/file conflict handling in ort", 2020-10-26) for more details). That, together with letting worktree/index updating be handled orthogonally in the merge_switch_to_result() function, dramatically simplifies the code for various special rename cases. Signed-off-by: Elijah Newren --- merge-ort.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index a10c3f5046f..1c5b2f7e3b9 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -795,10 +795,58 @@ static int process_renames(struct merge_options *opt, /* Need to check for special types of rename conflicts... */ if (collision && !source_deleted) { /* collision: rename/add or rename/rename(2to1) */ - die("Not yet implemented"); + const char *pathnames[3]; + struct version_info merged; + + struct conflict_info *base, *side1, *side2; + unsigned clean; + + pathnames[0] = oldpath; + pathnames[other_source_index] = oldpath; + pathnames[target_index] = newpath; + + base = strmap_get(&opt->priv->paths, pathnames[0]); + side1 = strmap_get(&opt->priv->paths, pathnames[1]); + side2 = strmap_get(&opt->priv->paths, pathnames[2]); + + VERIFY_CI(base); + VERIFY_CI(side1); + VERIFY_CI(side2); + + clean = handle_content_merge(opt, pair->one->path, + &base->stages[0], + &side1->stages[1], + &side2->stages[2], + pathnames, + 1 + 2 * opt->priv->call_depth, + &merged); + + memcpy(&newinfo->stages[target_index], &merged, + sizeof(merged)); + if (!clean) { + path_msg(opt, newpath, 0, + _("CONFLICT (rename involved in " + "collision): rename of %s -> %s has " + "content conflicts AND collides " + "with another path; this may result " + "in nested conflict markers."), + oldpath, newpath); + } } else if (collision && source_deleted) { - /* rename/add/delete or rename/rename(2to1)/delete */ - die("Not yet implemented"); + /* + * rename/add/delete or rename/rename(2to1)/delete: + * since oldpath was deleted on the side that didn't + * do the rename, there's not much of a content merge + * we can do for the rename. oldinfo->merged.is_null + * was already set, so we just leave things as-is so + * they look like an add/add conflict. + */ + + newinfo->path_conflict = 1; + path_msg(opt, newpath, 0, + _("CONFLICT (rename/delete): %s renamed " + "to %s in %s, but deleted in %s."), + oldpath, newpath, rename_branch, delete_branch); } else { /* * a few different cases...start by copying the From patchwork Tue Dec 15 18:28:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36C54C4361B for ; Tue, 15 Dec 2020 18:31:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCACF227C3 for ; Tue, 15 Dec 2020 18:31:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731551AbgLOS3h (ORCPT ); Tue, 15 Dec 2020 13:29:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730960AbgLOS3c (ORCPT ); Tue, 15 Dec 2020 13:29:32 -0500 Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2F19C0611CC for ; Tue, 15 Dec 2020 10:28:18 -0800 (PST) Received: by mail-wm1-x343.google.com with SMTP id a3so137753wmb.5 for ; Tue, 15 Dec 2020 10:28:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=S4/DVQKCYPIWucP+lIG6DURVvz/AJQSCPqWWg0rL0oY=; b=SUlqqQMmd8qdpIdDUKbQmuavDhchcxqlIkfHrf6yRt285o17A/pW8r595N6Rl2ukPq s7MLrgY+WyzL/5e0wnAhbLJcfX46llUZtQ5AWac5ksgUu84XB1tFEavCk04YfjZQYOYm rvO/FQ9GD4wFB4QCPFrQvtmUrTDhMvlPECtjcOhXiXqTZy+IO7/8Au+WuZ/uJyNmSnpy 7nGu5fr3PEszRcnIb6FnsX0KHfjfjCtYSVbwy6reGVUUoe+WwkcrN9WReZNlixd1wCJk ImRpBlz8TMSLuRpGdU44YC1TWJyvDfTNRDoRXd4jeZQO1wgPG073e9HQmTNzTNjSZ0Ws BIJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=S4/DVQKCYPIWucP+lIG6DURVvz/AJQSCPqWWg0rL0oY=; b=iZVaM22aH+/YPJCwmxC+PGDrjG9Ih/f2WI2CiRMvQOiprK2tmKBYQSm7VDe1kpBCEV O3arVorjFQ8jQT2ZqEK2urt6cH+DMORW9Nw0mt35hbxUANnP5uGpuoZZTXNpHMA3HK+L kLJnQytgf0KTpN89JoWdQh42ezNvI+JZSwqObNViAqJHB+xHjaVMAkFDm5jMq4w9ul1x Ukb3oSYwP8d/jWK7lgFyV0KMaD3pnHWrOeScF4b96sEksZgI7Digl40xpTz+YpN4u7uZ 0ckc4A49RRArKkaJqMt09FR1eAMNGeDz7aCAS62yups4AbcBRhX3Ujlxy23OI0EBL1w8 p55g== X-Gm-Message-State: AOAM531NdU7+trRfOG8qVRO/jfy7+7AmOgGHb5Os547vH9OWs06/qOnV 5a3/0KdFyF9K/UWC0HE+C5AT1u1NL+k= X-Google-Smtp-Source: ABdhPJwv6JPnjP0IhN22rm/UQVtqBN9q8Ja0BaEsbcn3EtMhkt+FluydezXHhXWLi18fyqoWd4p/Jg== X-Received: by 2002:a1c:25c2:: with SMTP id l185mr162696wml.113.1608056897229; Tue, 15 Dec 2020 10:28:17 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x18sm35828319wrg.55.2020.12.15.10.28.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:16 -0800 (PST) Message-Id: <73426c166877194d3c53a2ea250751318d223d21.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:05 +0000 Subject: [PATCH v3 10/11] merge-ort: add implementation of normal rename handling Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement handling of normal renames. This code replaces the following from merge-recurisve.c: * the code relevant to RENAME_NORMAL in process_renames() * the RENAME_NORMAL case of process_entry() Also, there is some shared code from merge-recursive.c for multiple different rename cases which we will no longer need for this case (or other rename cases): * handle_rename_normal() * setup_rename_conflict_info() The consolidation of four separate codepaths into one is made possible by a change in design: process_renames() tweaks the conflict_info entries within opt->priv->paths such that process_entry() can then handle all the non-rename conflict types (directory/file, modify/delete, etc.) orthogonally. This means we're much less likely to miss special implementation of some kind of combination of conflict types (see commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'", 2020-11-18), especially commit ef52778708 ("merge tests: expect improved directory/file conflict handling in ort", 2020-10-26) for more details). That, together with letting worktree/index updating be handled orthogonally in the merge_switch_to_result() function, dramatically simplifies the code for various special rename cases. (To be fair, the code for handling normal renames wasn't all that complicated beforehand, but it's still much simpler now.) Signed-off-by: Elijah Newren --- merge-ort.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index 1c5b2f7e3b9..26f357e524f 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -870,7 +870,11 @@ static int process_renames(struct merge_options *opt, rename_branch, delete_branch); } else { /* normal rename */ - die("Not yet implemented"); + memcpy(&newinfo->stages[other_source_index], + &oldinfo->stages[other_source_index], + sizeof(newinfo->stages[0])); + newinfo->filemask |= (1 << other_source_index); + newinfo->pathnames[other_source_index] = oldpath; } } From patchwork Tue Dec 15 18:28:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11975573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D411C2BB48 for ; Tue, 15 Dec 2020 18:30:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 651CD22B2D for ; Tue, 15 Dec 2020 18:30:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731570AbgLOS3p (ORCPT ); Tue, 15 Dec 2020 13:29:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730346AbgLOS3h (ORCPT ); Tue, 15 Dec 2020 13:29:37 -0500 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0DAFC0611CD for ; Tue, 15 Dec 2020 10:28:19 -0800 (PST) Received: by mail-wm1-x334.google.com with SMTP id q75so153893wme.2 for ; Tue, 15 Dec 2020 10:28:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=FuVethZdiI2jUh5+5cKumgbbQ/flJO7nj960YyQLtEA=; b=u1sXvIPzA3oqWOVQWLILBNfl4sKdLzQNKw7700Tev8VldEhAnbTdn3NSYSkmUtOKYn 7PdJHAxr28BljmVDs4k7p7jDrPkIerG8u7bgPF1HsmnpeBcw2dORMCv/H4heRQndhE5g gNK6KwZvBM6dyanMvmCcZ7u3+p7/FSxEBz+zCM0G1MJF/AMNs0zOXt9X4EfprHz1WwAN q3k5+vRbvF1Imx/BCsUIPEqRMJRglevZbDj59yf1bMvxa4r3RkpvLrUjQMyhXrSn/7EQ 3qXQjBmkcRkzJAh1NTfyxqkpn+rU8Gg3qSDFNZhLmMTe8gRanogfQkuq071P88qqVkx1 nyyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=FuVethZdiI2jUh5+5cKumgbbQ/flJO7nj960YyQLtEA=; b=IztROVDmVTS3z6MNHVo0Q2wGRYI+Ws4GRaN1CFKoyvliMx+ebqfRgIIljCQXELYeiE EuSiB6S4z0LGzK576YQQfbq2Px2LClUlmINOiYUfrOmxOiPpPUOCrMJV5GTLP8o2QKWO RdBCTsx9KknV12iBEIb/o3vjVAuRR+vyN2CVhi/2iNP9AIiS/KHS9xi8JitqR0bnu/lw HwvRCbFwcP+vYsuZRoc1fJu37MreUEIfL8yQpaew3uoxZkbh2EUX2bGbNeb/EUYF9GER CwY82Ri7c09VcMqlPqCvSdMLXI7c0JfezGAuRUea+OoyZcE9hHB76M6d84xcF3+BVaeM /wzQ== X-Gm-Message-State: AOAM5315Vbmn7/s4O+6xn1Ns2pXmgUo+hOPp85vYij5KH96BtwP5F/gi 3rJEfwjzEOlZHHL/4R7ilSy+kBZ2bPk= X-Google-Smtp-Source: ABdhPJzn7fmnaflN+Xr/pxyzEz4I8TVc+Wjw0TuT7dOlcVZjOle7geuQA1UwHQkwh6NEuni9DYlv/g== X-Received: by 2002:a1c:5f54:: with SMTP id t81mr167185wmb.77.1608056898094; Tue, 15 Dec 2020 10:28:18 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r82sm39022356wma.18.2020.12.15.10.28.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Dec 2020 10:28:17 -0800 (PST) Message-Id: <8f4662398ab4421a466b88b8984bd047528f31f1.1608056886.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 15 Dec 2020 18:28:06 +0000 Subject: [PATCH v3 11/11] merge-ort: add implementation of type-changed rename handling Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Derrick Stolee , Elijah Newren , Johannes Schindelin , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement cases where renames are involved in type changes (i.e. the side of history that didn't rename the file changed its type from a regular file to a symlink or submodule). There was some code to handle this in merge-recursive but only in the special case when the renamed file had no content changes. The code here works differently -- it knows process_entry() can handle mode conflicts, so it does a few minimal tweaks to ensure process_entry() can just finish the job as needed. Signed-off-by: Elijah Newren --- merge-ort.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 26f357e524f..677c6a878c5 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -777,8 +777,33 @@ static int process_renames(struct merge_options *opt, (S_ISREG(oldinfo->stages[other_source_index].mode) != S_ISREG(newinfo->stages[target_index].mode)); if (type_changed && collision) { - /* special handling so later blocks can handle this */ - die("Not yet implemented"); + /* + * special handling so later blocks can handle this... + * + * if type_changed && collision are both true, then this + * was really a double rename, but one side wasn't + * detected due to lack of break detection. I.e. + * something like + * orig: has normal file 'foo' + * side1: renames 'foo' to 'bar', adds 'foo' symlink + * side2: renames 'foo' to 'bar' + * In this case, the foo->bar rename on side1 won't be + * detected because the new symlink named 'foo' is + * there and we don't do break detection. But we detect + * this here because we don't want to merge the content + * of the foo symlink with the foo->bar file, so we + * have some logic to handle this special case. The + * easiest way to do that is make 'bar' on side1 not + * be considered a colliding file but the other part + * of a normal rename. If the file is very different, + * well we're going to get content merge conflicts + * anyway so it doesn't hurt. And if the colliding + * file also has a different type, that'll be handled + * by the content merge logic in process_entry() too. + * + * See also t6430, 'rename vs. rename/symlink' + */ + collision = 0; } if (source_deleted) { if (target_index == 1) { @@ -859,7 +884,11 @@ static int process_renames(struct merge_options *opt, newinfo->pathnames[0] = oldpath; if (type_changed) { /* rename vs. typechange */ - die("Not yet implemented"); + /* Mark the original as resolved by removal */ + memcpy(&oldinfo->stages[0].oid, &null_oid, + sizeof(oldinfo->stages[0].oid)); + oldinfo->stages[0].mode = 0; + oldinfo->filemask &= 0x06; } else if (source_deleted) { /* rename/delete */ newinfo->path_conflict = 1;