From patchwork Fri Dec 18 05:51:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981169 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 6782BC2BBD4 for ; Fri, 18 Dec 2020 05:52:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1940A23A57 for ; Fri, 18 Dec 2020 05:52:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728140AbgLRFwM (ORCPT ); Fri, 18 Dec 2020 00:52:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726045AbgLRFwL (ORCPT ); Fri, 18 Dec 2020 00:52:11 -0500 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 597ABC0617B0 for ; Thu, 17 Dec 2020 21:51:31 -0800 (PST) Received: by mail-wm1-x333.google.com with SMTP id 3so1214151wmg.4 for ; Thu, 17 Dec 2020 21:51:31 -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=z7fgkyh1UyUiX/qF3rRPmjr7ypy84zpeUgU7ex7QbZg=; b=Jo3Cz10ThrWS1YIny8B8xa6+ekrTpj+SJwul75ASFZT7obhFmv1a6XTiHDA6n3G0Ts WssD/No/gj358UzvwzdGcb1E3uHzGjhev06xL0QMGGlC07f4G0cmPxc7GfGgFiBBMm7h t10CYxOppEwbsz/M1OWyRGf/08NQb3xwCKlHQDXDWD/oNB4ue2kT3UzSRC+pYykoWHsj 88m0CyYSssLaamRkoe26fFiKNdQBoPji0ReIzAa/MZpRrwPw2U7CtHV+EKyvnXBUcJGD /87JwOUSt2NTnVfQY9DjTma7LUY0UdVdn8Ov3ASGCY/Oc9BajJyEk0nkzE+tqN/9sh6t 54UQ== 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=z7fgkyh1UyUiX/qF3rRPmjr7ypy84zpeUgU7ex7QbZg=; b=OrBTJQlBF24pvOKyo9ocIVolKutsNaWRA400Qp+weB9QAjn0NpwO1wH861YWsEH95p OTxMIXSR8G0n2BmrikffAhZKXyArJCtfZU9k1aQHc/hGW4UyPv0Uxk0tLrPRGLAsPKd9 umYY7rzijd+iclOzp89CshJ40snAj44j6rbRNMpyfMCJnjeFqoZ3Z46RSl2RkrCD6xS9 RWGmwn0cKTuFkml9wwF3Dmlr/7I0MWoiAvzF0XyjImzSoP+cKMvrltQlkjoVP2z9CbIe t7mJcxtjPUDmT4Hmz3tU/vLnsJ4kRobeuFedQQC5PwM4VIJ9FedOiq2eklvt4+/ySJ2r 24BA== X-Gm-Message-State: AOAM533JbuuwHncbPlgMeLgMbuHoWqM5lYpwytbjGbnHBISvHnuwCutz 3y5Ekqu3E2Is2FitJeeL6ZNTPNvX5ts= X-Google-Smtp-Source: ABdhPJwHyhrV/GsCZWwF6XT0Ul9yTHXOAcaFufhcehjIK8TxKAZ24ONy8vdsuGmXvCfsvqlp6KlUsQ== X-Received: by 2002:a1c:f706:: with SMTP id v6mr2508945wmh.85.1608270689876; Thu, 17 Dec 2020 21:51:29 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a12sm13363666wrh.71.2020.12.17.21.51.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:29 -0800 (PST) Message-Id: <382a009c18efc8a46a9c0210754f2266c3116ee4.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:18 +0000 Subject: [PATCH 01/10] merge-ort: handle D/F conflict where directory disappears due to merge Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren When one side has a directory at a given path and the other side of history has a file at the path, but the merge resolves the directory away (e.g. because no path within that directory was modified and the other side deleted it, or because renaming moved all the files elsewhere), then we don't actually have a conflict anymore. We just need to clear away any information related to the relevant directory, and then the subsequent process_entry() handling can handle the given path. Signed-off-by: Elijah Newren --- merge-ort.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 414e7b7eeac..f9a79eb25e6 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -976,14 +976,35 @@ static void process_entry(struct merge_options *opt, assert(ci->df_conflict); } - if (ci->df_conflict) { + if (ci->df_conflict && ci->merged.result.mode == 0) { + int i; + + /* + * directory no longer in the way, but we do have a file we + * need to place here so we need to clean away the "directory + * merges to nothing" result. + */ + ci->df_conflict = 0; + assert(ci->filemask != 0); + ci->merged.clean = 0; + ci->merged.is_null = 0; + /* and we want to zero out any directory-related entries */ + ci->match_mask = (ci->match_mask & ~ci->dirmask); + ci->dirmask = 0; + for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) { + if (ci->filemask & (1 << i)) + continue; + ci->stages[i].mode = 0; + oidcpy(&ci->stages[i].oid, &null_oid); + } + } else if (ci->df_conflict && ci->merged.result.mode != 0) { die("Not yet implemented."); } /* * NOTE: Below there is a long switch-like if-elseif-elseif... block * which the code goes through even for the df_conflict cases - * above. Well, it will once we don't die-not-implemented above. + * above. */ if (ci->match_mask) { ci->merged.clean = 1; From patchwork Fri Dec 18 05:51:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981175 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 43D3FC2BBD4 for ; Fri, 18 Dec 2020 05:52:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 103CA23A57 for ; Fri, 18 Dec 2020 05:52:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731747AbgLRFwO (ORCPT ); Fri, 18 Dec 2020 00:52:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726045AbgLRFwO (ORCPT ); Fri, 18 Dec 2020 00:52:14 -0500 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71EE6C061282 for ; Thu, 17 Dec 2020 21:51:33 -0800 (PST) Received: by mail-wr1-x42e.google.com with SMTP id t16so822805wra.3 for ; Thu, 17 Dec 2020 21:51:33 -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=b/lQQhK8bSffDw3/2icwtSxNT2UhUhNVLirkuVtqw5E=; b=IjtTPoHWFQ5WopaSUmaAz5G4usug9Tv1AhEp50ADR8LlKobNFttmNXNV7IDrDKbGhR MY8rx4qqwF/TFTKJ9aOAHofXqMMJXs2RBugjcP1qv0CYSs/5rXtuRwJWaYdia+JnbQD/ KHwiv1L8thv+0fIiuClnP6DYrlfmV2hub8LJHpz3+bNVwHfplxsf5uuonHn46aNVGxyk K+h8l9WOVCToIyRtfSNnwS4agPJjBBYihT23O6Ngqe0wKdHW+s3GbYZyfdWqd00q853/ ocKVyjW4TyoEd+UmD5gjqVhR5vEJEEjt7sbits2Ao9HSP3i196Xx9VZYYg8+CZ9U0FwC NVDg== 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=b/lQQhK8bSffDw3/2icwtSxNT2UhUhNVLirkuVtqw5E=; b=eAwAoWQ2TftZ9FPdqMmWpmQ+kpXwGiEqnLUqTuwpKxP9HL6YCvH5DgXl3YWxt1+Q/g iaM8RhqdIXihCVIBC//F1mb3/QCPlLCR1BY98VKiJrQ50v8IpD3YqZ+N19oJOqaPb4A5 9UZXPcmModCr5NUCWk4jjUjtUPJQQa0EDpzI1gPV2UdNt3GqLKb3Z8kw6z26fYbaDjn0 vzOvgUbqqRS1puJuI5aifwM95XP8Cy2XydwySj6O956AkSqBnIrNK7Xt20cXoBZLdLJw VLeY4lDa/kkYKQEbc+NGQarZLAdi5nIFOUnGB+Sj6IoeSRuPup7iLN1tp+tKHiOdssjl weUw== X-Gm-Message-State: AOAM532SGiRzrA9UT8VGMS7c2QaYFzE+YGYZYcPas1jeaoWPMVljIqmM +vQct+PoIW1txZh5519BubwOG11l7uo= X-Google-Smtp-Source: ABdhPJwXbvFMQ1BgjTbN1E940cD6r/O14CMw94FZQOd1D0/D2ZCtcuxtNZp03cTXyMvggA+ca+FuTQ== X-Received: by 2002:adf:b74d:: with SMTP id n13mr2393191wre.101.1608270690707; Thu, 17 Dec 2020 21:51:30 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i4sm13242181wri.88.2020.12.17.21.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:30 -0800 (PST) Message-Id: <46953226ba86fa159180262adb068b3218c74a9b.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:19 +0000 Subject: [PATCH 02/10] merge-ort: handle directory/file conflicts that remain Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren When a directory/file conflict remains, we can leave the directory where it is, but need to move the information about the file to a different pathname. After moving the file to a different pathname, we allow subsequent process_entry() logic to handle any additional details that might be relevant. This depends on a new helper function, unique_path(), that dies with an unimplemented error currently but will be implemented in a subsequent commit. Signed-off-by: Elijah Newren --- merge-ort.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index f9a79eb25e6..d300a02810e 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -343,6 +343,13 @@ static void path_msg(struct merge_options *opt, strbuf_addch(sb, '\n'); } +static char *unique_path(struct strmap *existing_paths, + const char *path, + const char *branch) +{ + die("Not yet implemented."); +} + /*** Function Grouping: functions related to collect_merge_info() ***/ static void setup_path_info(struct merge_options *opt, @@ -962,6 +969,8 @@ static void process_entry(struct merge_options *opt, struct conflict_info *ci, struct directory_versions *dir_metadata) { + int df_file_index = 0; + VERIFY_CI(ci); assert(ci->filemask >= 0 && ci->filemask <= 7); /* ci->match_mask == 7 was handled in collect_merge_info_callback() */ @@ -998,7 +1007,80 @@ static void process_entry(struct merge_options *opt, oidcpy(&ci->stages[i].oid, &null_oid); } } else if (ci->df_conflict && ci->merged.result.mode != 0) { - die("Not yet implemented."); + /* + * This started out as a D/F conflict, and the entries in + * the competing directory were not removed by the merge as + * evidenced by write_completed_directory() writing a value + * to ci->merged.result.mode. + */ + struct conflict_info *new_ci; + const char *branch; + const char *old_path = path; + int i; + + assert(ci->merged.result.mode == S_IFDIR); + + /* + * If filemask is 1, we can just ignore the file as having + * been deleted on both sides. We do not want to overwrite + * ci->merged.result, since it stores the tree for all the + * files under it. + */ + if (ci->filemask == 1) { + ci->filemask = 0; + return; + } + + /* + * This file still exists on at least one side, and we want + * the directory to remain here, so we need to move this + * path to some new location. + */ + new_ci = xcalloc(1, sizeof(*new_ci)); + /* We don't really want new_ci->merged.result copied, but it'll + * be overwritten below so it doesn't matter. We also don't + * want any directory mode/oid values copied, but we'll zero + * those out immediately. We do want the rest of ci copied. + */ + memcpy(new_ci, ci, sizeof(*ci)); + new_ci->match_mask = (new_ci->match_mask & ~new_ci->dirmask); + new_ci->dirmask = 0; + for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) { + if (new_ci->filemask & (1 << i)) + continue; + /* zero out any entries related to directories */ + new_ci->stages[i].mode = 0; + oidcpy(&new_ci->stages[i].oid, &null_oid); + } + + /* + * Find out which side this file came from; note that we + * cannot just use ci->filemask, because renames could cause + * the filemask to go back to 7. So we use dirmask, then + * pick the opposite side's index. + */ + df_file_index = (ci->dirmask & (1 << 1)) ? 2 : 1; + branch = (df_file_index == 1) ? opt->branch1 : opt->branch2; + path = unique_path(&opt->priv->paths, path, branch); + strmap_put(&opt->priv->paths, path, new_ci); + + path_msg(opt, path, 0, + _("CONFLICT (file/directory): directory in the way " + "of %s from %s; moving it to %s instead."), + old_path, branch, path); + + /* + * Zero out the filemask for the old ci. At this point, ci + * was just an entry for a directory, so we don't need to + * do anything more with it. + */ + ci->filemask = 0; + + /* + * Now note that we're working on the new entry (path was + * updated above. + */ + ci = new_ci; } /* From patchwork Fri Dec 18 05:51:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981171 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 F17E6C4361B for ; Fri, 18 Dec 2020 05:52:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A036C23A57 for ; Fri, 18 Dec 2020 05:52:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730483AbgLRFwN (ORCPT ); Fri, 18 Dec 2020 00:52:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726045AbgLRFwN (ORCPT ); Fri, 18 Dec 2020 00:52:13 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4CD6C06138C for ; Thu, 17 Dec 2020 21:51:32 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id x22so1082581wmc.5 for ; Thu, 17 Dec 2020 21:51:32 -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=wbFxwuR0mJ88lBfOYEZRwFLji0FcvED1IaVK6/E3Gjs=; b=q91GU3KtVtIsPBrszLW9l8P6DmjNXlVZbYe7ydGyhiEDANrhs2IuSvjGUiAzH4sYoi kgYm5FiHxWl7xw2TQeqnkkWAFqT/pstt8ePIDSXr4vQ0VKH5cyHPr1kNzYGecicE6UUe AboZF5ZxET9WLMpMxusInrhHtY9S6A9idj6PoN2L7cZjjqIYmySkxsFXCJ/Yo0GVx4sg BE14opsjC6SsVgAOjLC0291vcc+AdOPqFJdUJGNgVx4ThrmCMlLRb3ADMgn4jGAPVILO 31lkCFEUY3b+b5C9+ZkyBvBy6JoW9ySaawYxB95f/D9PTpi0ZGTM7J1nmXJX0Krw/bIf ffAQ== 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=wbFxwuR0mJ88lBfOYEZRwFLji0FcvED1IaVK6/E3Gjs=; b=ueqtbNYKWDfQ0zE+PGGVWogvJNVMb2yTQYPB7sP4GjFt7QWzS1A1/0tOkYZmEe1I4+ 17rgt592PXA+XxyBOG80S5jGNNZ3j8WWlkvpTuQJMecP/Y5ckkDtNGaA36UGRK6wytcU JjYw9PZfyyPjB6MjgtMpCI/SRqjjl0Gz8L1jX5BVShhOx27OTIqmfVpoxjYUIJQkDfK7 cnar6HBWu9itW9fbtkYC/82R1K6bNVv9ZNX42PtxdFlKIdu8FdN84I700GWkcTFwbv1w ACFpfmiU+rEgG7zJxZ4WEXGq+VACE6QmsV1/CiNmAX8DPRx7OcwgfRz+IzY1Ca/j/cyc OC/g== X-Gm-Message-State: AOAM530DthfrPtvTniEvn7JSfhLsskIvgucHxA9q19jMnUPvNT8p9L7W FZnZM/GFAblWqqykqC32JrNbSrRXhmI= X-Google-Smtp-Source: ABdhPJzv/yQ6V+e8gtL2B9AApg9hlcbq7o7Rp8XadxZyqRkp1WuSVXqupaGD+tgPJ9+uj+oAcLCwZQ== X-Received: by 2002:a7b:c205:: with SMTP id x5mr2555370wmi.115.1608270691547; Thu, 17 Dec 2020 21:51:31 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q15sm10916759wrw.75.2020.12.17.21.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:31 -0800 (PST) Message-Id: <6ac555b3c0fe605fbbe6e304482c2e3aef321865.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:20 +0000 Subject: [PATCH 03/10] merge-ort: implement unique_path() helper Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Implement unique_path(), based on the one from merge-recursive.c. It is simplified, however, due to: (1) using strmaps, and (2) the fact that merge-ort lets the checkout codepath handle possible collisions with the working tree means that other code locations don't have to. Signed-off-by: Elijah Newren --- merge-ort.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index d300a02810e..1adc27a11bc 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -343,11 +343,34 @@ static void path_msg(struct merge_options *opt, strbuf_addch(sb, '\n'); } +/* add a string to a strbuf, but converting "/" to "_" */ +static void add_flattened_path(struct strbuf *out, const char *s) +{ + size_t i = out->len; + strbuf_addstr(out, s); + for (; i < out->len; i++) + if (out->buf[i] == '/') + out->buf[i] = '_'; +} + static char *unique_path(struct strmap *existing_paths, const char *path, const char *branch) { - die("Not yet implemented."); + struct strbuf newpath = STRBUF_INIT; + int suffix = 0; + size_t base_len; + + strbuf_addf(&newpath, "%s~", path); + add_flattened_path(&newpath, branch); + + base_len = newpath.len; + while (strmap_contains(existing_paths, newpath.buf)) { + strbuf_setlen(&newpath, base_len); + strbuf_addf(&newpath, "_%d", suffix++); + } + + return strbuf_detach(&newpath, NULL); } /*** Function Grouping: functions related to collect_merge_info() ***/ From patchwork Fri Dec 18 05:51:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981173 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 98397C2BBD5 for ; Fri, 18 Dec 2020 05:52:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 622ED2313B for ; Fri, 18 Dec 2020 05:52:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732081AbgLRFwP (ORCPT ); Fri, 18 Dec 2020 00:52:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730768AbgLRFwO (ORCPT ); Fri, 18 Dec 2020 00:52:14 -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 02138C061285 for ; Thu, 17 Dec 2020 21:51:33 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id 3so1214263wmg.4 for ; Thu, 17 Dec 2020 21:51:33 -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=uQj1KnZFNkvgzNoX7zgcyb8j09rgmx4sS6HQzs7Ndu0=; b=IZvZq1IbKmXg2/V+pM176Xg/zsluwt0hLuPn/+KOSAx8rISLiBOA5AOj0U9OMF3+Xv D3/UZsoXr8RAfAto2oxUF1P3rfMAvrX0pKOZlQGTbWAR+8YO1ttUolD8QkqLfAisE29u apxRhjoeqVGWyZSCXN9P0uulpuCGdfovxCmBnCQ2Xc1V1cEgiRtY0jYT2ad7K/DaO8uI vrxSrQ+PpPRF24hbkXPWf1qqSNgnOC52RtSmPmaDz9XiqcZBJr/jC6V1w0N5xQRJs67m 8pAsgNID3+b9Iwb6L7OIukrUjc7snkoVm6ycR+M3k7VcuTefs2vYTWgAm2OjnPp1bH9E b/Jg== 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=uQj1KnZFNkvgzNoX7zgcyb8j09rgmx4sS6HQzs7Ndu0=; b=Ms22QN1WowJGh/a0fOmQsmHB7Rf+xp1sZYqA6Z7qUVP/F68WEWOeOkC3qKh3vBWMRy znANt8VSWI430cjnDtLF4YSjl1gIC04rLFTW8OZwMscbFrCjgj+eGAz1bufROhg0HNK9 Ct5sEWv0NkD/mo6RouOLKnqDPzCHfMeEMjmPrdPynqSGPvXHcZriId9G43aN9CspD+wT N9l3zuCJCt3F4gvjzKRxZWyrAIs4tkKpTfiMeFORnHZ33UoZ22gQ7vuGptdKehSzW19P eqRsx9sMnXXoBuvm0cOA/0Ku8antg3JsWsXDBqYJlwbMf5zf9NjfnanhfxPucyoMvoRA KHMQ== X-Gm-Message-State: AOAM5305s4SNPqDDJgFXUBJIJBOlx0TsZArOZOJ4FWK/eczrI4r5ZuHo FbX5DPDtI6cEUlgfqThhJ7vlgeSoh7Y= X-Google-Smtp-Source: ABdhPJzOObgwFLGMlzCgS1I6UK/Nv2lIVPDY79puC/iG2N9Kr63PWAoi6aBJCLksJXqExbu6rmrFCw== X-Received: by 2002:a1c:2d47:: with SMTP id t68mr2573840wmt.148.1608270692433; Thu, 17 Dec 2020 21:51:32 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p8sm7124152wru.50.2020.12.17.21.51.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:31 -0800 (PST) Message-Id: <4c641ec19d578a4014b4d3b568d18606a164ae9a.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:21 +0000 Subject: [PATCH 04/10] merge-ort: handle book-keeping around two- and three-way content merge Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren In addition to the content merge (which will go in a subsequent commit), we need to worry about conflict messages, placing results in higher order stages in case of a df_conflict, and making sure the results are placed in ci->merged.result so that they will show up in the working tree. Take care of all that external book-keeping, moving the simplistic just-take-HEAD code into the barebones handle_content_merge() function for now. Subsequent commits will flesh out handle_content_merge(). Signed-off-by: Elijah Newren --- merge-ort.c | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 1adc27a11bc..47e230fe341 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -640,7 +640,15 @@ static int handle_content_merge(struct merge_options *opt, const int extra_marker_size, struct version_info *result) { - die("Not yet implemented"); + int clean = 0; + /* + * TODO: Needs a two-way or three-way content merge, but we're + * just being lazy and copying the version from HEAD and + * leaving it as conflicted. + */ + result->mode = a->mode; + oidcpy(&result->oid, &a->oid); + return clean; } /*** Function Grouping: functions related to detect_and_process_renames(), *** @@ -1138,16 +1146,38 @@ static void process_entry(struct merge_options *opt, */ die("Not yet implemented."); } else if (ci->filemask >= 6) { - /* - * TODO: Needs a two-way or three-way content merge, but we're - * just being lazy and copying the version from HEAD and - * leaving it as conflicted. - */ - ci->merged.clean = 0; - ci->merged.result.mode = ci->stages[1].mode; - oidcpy(&ci->merged.result.oid, &ci->stages[1].oid); - /* When we fix above, we'll call handle_content_merge() */ - (void)handle_content_merge; + /* Need a two-way or three-way content merge */ + struct version_info merged_file; + unsigned clean_merge; + struct version_info *o = &ci->stages[0]; + struct version_info *a = &ci->stages[1]; + struct version_info *b = &ci->stages[2]; + + clean_merge = handle_content_merge(opt, path, o, a, b, + ci->pathnames, + opt->priv->call_depth * 2, + &merged_file); + ci->merged.clean = clean_merge && + !ci->df_conflict && !ci->path_conflict; + ci->merged.result.mode = merged_file.mode; + ci->merged.is_null = (merged_file.mode == 0); + oidcpy(&ci->merged.result.oid, &merged_file.oid); + if (clean_merge && ci->df_conflict) { + assert(df_file_index == 1 || df_file_index == 2); + ci->filemask = 1 << df_file_index; + ci->stages[df_file_index].mode = merged_file.mode; + oidcpy(&ci->stages[df_file_index].oid, &merged_file.oid); + } + if (!clean_merge) { + const char *reason = _("content"); + if (ci->filemask == 6) + reason = _("add/add"); + if (S_ISGITLINK(merged_file.mode)) + reason = _("submodule"); + path_msg(opt, path, 0, + _("CONFLICT (%s): Merge conflict in %s"), + reason, path); + } } else if (ci->filemask == 3 || ci->filemask == 5) { /* Modify/delete */ const char *modify_branch, *delete_branch; From patchwork Fri Dec 18 05:51:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981177 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 EC053C4361B for ; Fri, 18 Dec 2020 05:52:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C70D23A57 for ; Fri, 18 Dec 2020 05:52:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732146AbgLRFww (ORCPT ); Fri, 18 Dec 2020 00:52:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725290AbgLRFwv (ORCPT ); Fri, 18 Dec 2020 00:52:51 -0500 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4AF82C061248 for ; Thu, 17 Dec 2020 21:51:35 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id r3so824044wrt.2 for ; Thu, 17 Dec 2020 21:51:35 -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=5nRPYtOpZEu778+nvTAeqzOIXuhD9jlfLfk7n+GwGJM=; b=b3WVzoHoGXcO8tex62ZawtOx0tAiaBodJKk4jRC1dr1xpDxcYiai3BJGIyc/g7zaAy usTsy00Bb5/KAmtyRQPDLXll6Hj2y9PByxT3HKlRVUfPRkKWTJRm4bodYhSYiOshx2QG naV2nkUiW0amIPHNqS8ORUfLPgakLcKiHr+coplLuHGqk9ZJS2TQSpdwPzX+t3Gqj3qU zh8o+tl1mquqqPEI0+PEARgYybqQci/Wao5qwFsQivTg6+oEGCOseRhsHx85SLwx43qJ CkaWvWVPPpYQ9G8PI2Oi25UfpB4qozSCkwLC3wfPFNgdiN5MIAxLotNBs2MA0icUO7q8 AHAA== 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=5nRPYtOpZEu778+nvTAeqzOIXuhD9jlfLfk7n+GwGJM=; b=WQCUrVUJOfi8FNGompVAzIraA+zMq4JePWZI0tmDTkmwPeCyI4i94XLW7yEda1vsIU jqcv2zJLf38w+M0eH+Ump4gvJ1n8OSsMyXVH3CirMl2GQ/J2p5ZH0fWMFJ8LQNT7grpH riIn048WyR7L2IX+IY0jweNnqhXrbDqCGkXEnazjiD4FHoz0mPycaHhYT26i9L16a/zv ZYHROx6KlhdYXFjwZdmIrNPRTKZBqG60IZjtEcgO3y2TaxzQlwKqaaW463BKfQNRssmo HisQt/IwktdQHUNUJA/e++V2cNmVxIdkxyZa3X5QIB0JRg361WuTtGjYQVMuCLOp82MF VGiA== X-Gm-Message-State: AOAM53102nc4frxxDbcpIzy2MS8cAdW/BM5fd2tEhGppO+VcmN6UYo8B 1BqX+xcB4PGOYSAoeeZ2G6PVx+oRKlY= X-Google-Smtp-Source: ABdhPJytog6dhhC+U05IaQRCvqcBWgcBGqeYCiB+6E/2FY6H1aJMrrn6dAaXW2bpkUc2pa1JWoU7Jw== X-Received: by 2002:adf:f344:: with SMTP id e4mr2370161wrp.25.1608270693372; Thu, 17 Dec 2020 21:51:33 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id m18sm12060604wrw.43.2020.12.17.21.51.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:32 -0800 (PST) Message-Id: <0e7321e67f83c197e84ad7b281ab2ce79c90b784.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:22 +0000 Subject: [PATCH 05/10] merge-ort: flesh out implementation of handle_content_merge() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This implementation is based heavily on merge_mode_and_contents() from merge-recursive.c, though it has some fixes for recursive merges (i.e. when call_depth > 0), and has a number of changes throughout based on slight differences in data structures and in how the functions are called. It is, however, based on two new helper functions -- merge_3way() and merge_submodule -- for which we only provide die-not-implemented stubs at this point. Future commits will add implementations of these functions. Signed-off-by: Elijah Newren --- merge-ort.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 6 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 47e230fe341..2cfb7ffa3b0 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -631,6 +631,28 @@ static int collect_merge_info(struct merge_options *opt, /*** Function Grouping: functions related to threeway content merges ***/ +static int merge_submodule(struct merge_options *opt, + const char *path, + const struct object_id *o, + const struct object_id *a, + const struct object_id *b, + struct object_id *result) +{ + die("Not yet implemented."); +} + +static int merge_3way(struct merge_options *opt, + const char *path, + const struct object_id *o, + const struct object_id *a, + const struct object_id *b, + const char *pathnames[3], + const int extra_marker_size, + mmbuffer_t *result_buf) +{ + die("Not yet implemented."); +} + static int handle_content_merge(struct merge_options *opt, const char *path, const struct version_info *o, @@ -640,14 +662,129 @@ static int handle_content_merge(struct merge_options *opt, const int extra_marker_size, struct version_info *result) { - int clean = 0; /* - * TODO: Needs a two-way or three-way content merge, but we're - * just being lazy and copying the version from HEAD and - * leaving it as conflicted. + * path is the target location where we want to put the file, and + * is used to determine any normalization rules in ll_merge. + * + * The normal case is that path and all entries in pathnames are + * identical, though renames can affect which path we got one of + * the three blobs to merge on various sides of history. + * + * extra_marker_size is the amount to extend conflict markers in + * ll_merge; this is neeed if we have content merges of content + * merges, which happens for example with rename/rename(2to1) and + * rename/add conflicts. */ - result->mode = a->mode; - oidcpy(&result->oid, &a->oid); + unsigned clean = 1; + + /* + * handle_content_merge() needs both files to be of the same type, i.e. + * both files OR both submodules OR both symlinks. Conflicting types + * needs to be handled elsewhere. + */ + assert((S_IFMT & a->mode) == (S_IFMT & b->mode)); + + /* Merge modes */ + if (a->mode == b->mode || a->mode == o->mode) + result->mode = b->mode; + else { + /* must be the 100644/100755 case */ + assert(S_ISREG(a->mode)); + result->mode = a->mode; + clean = (b->mode == o->mode); + /* + * FIXME: If opt->priv->call_depth && !clean, then we really + * should not make result->mode match either a->mode or + * b->mode; that causes t6036 "check conflicting mode for + * regular file" to fail. It would be best to use some other + * mode, but we'll confuse all kinds of stuff if we use one + * where S_ISREG(result->mode) isn't true, and if we use + * something like 0100666, then tree-walk.c's calls to + * canon_mode() will just normalize that to 100644 for us and + * thus not solve anything. + * + * Figure out if there's some kind of way we can work around + * this... + */ + } + + /* + * Trivial oid merge. + * + * Note: While one might assume that the next four lines would + * be unnecessary due to the fact that match_mask is often + * setup and already handled, renames don't always take care + * of that. + */ + if (oideq(&a->oid, &b->oid) || oideq(&a->oid, &o->oid)) + oidcpy(&result->oid, &b->oid); + else if (oideq(&b->oid, &o->oid)) + oidcpy(&result->oid, &a->oid); + + /* Remaining rules depend on file vs. submodule vs. symlink. */ + else if (S_ISREG(a->mode)) { + mmbuffer_t result_buf; + int ret = 0, merge_status; + int two_way; + + /* + * If 'o' is different type, treat it as null so we do a + * two-way merge. + */ + two_way = ((S_IFMT & o->mode) != (S_IFMT & a->mode)); + + merge_status = merge_3way(opt, path, + two_way ? &null_oid : &o->oid, + &a->oid, &b->oid, + pathnames, extra_marker_size, + &result_buf); + + if ((merge_status < 0) || !result_buf.ptr) + 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(opt, _("Unable to add %s to database"), + path); + + free(result_buf.ptr); + if (ret) + return -1; + clean &= (merge_status == 0); + path_msg(opt, path, 1, _("Auto-merging %s"), path); + } else if (S_ISGITLINK(a->mode)) { + int two_way = ((S_IFMT & o->mode) != (S_IFMT & a->mode)); + clean = merge_submodule(opt, pathnames[0], + two_way ? &null_oid : &o->oid, + &a->oid, &b->oid, &result->oid); + if (opt->priv->call_depth && two_way && !clean) { + result->mode = o->mode; + oidcpy(&result->oid, &o->oid); + } + } else if (S_ISLNK(a->mode)) { + if (opt->priv->call_depth) { + clean = 0; + result->mode = o->mode; + oidcpy(&result->oid, &o->oid); + } else { + switch (opt->recursive_variant) { + case MERGE_VARIANT_NORMAL: + clean = 0; + oidcpy(&result->oid, &a->oid); + break; + case MERGE_VARIANT_OURS: + oidcpy(&result->oid, &a->oid); + break; + case MERGE_VARIANT_THEIRS: + oidcpy(&result->oid, &b->oid); + break; + } + } + } else + BUG("unsupported object type in the tree: %06o for %s", + a->mode, path); + return clean; } From patchwork Fri Dec 18 05:51:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981187 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 E97CBC4361B for ; Fri, 18 Dec 2020 05:53:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9529523A5B for ; Fri, 18 Dec 2020 05:53:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730768AbgLRFwv (ORCPT ); Fri, 18 Dec 2020 00:52:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbgLRFwv (ORCPT ); Fri, 18 Dec 2020 00:52:51 -0500 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3843C061257 for ; Thu, 17 Dec 2020 21:51:35 -0800 (PST) Received: by mail-wm1-x32d.google.com with SMTP id 3so1214329wmg.4 for ; Thu, 17 Dec 2020 21:51:35 -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=qAYm3lIoZOWgkgmupGAToxGB30CYGq9eTWjDA19TrNY=; b=rH5d5M+NNqNGXqerywm2SA8NZ0nMOgy8gduh9GpeER6AFy3VaePmSiBg5hi5IGHCit J0uD8IIYgWTgQqAk+f7ia7bcxwBP1qAOa9IaT7b2cThvNulcBqQ+qc8jtSbPVz3D2IyP rXCvoapPP4cRfs5FvieXBBbiFGC4rDeq6fsIjNyHctSVCqZqsSj+6+j350LR7MaPZ9gV P4p+6MV3l+2BCmZ4KNnIMAy2NYdQ4NWWInPWEAqM9gBE9gf+WOg5i5UAsMe7Nyn0btVU d6rZUGMCh6QXn6d52lOv9lHrgC2ad4sGEoRUH+lRVdM7wYKjEyuzwWZ4Kz3ZQo5Rb27X HMGA== 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=qAYm3lIoZOWgkgmupGAToxGB30CYGq9eTWjDA19TrNY=; b=htMsihpBlVdxwzeFvHT8g8Q8O7L7BHsOQPAd1TIcgQ1TATCBLENeTc+aErvdTg+vn/ DbQ18HD4PgoppOgNYP739O472hzkVft0XqM+6Ut8Fe9pc81S4XrP9fD33sn9CMO3xb9T bOefuoQQasnwITXE8RVNTjLfikV32ycu1KAxy2anPc8CLvnSo8736JS0YZxf9dB5b/YR lpwh2dHg/5HRUr2R/Svi/HuW1W0C7SeRPHAYso8RCsysg9KFpX+YhdLQ3lZHMIegAzV3 KVVFj3JheH1thgIsQdAzOdeyqVXY58qemCso8d4QKKPBVOTXs2QEjQvJKDAOpJcOVwcl Jekw== X-Gm-Message-State: AOAM531MN8J/UAGIYbyUIxU+FN/yRPFO0RlVeQ8diUpiIxzOQXvJuI5J nHGn11RreJfoaGmqbECD7Cq36eJSuLQ= X-Google-Smtp-Source: ABdhPJxS0uC1dOQlJorXKDsVinZz6qRykj9Aype6ymzQPNhHgbNdKYYNF2451r0anw9zsSZAquhslA== X-Received: by 2002:a7b:c04c:: with SMTP id u12mr2545149wmc.185.1608270694262; Thu, 17 Dec 2020 21:51:34 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id y7sm10849849wmb.37.2020.12.17.21.51.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:33 -0800 (PST) Message-Id: <611141f24af2c8d706fbf2dc6ef776ca61391e41.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:23 +0000 Subject: [PATCH 06/10] merge-ort: copy and adapt merge_3way() from merge-recursive.c Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Take merge_3way() from merge-recursive.c and make slight adjustments based on different data structures (direct usage of object_id rather diff_filespec, separate pathnames which based on our careful interning of pathnames in opt->priv->paths can be compared with '!=' rather than 'strcmp'). Signed-off-by: Elijah Newren --- merge-ort.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index 2cfb7ffa3b0..a59adb42aa6 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -23,6 +23,7 @@ #include "diff.h" #include "diffcore.h" #include "dir.h" +#include "ll-merge.h" #include "object-store.h" #include "strmap.h" #include "tree.h" @@ -650,7 +651,58 @@ static int merge_3way(struct merge_options *opt, const int extra_marker_size, mmbuffer_t *result_buf) { - die("Not yet implemented."); + mmfile_t orig, src1, src2; + struct ll_merge_options ll_opts = {0}; + char *base, *name1, *name2; + int merge_status; + + ll_opts.renormalize = opt->renormalize; + ll_opts.extra_marker_size = extra_marker_size; + ll_opts.xdl_opts = opt->xdl_opts; + + if (opt->priv->call_depth) { + ll_opts.virtual_ancestor = 1; + ll_opts.variant = 0; + } else { + switch (opt->recursive_variant) { + case MERGE_VARIANT_OURS: + ll_opts.variant = XDL_MERGE_FAVOR_OURS; + break; + case MERGE_VARIANT_THEIRS: + ll_opts.variant = XDL_MERGE_FAVOR_THEIRS; + break; + default: + ll_opts.variant = 0; + break; + } + } + + assert(pathnames[0] && pathnames[1] && pathnames[2] && opt->ancestor); + if (pathnames[0] == pathnames[1] && pathnames[1] == pathnames[2]) { + base = mkpathdup("%s", opt->ancestor); + name1 = mkpathdup("%s", opt->branch1); + name2 = mkpathdup("%s", opt->branch2); + } else { + base = mkpathdup("%s:%s", opt->ancestor, pathnames[0]); + name1 = mkpathdup("%s:%s", opt->branch1, pathnames[1]); + name2 = mkpathdup("%s:%s", opt->branch2, pathnames[2]); + } + + read_mmblob(&orig, o); + read_mmblob(&src1, a); + read_mmblob(&src2, b); + + merge_status = ll_merge(result_buf, path, &orig, base, + &src1, name1, &src2, name2, + opt->repo->index, &ll_opts); + + free(base); + free(name1); + free(name2); + free(orig.ptr); + free(src1.ptr); + free(src2.ptr); + return merge_status; } static int handle_content_merge(struct merge_options *opt, From patchwork Fri Dec 18 05:51:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981179 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 6A4F7C2BBCF for ; Fri, 18 Dec 2020 05:52:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 203522313B for ; Fri, 18 Dec 2020 05:52:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732306AbgLRFwx (ORCPT ); Fri, 18 Dec 2020 00:52:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbgLRFww (ORCPT ); Fri, 18 Dec 2020 00:52:52 -0500 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0FECC0611C5 for ; Thu, 17 Dec 2020 21:51:36 -0800 (PST) Received: by mail-wr1-x42f.google.com with SMTP id c5so806727wrp.6 for ; Thu, 17 Dec 2020 21:51:36 -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=VUY37MnFlwBe6Um2ozB7acPDc0llZSH/yK3nPGAp9yw=; b=jsToQkWuL8J/jA8+wCE82UiA62aFhhNcHTaE5aEgdZmOSEZQI09mkAu1l/kkYsN9pW OJKoh5lo6jhbaxZ+66I1KzBSjWscHLBC71dfMkXhYxSHzALB/qTfQiC4RILB3nICG8ZV ALHE27rByvSak1vA4sSypdzJbWEL3BNwviJKUNEIyuWulbY95ePLMSSsEk2kt85ZeHiH xqLirp4HVT78YBr9eIg5L37XkyE4aKvn0JcKWT6oLcrhfTeWg6eEH7gpuULoG/YUAE+L upfYVgOxIR4ulf0hX+OPLiQATjI/E7DnuVEoLyM5AEz+/LiMBwgfStbeipcg4XL8f6bA 07Uw== 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=VUY37MnFlwBe6Um2ozB7acPDc0llZSH/yK3nPGAp9yw=; b=JVeKBML0U8h0aMJkaHlyIz+5+IqYuWG3A9zNSxDoly5bFQ5MDyERwhXuoRqrG9gXXC PIwBm9Zon128VyGusUSo4Oamu3R2zzPbZPM8oQMNZgzRPEz0luQrJnIL7mdMrLoHOjUJ FVXE2W0PJtMcBG0v80IeQrT0aMvWMO+InUqt1gRMlShDTBIhlbQmYsu7Tf57Ub5mUOzz uQjLO8PS9558tLGybAlqhmRjHURvtNnSb5iNMGRS6WtDIzTmndzbiwd4/jjdS1268dBo 1jK+fKIzDozMn01gsN5m0DcHXIBIKhJqpbxtDsS+JTuv7tYBUTmutkiNzpES9VzBG7mY Izow== X-Gm-Message-State: AOAM533TsR3UuFryQsmuPoLUTrUlAyetqG18yqayBgNUyVc6DjXTG6Sd LrzGo7dCVjB7goaemQYU4ptZtX8dWrE= X-Google-Smtp-Source: ABdhPJzq47HG17XwkflvCHjcLS7HZI+pM1x+GhxkHnbbYjYQkw/Ya/B0ZhOcHqkse8maFgKWLunB2A== X-Received: by 2002:adf:ded1:: with SMTP id i17mr2371841wrn.190.1608270695213; Thu, 17 Dec 2020 21:51:35 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id v20sm10337315wml.34.2020.12.17.21.51.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:34 -0800 (PST) Message-Id: <4696f6c2d95e5080486cf6775ed0fccee59f150e.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:24 +0000 Subject: [PATCH 07/10] merge-ort: copy and adapt merge_submodule() from merge-recursive.c Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Take merge_submodule() from merge-recursive.c and make slight adjustments, predominantly around deferring output using path_msg() instead of using merge-recursive's output() and show() functions. There's also a fix for recursive cases (when call_depth > 0) and a slight change to argument order for find_first_merges(). find_first_merges() and format_commit() are left unimplemented for now, but will be added by subsequent commits. Signed-off-by: Elijah Newren --- merge-ort.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index a59adb42aa6..2dfab1858fc 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -26,6 +26,7 @@ #include "ll-merge.h" #include "object-store.h" #include "strmap.h" +#include "submodule.h" #include "tree.h" #include "unpack-trees.h" #include "xdiff-interface.h" @@ -323,6 +324,13 @@ static int err(struct merge_options *opt, const char *err, ...) return -1; } +static void format_commit(struct strbuf *sb, + int indent, + struct commit *commit) +{ + die("Not yet implemented."); +} + __attribute__((format (printf, 4, 5))) static void path_msg(struct merge_options *opt, const char *path, @@ -632,6 +640,15 @@ static int collect_merge_info(struct merge_options *opt, /*** Function Grouping: functions related to threeway content merges ***/ +static int find_first_merges(struct repository *repo, + const char *path, + struct commit *a, + struct commit *b, + struct object_array *result) +{ + die("Not yet implemented."); +} + static int merge_submodule(struct merge_options *opt, const char *path, const struct object_id *o, @@ -639,7 +656,114 @@ static int merge_submodule(struct merge_options *opt, const struct object_id *b, struct object_id *result) { - die("Not yet implemented."); + struct commit *commit_o, *commit_a, *commit_b; + int parent_count; + struct object_array merges; + struct strbuf sb = STRBUF_INIT; + + int i; + int search = !opt->priv->call_depth; + + /* store fallback answer in result in case we fail */ + oidcpy(result, opt->priv->call_depth ? o : a); + + /* we can not handle deletion conflicts */ + if (is_null_oid(o)) + return 0; + if (is_null_oid(a)) + return 0; + if (is_null_oid(b)) + return 0; + + if (add_submodule_odb(path)) { + path_msg(opt, path, 0, + _("Failed to merge submodule %s (not checked out)"), + path); + return 0; + } + + if (!(commit_o = lookup_commit_reference(opt->repo, o)) || + !(commit_a = lookup_commit_reference(opt->repo, a)) || + !(commit_b = lookup_commit_reference(opt->repo, b))) { + path_msg(opt, path, 0, + _("Failed to merge submodule %s (commits not present)"), + path); + return 0; + } + + /* check whether both changes are forward */ + if (!in_merge_bases(commit_o, commit_a) || + !in_merge_bases(commit_o, commit_b)) { + path_msg(opt, path, 0, + _("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); + path_msg(opt, path, 1, + _("Note: Fast-forwarding submodule %s to %s"), + path, oid_to_hex(b)); + return 1; + } + if (in_merge_bases(commit_b, commit_a)) { + oidcpy(result, a); + path_msg(opt, path, 1, + _("Note: Fast-forwarding submodule %s to %s"), + path, oid_to_hex(a)); + return 1; + } + + /* + * Case #2: There are one or more merges that contain a and b in + * the submodule. If there is only one, then present it as a + * suggestion to the user, but leave it marked unmerged so the + * user needs to confirm the resolution. + */ + + /* Skip the search if makes no sense to the calling context. */ + if (!search) + return 0; + + /* find commit which merges them */ + parent_count = find_first_merges(opt->repo, path, commit_a, commit_b, + &merges); + switch (parent_count) { + case 0: + path_msg(opt, path, 0, _("Failed to merge submodule %s"), path); + break; + + case 1: + format_commit(&sb, 4, + (struct commit *)merges.objects[0].item); + path_msg(opt, path, 0, + _("Failed to merge submodule %s, but a possible merge " + "resolution exists:\n%s\n"), + path, sb.buf); + path_msg(opt, path, 1, + _("If this is correct simply add it to the index " + "for example\n" + "by using:\n\n" + " git update-index --cacheinfo 160000 %s \"%s\"\n\n" + "which will accept this suggestion.\n"), + oid_to_hex(&merges.objects[0].item->oid), path); + strbuf_release(&sb); + break; + default: + for (i = 0; i < merges.nr; i++) + format_commit(&sb, 4, + (struct commit *)merges.objects[i].item); + path_msg(opt, path, 0, + _("Failed to merge submodule %s, but multiple " + "possible merges exist:\n%s"), path, sb.buf); + strbuf_release(&sb); + } + + object_array_clear(&merges); + return 0; } static int merge_3way(struct merge_options *opt, From patchwork Fri Dec 18 05:51:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981185 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 22505C2BBD4 for ; Fri, 18 Dec 2020 05:53:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C448F23A63 for ; Fri, 18 Dec 2020 05:53:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732248AbgLRFwx (ORCPT ); Fri, 18 Dec 2020 00:52:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732108AbgLRFww (ORCPT ); Fri, 18 Dec 2020 00:52:52 -0500 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73E8BC0611CA for ; Thu, 17 Dec 2020 21:51:37 -0800 (PST) Received: by mail-wm1-x333.google.com with SMTP id g25so5248090wmh.1 for ; Thu, 17 Dec 2020 21:51:37 -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=L/WVsRYrspMW4RmRifIMouf1b8GyIYjbnvZIWb8/lPo=; b=gMIQhGeUBC8U+ZRbjf4kazJ+Y835lUkJG3aIsEiVKVAI2peqSyC0RSRmJh5tub3YK7 zCDFKIUT0m1pzl4U/u1iAZcr0yzfIbTmpvUSbgEBDjW1sWBqzR8vnicH2++cgL/52vcR toaoQIPJNN7t4ikSR7oXkJmTzjnSt1An+ZA9TUr5mtvVr8syNIxn/nvoW8J+Cvrgl5WK HQq1oFYWxekghGUPIWSkeFckio650R3/3UCPjhMJ2H3puc6ygxmuCX+4hywtK02wscWk OAX4MNQ3HHgSI97RdtZHoWcx+K0a18QAM3O8fD3N7bMO8elHdcwZhZU0erufmQG1D2Q1 k6kw== 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=L/WVsRYrspMW4RmRifIMouf1b8GyIYjbnvZIWb8/lPo=; b=haTCu82+keCOJUy5tN/da1tZtOXHiPANg0/tL+QutqaawlnUP9LMH+QXC/a9FibAB6 A2NXnKyMBNNvNmpSGvNbX8k14WRee0aTcCUclhQa8UX7mW2AFGrdlt5yErNyTzS0mq2T R4F1d6bEiDXOHpmcx0L0IbZeI50JWeyoMx/qw6a/d3q4vgG+Joa/Eze0a95nUKfnrIz+ CpVNMfttIrf2R8vmzy48jAEqkB/3qSBVs3bQQQ8GDMsFldvraOHSuSkpmsPMrTxP8gVh Uvc5LDLaigCY2laIu9eNaIOaDE706Io0QUBwIbAVViCFAeQBr16hxxfLUadSnwQgUeED ecHg== X-Gm-Message-State: AOAM531CctlEEA7pZqgVNM3Wt55akoHnvubuuYfyTJRoHX5XnNgXIDEP hU2EUNJKFx/AVnd8UodOQkb57IP6kIA= X-Google-Smtp-Source: ABdhPJw5gRn8jwyWgil8Ry/K566n7X26XjH7TJCGXhytuSgDIcdebE6/xZ2S3v5USJN8a2WT8LKU/w== X-Received: by 2002:a1c:7f52:: with SMTP id a79mr2427207wmd.157.1608270696098; Thu, 17 Dec 2020 21:51:36 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l16sm12405660wrx.5.2020.12.17.21.51.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:35 -0800 (PST) Message-Id: In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:25 +0000 Subject: [PATCH 08/10] merge-ort: implement format_commit() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This implementation is based on a mixture of print_commit() and output_commit_title() from merge-recursive.c so that it can be used to take over both functions. Signed-off-by: Elijah Newren --- merge-ort.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index 2dfab1858fc..bf704bcd34d 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -328,7 +328,19 @@ static void format_commit(struct strbuf *sb, int indent, struct commit *commit) { - die("Not yet implemented."); + struct merge_remote_desc *desc; + struct pretty_print_context ctx = {0}; + ctx.abbrev = DEFAULT_ABBREV; + + strbuf_addchars(sb, ' ', indent); + desc = merge_remote_util(commit); + if (desc) { + strbuf_addf(sb, "virtual %s\n", desc->name); + return; + } + + format_commit_message(commit, "%h %s", sb, &ctx); + strbuf_addch(sb, '\n'); } __attribute__((format (printf, 4, 5))) From patchwork Fri Dec 18 05:51:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981181 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 4CF8FC2BBD5 for ; Fri, 18 Dec 2020 05:52:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ECACF23A57 for ; Fri, 18 Dec 2020 05:52:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732455AbgLRFwy (ORCPT ); Fri, 18 Dec 2020 00:52:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbgLRFwx (ORCPT ); Fri, 18 Dec 2020 00:52:53 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7165BC0611CB for ; Thu, 17 Dec 2020 21:51:38 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id v14so1102991wml.1 for ; Thu, 17 Dec 2020 21:51:38 -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=3VWdFNzHStrIFPMTrcpUhepqI3KmHCI8z1cXv60VA8M=; b=cJs2SDz4acEqKQvcXKr8YVFKHosoB/NNKU1yKMoJKaQCKVoFVdrZ0Fi7pmtBkAJNqB WKuTiTkUghMpmMz0CqKmXYeSqbZ7ZvOCx+p2lruxa63+Rhm+2wzYPTaNBuDAbBPfn/Fu ugRAHGggvYwjRWVpZNSIoqhzIuMpGGmkCYjvNPITSwGyJMxgX0oRMaVXdUwkzAjOm0H3 aVmVuypmr1UvBeRdXEmOsHKKezKdUlh90wCCIR79InoMfp0x9YM7CKUxpeRNhle2UF10 Ay4ZxSdxpBdFV2ykz/s8bDGO/PJPW7Bxjvqqzw+axp18fsHtKUZ3NT/PGXjuigWUGeiW 3mFg== 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=3VWdFNzHStrIFPMTrcpUhepqI3KmHCI8z1cXv60VA8M=; b=BxjX5gi5Ksg9zrGP31awLdpoFmTgJGynHBnhoYRb9bZfCdIEPMp4byBxRG/inVcSs3 GTHiCIKI2O8Z9dJT61TMi8jm76UVUfGVC/3s+A29gX13Wzsa3XZ1K9PMn5K86a3NVvtL 7Sgt8Sfs6YDAy3r1UiQzaUBbg1LPXQmKBkbhbZNvGjuXE6wqunwqadN/xv3FJAsTSDug 5tCGphng3ajlFJUIbbPkjTagUh48lrBx2Z6B5JJuqkJZe8IHsVEfc5rgLNw8GUhXXj5I lof4T3xFuSX9z6/Ih0LWYnmemtZH5i2tQRmYnPYekU4Z/w1edHAjmccwFPnI/T0PVJHU gm3A== X-Gm-Message-State: AOAM532PDBrmEvlqwDBceBGWMY1eBp7HVsni7evD4MYyNdApVXTzLNmn 3yYKwnZjm7uxwJ9TfAq+9UEK+laUuKs= X-Google-Smtp-Source: ABdhPJzqsoSgCKyWWXR/ppb4fV+ue8zJsvmLPeChaJi77MR0T/mOdZS2nNwxZsjmWjanUVxvybqoeQ== X-Received: by 2002:a7b:c7d8:: with SMTP id z24mr2512962wmk.1.1608270696975; Thu, 17 Dec 2020 21:51:36 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id b12sm17427652wmj.2.2020.12.17.21.51.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:36 -0800 (PST) Message-Id: In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:26 +0000 Subject: [PATCH 09/10] merge-ort: copy find_first_merges() implementation from merge-recursive.c Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Code is identical for the function body in the two files, the call signature is just slightly different in merge-ort than merge-recursive as noted a couple commits ago. Signed-off-by: Elijah Newren --- merge-ort.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/merge-ort.c b/merge-ort.c index bf704bcd34d..203fa987e43 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -25,6 +25,7 @@ #include "dir.h" #include "ll-merge.h" #include "object-store.h" +#include "revision.h" #include "strmap.h" #include "submodule.h" #include "tree.h" @@ -658,7 +659,61 @@ static int find_first_merges(struct repository *repo, struct commit *b, struct object_array *result) { - die("Not yet implemented."); + int i, j; + struct object_array merges = OBJECT_ARRAY_INIT; + struct commit *commit; + int contains_another; + + char merged_revision[GIT_MAX_HEXSZ + 2]; + const char *rev_args[] = { "rev-list", "--merges", "--ancestry-path", + "--all", merged_revision, NULL }; + struct rev_info revs; + struct setup_revision_opt rev_opts; + + memset(result, 0, sizeof(struct object_array)); + memset(&rev_opts, 0, sizeof(rev_opts)); + + /* get all revisions that merge commit a */ + xsnprintf(merged_revision, sizeof(merged_revision), "^%s", + oid_to_hex(&a->object.oid)); + repo_init_revisions(repo, &revs, NULL); + rev_opts.submodule = path; + /* FIXME: can't handle linked worktrees in submodules yet */ + revs.single_worktree = path != NULL; + setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts); + + /* save all revisions from the above list that contain b */ + if (prepare_revision_walk(&revs)) + die("revision walk setup failed"); + while ((commit = get_revision(&revs)) != NULL) { + struct object *o = &(commit->object); + if (in_merge_bases(b, commit)) + add_object_array(o, NULL, &merges); + } + reset_revision_walk(); + + /* Now we've got all merges that contain a and b. Prune all + * merges that contain another found merge and save them in + * result. + */ + for (i = 0; i < merges.nr; i++) { + struct commit *m1 = (struct commit *) merges.objects[i].item; + + contains_another = 0; + for (j = 0; j < merges.nr; j++) { + struct commit *m2 = (struct commit *) merges.objects[j].item; + if (i != j && in_merge_bases(m2, m1)) { + contains_another = 1; + break; + } + } + + if (!contains_another) + add_object_array(merges.objects[i].item, NULL, result); + } + + object_array_clear(&merges); + return result->nr; } static int merge_submodule(struct merge_options *opt, From patchwork Fri Dec 18 05:51:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 11981183 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 10768C4361B for ; Fri, 18 Dec 2020 05:52:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B41EC23A57 for ; Fri, 18 Dec 2020 05:52:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732559AbgLRFwz (ORCPT ); Fri, 18 Dec 2020 00:52:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732318AbgLRFwy (ORCPT ); Fri, 18 Dec 2020 00:52:54 -0500 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67B4BC0611CC for ; Thu, 17 Dec 2020 21:51:39 -0800 (PST) Received: by mail-wr1-x42b.google.com with SMTP id m5so796651wrx.9 for ; Thu, 17 Dec 2020 21:51:39 -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=OhtQzFMI2wfrUKk4Dudo41Vcv3rpe9NHzEcS9zY8l0c=; b=NNHRBA/DpuafZL+Sndw45Mx8RgF5Kz2IO0Clsa4hOO4258H0KXFgjIuAQ6e4b2neDE Ncs807y0XYL6o1y6/7/5GEUgnhWETcpY9LCdDMSgsQOjxiPsKx0dkiB76PLKlncWjA9g wq1UsS2UyPcJhg+HVtUJAJ4IumiwS/5u+HyQTmCTDYNwRIqrnGfcwbQeZr2MHquflmrX SpSH38l3VjeF94WGAJavPi3zKaN5c8iKa3lFBtDy8mB2lQO8XRPV2UbAzF5wD9L2wo85 j+Mf0Bz1+qI4dGpZwVvvFyGEJ95M/WrOKDOdN+ZHF9pxG7CIoWKfAXUmh9HiACF0mA8k 3Mpw== 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=OhtQzFMI2wfrUKk4Dudo41Vcv3rpe9NHzEcS9zY8l0c=; b=VkHK7Gzpzso/+ThbPe5Yl3XwkxOMmCgr0oa9T/8qpHiLv+19qBxfL4s8nkrxLkmTmX wQSLoK8mNZgj9dHxrtne+KVNKn7+4zFZWa7gXgNERV8mvfRj7lB6aiZiH5CgzLKkj2p6 N87nNBGMZsa9eoKqHsFL5AQ/0z0aWWjERt9UvsLULKRqSs6zsKthPXSuKvHmxHn5KS30 YUhEc0slaAWOnYdptDjn4zMtLWZ28ZMogb+oxrSxwoa8W9SXZKidhnVa6NgfQAvpw70E jMklfPyZjGCkjlDqL2xCi0Jzp3+EC/mOXgE11ZZut99HPGj9WWDkgeDK4jCUFTMMcTJ6 swcw== X-Gm-Message-State: AOAM532Z3YCEc2JjgOLJQq6l38TUqxQPskZgWvbG5eR+cebTa1DlAM0A DULgzakIdAnbJlzZcHVekOZRQpnJ/ao= X-Google-Smtp-Source: ABdhPJy+7rt8/mhgcrImcCAuxS3CVEHnHQvL7sjwD781NpnNJ3EQWQMrujevSYBZo68hUV6OUQranw== X-Received: by 2002:a5d:4ccb:: with SMTP id c11mr2268380wrt.324.1608270697878; Thu, 17 Dec 2020 21:51:37 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id m5sm106380wrz.18.2020.12.17.21.51.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 21:51:37 -0800 (PST) Message-Id: <0a5778df2535c12b1ecb1484878e62d37e69d7cb.1608270687.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Fri, 18 Dec 2020 05:51:27 +0000 Subject: [PATCH 10/10] merge-ort: add handling for different types of files at same path Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Add some handling that explicitly considers collisions of the following types: * file/submodule * file/symlink * submodule/symlink Leaving them as conflicts at the same path are hard for users to resolve, so move one or both of them aside so that they each get their own path. Note that in the case of recursive handling (i.e. call_depth > 0), we can just use the merge base of the two merge bases as the merge result much like we do with modify/delete conflicts, binary files, conflicting submodule values, and so on. Signed-off-by: Elijah Newren --- merge-ort.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 203fa987e43..afe721182e2 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1521,10 +1521,109 @@ static void process_entry(struct merge_options *opt, } else if (ci->filemask >= 6 && (S_IFMT & ci->stages[1].mode) != (S_IFMT & ci->stages[2].mode)) { - /* - * Two different items from (file/submodule/symlink) - */ - die("Not yet implemented."); + /* Two different items from (file/submodule/symlink) */ + if (opt->priv->call_depth) { + /* Just use the version from the merge base */ + ci->merged.clean = 0; + oidcpy(&ci->merged.result.oid, &ci->stages[0].oid); + ci->merged.result.mode = ci->stages[0].mode; + ci->merged.is_null = (ci->merged.result.mode == 0); + } else { + /* Handle by renaming one or both to separate paths. */ + unsigned o_mode = ci->stages[0].mode; + unsigned a_mode = ci->stages[1].mode; + unsigned b_mode = ci->stages[2].mode; + struct conflict_info *new_ci; + const char *a_path = NULL, *b_path = NULL; + int rename_a = 0, rename_b = 0; + + new_ci = xmalloc(sizeof(*new_ci)); + + if (S_ISREG(a_mode)) + rename_a = 1; + else if (S_ISREG(b_mode)) + rename_b = 1; + else { + rename_a = 1; + rename_b = 1; + } + + path_msg(opt, path, 0, + _("CONFLICT (distinct types): %s had different " + "types on each side; renamed %s of them so " + "each can be recorded somewhere."), + path, + (rename_a && rename_b) ? _("both") : _("one")); + + ci->merged.clean = 0; + memcpy(new_ci, ci, sizeof(*new_ci)); + + /* Put b into new_ci, removing a from stages */ + new_ci->merged.result.mode = ci->stages[2].mode; + oidcpy(&new_ci->merged.result.oid, &ci->stages[2].oid); + new_ci->stages[1].mode = 0; + oidcpy(&new_ci->stages[1].oid, &null_oid); + new_ci->filemask = 5; + if ((S_IFMT & b_mode) != (S_IFMT & o_mode)) { + new_ci->stages[0].mode = 0; + oidcpy(&new_ci->stages[0].oid, &null_oid); + new_ci->filemask = 4; + } + + /* Leave only a in ci, fixing stages. */ + ci->merged.result.mode = ci->stages[1].mode; + oidcpy(&ci->merged.result.oid, &ci->stages[1].oid); + ci->stages[2].mode = 0; + oidcpy(&ci->stages[2].oid, &null_oid); + ci->filemask = 3; + if ((S_IFMT & a_mode) != (S_IFMT & o_mode)) { + ci->stages[0].mode = 0; + oidcpy(&ci->stages[0].oid, &null_oid); + ci->filemask = 2; + } + + /* Insert entries into opt->priv_paths */ + assert(rename_a || rename_b); + if (rename_a) { + a_path = unique_path(&opt->priv->paths, + path, opt->branch1); + strmap_put(&opt->priv->paths, a_path, ci); + } + + if (rename_b) + b_path = unique_path(&opt->priv->paths, + path, opt->branch2); + else + b_path = path; + strmap_put(&opt->priv->paths, b_path, new_ci); + + if (rename_a && rename_b) { + strmap_remove(&opt->priv->paths, path, 0); + /* + * We removed path from opt->priv->paths. path + * will also eventually need to be freed, but + * it may still be used by e.g. ci->pathnames. + * So, store it in another string-list for now. + */ + string_list_append(&opt->priv->paths_to_free, + path); + } + + /* + * Do special handling for b_path since process_entry() + * won't be called on it specially. + */ + strmap_put(&opt->priv->conflicted, b_path, new_ci); + record_entry_for_tree(dir_metadata, b_path, + &new_ci->merged); + + /* + * Remaining code for processing this entry should + * think in terms of processing a_path. + */ + if (a_path) + path = a_path; + } } else if (ci->filemask >= 6) { /* Need a two-way or three-way content merge */ struct version_info merged_file;