From patchwork Wed Feb 2 07:34:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732664 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD7A7C433FE for ; Wed, 2 Feb 2022 07:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238140AbiBBHeq (ORCPT ); Wed, 2 Feb 2022 02:34:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238048AbiBBHep (ORCPT ); Wed, 2 Feb 2022 02:34:45 -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 92C07C061714 for ; Tue, 1 Feb 2022 23:34:45 -0800 (PST) Received: by mail-wr1-x430.google.com with SMTP id e2so36635906wra.2 for ; Tue, 01 Feb 2022 23:34:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=HsHj2KxDWTA9QM6TZSN11NDwemvgrQd3pHbka8fElO8=; b=qWyPPa0T9JYdn+UDCC8fWI0AHy0ShE9yXmZc1Hj1FeTm/rwrqkCLcZp/Tbt1ovtlq2 SFn7nCebVS+WWpyXS9leYmgm2QKM2rONRaVzyrM7cAkB5WDIffQXJCdxmTn2Jw+pvILu RAvWLy9iYW0eJWCD/Ve3nMopT4KrjDlIsVvTBd/9Znwuj7ZXVisS98tc7PUuSqIKGMDX 74Kn0zSrbJB+UWz/SsYHSl5UlL1CDsT/SZBfiCLmX0w+SJhK7nb36SNxDTevZ6+o+sTm mHhFsNY4ttrSm2FTBUHBbqc2vtpBj85EWb1a2sW+i7wwx8qLx4VJOhlpDYepYu+VFMTp dgVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=HsHj2KxDWTA9QM6TZSN11NDwemvgrQd3pHbka8fElO8=; b=Pu2qkzM/W6MNg6ZvAp+CKRYSAFMB7oeqigzOEvt4NqOJ1k72Vr9XA5sDR+6Bia3sRW Te6t3zYBFkZW/pS+OzI4uAyULWhW7bs/FEwGfADPU8Sazbq6jSaVLKacmz0okbsNYrop 4cmb/OyJbHwHwkFeZj7ruggWPqKVmc3KivMxEB0PtqjbcesibbuE8vxuvIzpSRSe2eob P6e3v5E/lifjbMh8WZyH1IRz5zz6F5csKNsBEj6k+fYXgIz7sTMWkKyyfohCtl+gzpFU 6whoNGpAi2Dhqwb0TKxhzfDhwPRd6wZ9sVCTTohs8e3cVxub/pnK8KBrl3DdnVbEALnD vvzA== X-Gm-Message-State: AOAM532q9t0klcS9VRQzBec9JHw+mnH8ycgd46xWw0sLXI4bp/x/d73f VPtbSSPev/Fh+SBMypXoj+cmI9F9S78= X-Google-Smtp-Source: ABdhPJxdYahcD/la2KFIjc7X+Le7sesmThs6hFk7p/kcaDrpjuFpzMiMxA6MYRa+ZXzJjISjWHBKcg== X-Received: by 2002:a5d:4c88:: with SMTP id z8mr24044720wrs.209.1643787283929; Tue, 01 Feb 2022 23:34:43 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g6sm4397234wmq.3.2022.02.01.23.34.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:43 -0800 (PST) Message-Id: <4a7cd5542bb2f89b4874e4115542ccee9c4639af.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:27 +0000 Subject: [PATCH v3 01/15] merge-tree: rename merge_trees() to trivial_merge_trees() Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren merge-recursive.h defined its own merge_trees() function, different than the one found in builtin/merge-tree.c. That was okay in the past, but we want merge-tree to be able to use the merge-ort functions, which will end up including merge-recursive.h. Rename the function found in builtin/merge-tree.c to avoid the conflict. Signed-off-by: Elijah Newren --- builtin/merge-tree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 5dc94d6f880..06f9eee9f78 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -28,7 +28,7 @@ static void add_merge_entry(struct merge_list *entry) merge_result_end = &entry->next; } -static void merge_trees(struct tree_desc t[3], const char *base); +static void trivial_merge_trees(struct tree_desc t[3], const char *base); static const char *explanation(struct merge_list *entry) { @@ -225,7 +225,7 @@ static void unresolved_directory(const struct traverse_info *info, buf2 = fill_tree_descriptor(r, t + 2, ENTRY_OID(n + 2)); #undef ENTRY_OID - merge_trees(t, newbase); + trivial_merge_trees(t, newbase); free(buf0); free(buf1); @@ -342,7 +342,7 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s return mask; } -static void merge_trees(struct tree_desc t[3], const char *base) +static void trivial_merge_trees(struct tree_desc t[3], const char *base) { struct traverse_info info; @@ -378,7 +378,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) buf1 = get_tree_descriptor(r, t+0, argv[1]); buf2 = get_tree_descriptor(r, t+1, argv[2]); buf3 = get_tree_descriptor(r, t+2, argv[3]); - merge_trees(t, ""); + trivial_merge_trees(t, ""); free(buf1); free(buf2); free(buf3); From patchwork Wed Feb 2 07:34:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732665 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8B09C433F5 for ; Wed, 2 Feb 2022 07:34:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238315AbiBBHev (ORCPT ); Wed, 2 Feb 2022 02:34:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238048AbiBBHeq (ORCPT ); Wed, 2 Feb 2022 02:34:46 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7179BC061714 for ; Tue, 1 Feb 2022 23:34:46 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id u15so36601481wrt.3 for ; Tue, 01 Feb 2022 23:34:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=s/FNUD3Nfv1aJ56di/sqnJE/jJBUPQEIKWoIKlAJYVg=; b=UXMWn4Wa3cHRYntS+MDukKQKR1YaCl21cesMTEuDJmrer/0bUX0cEDi+G9u6haqmIw 4RyV9OvEzfkIZ8TZOQF7wlux0O4QANC/I73uiRQZW/MDPqSh3MucIwRWzAOJEYViRNqh QEWq+LjjNkeu2Tz+o0scyVX+S7JfRFFVEWtYVckAmkthTEQsbcGWYY9dWw/fAkoWyqXD XC5qvZvoDgy8wyH7q0Nfl5errROIQzVOz4rW5s+fdvwnJ3nNVnCEfkaRgJx9mLmJHexo bdBp3AkthFKxB6NEH+wJXIIE3XwV2GZja2bG4pWyy2qm5Pb6Yd+zg/TIPq28wGVbJcbl DZqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=s/FNUD3Nfv1aJ56di/sqnJE/jJBUPQEIKWoIKlAJYVg=; b=4rC+xA7LrxlI5O/wbCOyditqiPf2hkjbKkG8ibSsla5ONr0R6G9I25Cq0r2rDgAqK6 33yPxPDarkOFWeaHTnnshLi8Zz8pz7JAMB6CfHm7Fa39bWECMfMcs8m5nGX6FAi4yI0T DWK4yrT7FaAaXiViWOo1VSLb1KMa0YwQ0scNahYv5S7Y5n/Omqz3toIMYqhmbWe4nCiC 6OSaQY7ksrZ85zUlNMa61b2DnLH5/sUUn836Az+tnWEQnLPRuhI0l54ErMw6vAmRZFX+ j3AaJ80L2na6Lu5jeRHlD+yxMisKltWIJ2G/naQ9JJZNYH/ZI2xqPSKDbc5A75ICP1Dk IFAQ== X-Gm-Message-State: AOAM5324czAfb/+8v1pW/si9XTXihWg8zRjFAT/cZv1kE0WGNSCmRa6D YLImaDj0qZkwxAWFMrGmNF7ZiDMJB7M= X-Google-Smtp-Source: ABdhPJwO0qofRf3Ndxr4TfcLnatCDpRHCWk3Lh7/KPz+45IJUR/ZzsKi28OR84aXcr6N3oPDKww3kw== X-Received: by 2002:a5d:524e:: with SMTP id k14mr23920339wrc.620.1643787284884; Tue, 01 Feb 2022 23:34:44 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c14sm18048078wri.56.2022.02.01.23.34.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:44 -0800 (PST) Message-Id: <4780ff6784d426bf0a96859ef9bf9c14e87d5f50.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:28 +0000 Subject: [PATCH v3 02/15] merge-tree: move logic for existing merge into new function Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren In preparation for adding a non-trivial merge capability to merge-tree, move the existing merge logic for trivial merges into a new function. Signed-off-by: Elijah Newren --- builtin/merge-tree.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 06f9eee9f78..914ec960b7e 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -366,15 +366,12 @@ static void *get_tree_descriptor(struct repository *r, return buf; } -int cmd_merge_tree(int argc, const char **argv, const char *prefix) +static int trivial_merge(int argc, const char **argv) { struct repository *r = the_repository; struct tree_desc t[3]; void *buf1, *buf2, *buf3; - if (argc != 4) - usage(merge_tree_usage); - buf1 = get_tree_descriptor(r, t+0, argv[1]); buf2 = get_tree_descriptor(r, t+1, argv[2]); buf3 = get_tree_descriptor(r, t+2, argv[3]); @@ -386,3 +383,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) show_result(); return 0; } + +int cmd_merge_tree(int argc, const char **argv, const char *prefix) +{ + if (argc != 4) + usage(merge_tree_usage); + return trivial_merge(argc, argv); +} From patchwork Wed Feb 2 07:34:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732666 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8A3EC433EF for ; Wed, 2 Feb 2022 07:34:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238739AbiBBHew (ORCPT ); Wed, 2 Feb 2022 02:34:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238217AbiBBHer (ORCPT ); Wed, 2 Feb 2022 02:34:47 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 44F4CC06173B for ; Tue, 1 Feb 2022 23:34:47 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id s9so36528407wrb.6 for ; Tue, 01 Feb 2022 23:34:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=6oNLvE3Kf1AT5/coVfsEXJRsaPG9jKHHjbI8tr++geM=; b=jM333KnpI1tCzsu63kLECDPpPRlb+Y0p1Tnf2H5El8gCxRuDBfhRbcalCY0A3YcJDO q+nHR3jgdmd2R4SiKP4bvvHD3GhQq60FiGNYwHHvclqC3DxAjMX79WTvj2UOzpz54YZJ btqXRG2ialRq1eOW5iBe0ulQVGBUA1CQ2kzjRA9Pl9vben/Q72ZPIzORaDAt4V7WxGBK OHl7VlExoInb5mz+Ixmpzn5YPa+pi/MY128OpEi0cEK/BlqbPFgsejYCRuKEpa3V/hgk nnFeCMFXwCxWQby7aK9Rc0GZYz7Rwbh3FT8uG7yfdRjUy6h7UpbgLDW+H6QnTykaFHQ5 zo7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=6oNLvE3Kf1AT5/coVfsEXJRsaPG9jKHHjbI8tr++geM=; b=ePD6GO3XOob3GxHRLD7lAeDXxRWD1QxuQ6KLEOfZDAv8uaHbgFAuOEz6Qinouo9qFn +6I3CGmQgjbMPKvwTm63rXF5hCuI3VhT0M2CmMYUphsW+Ini+1oSuv1YoNA9JKTpQgPn rYmIOJRUv06p4ZRUDRCI9DTKQYOlaCtNLDhcgRIRf8XmO2aM7bReBsbkiaX2bl2NR9yy /B4Is6E0cDTdP1JUvGJ/3Ux38B4I4OtYvLNPLnuf5rzf2WmlOLZG5mOSEgrzsNcHaNW9 MgKAUCEMorj9THJnghFiFJK5hw8VE4CbdLtus8vJ8YmrBndVdPEQbUXQ+ziaO1LTNzwC 4jXA== X-Gm-Message-State: AOAM53354Smj5z00tYVxcXEbs1nbgaPjr0UaX3WnXrmCilKSHTINJyiQ CJcnhsV5xZo3awwKeC3FCLQMJtn2Nzo= X-Google-Smtp-Source: ABdhPJzSy0ZLb3/OOuGxZQs+ZKVZID32nk85p8t9+DMQjBL0r/0cTfcFp3MXI/u0GOm9RnB4iRqB6w== X-Received: by 2002:a05:6000:2ad:: with SMTP id l13mr23811150wry.174.1643787285668; Tue, 01 Feb 2022 23:34:45 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k10sm3805487wmi.1.2022.02.01.23.34.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:45 -0800 (PST) Message-Id: <63f42df21aec5bda50e4414493eb59dcb64e5558.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:29 +0000 Subject: [PATCH v3 03/15] merge-tree: add option parsing and initial shell for real merge function Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Let merge-tree accept a `--write-tree` parameter for choosing real merges instead of trivial merges, and accept an optional `--trivial-merge` option to get the traditional behavior. Note that these accept different numbers of arguments, though, so these names need not actually be used. Note that real merges differ from trivial merges in that they handle: - three way content merges - recursive ancestor consolidation - renames - proper directory/file conflict handling - etc. Basically all the stuff you'd expect from `git merge`, just without updating the index and working tree. The initial shell added here does nothing more than die with "real merges are not yet implemented", but that will be fixed in subsequent commits. Signed-off-by: Elijah Newren --- builtin/merge-tree.c | 61 +++++++++++++++++++++++++++++++++++++------- git.c | 2 +- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 914ec960b7e..e98ec8a9f1d 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -3,13 +3,12 @@ #include "tree-walk.h" #include "xdiff-interface.h" #include "object-store.h" +#include "parse-options.h" #include "repository.h" #include "blob.h" #include "exec-cmd.h" #include "merge-blobs.h" -static const char merge_tree_usage[] = "git merge-tree "; - struct merge_list { struct merge_list *next; struct merge_list *link; /* other stages for this object */ @@ -366,15 +365,17 @@ static void *get_tree_descriptor(struct repository *r, return buf; } -static int trivial_merge(int argc, const char **argv) +static int trivial_merge(const char *base, + const char *branch1, + const char *branch2) { struct repository *r = the_repository; struct tree_desc t[3]; void *buf1, *buf2, *buf3; - buf1 = get_tree_descriptor(r, t+0, argv[1]); - buf2 = get_tree_descriptor(r, t+1, argv[2]); - buf3 = get_tree_descriptor(r, t+2, argv[3]); + buf1 = get_tree_descriptor(r, t+0, base); + buf2 = get_tree_descriptor(r, t+1, branch1); + buf3 = get_tree_descriptor(r, t+2, branch2); trivial_merge_trees(t, ""); free(buf1); free(buf2); @@ -384,9 +385,51 @@ static int trivial_merge(int argc, const char **argv) return 0; } +struct merge_tree_options { + int mode; +}; + +static int real_merge(struct merge_tree_options *o, + const char *branch1, const char *branch2) +{ + die(_("real merges are not yet implemented")); +} + int cmd_merge_tree(int argc, const char **argv, const char *prefix) { - if (argc != 4) - usage(merge_tree_usage); - return trivial_merge(argc, argv); + struct merge_tree_options o = { 0 }; + int expected_remaining_argc; + + const char * const merge_tree_usage[] = { + N_("git merge-tree [--write-tree] "), + N_("git merge-tree [--trivial-merge] "), + NULL + }; + struct option mt_options[] = { + OPT_CMDMODE(0, "write-tree", &o.mode, + N_("do a real merge instead of a trivial merge"), + 'w'), + OPT_CMDMODE(0, "trivial-merge", &o.mode, + N_("do a trivial merge only"), 't'), + OPT_END() + }; + + /* Parse arguments */ + argc = parse_options(argc, argv, prefix, mt_options, + merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (o.mode) { + expected_remaining_argc = (o.mode == 'w' ? 2 : 3); + if (argc != expected_remaining_argc) + usage_with_options(merge_tree_usage, mt_options); + } else { + if (argc < 2 || argc > 3) + usage_with_options(merge_tree_usage, mt_options); + o.mode = (argc == 2 ? 'w' : 't'); + } + + /* Do the relevant type of merge */ + if (o.mode == 'w') + return real_merge(&o, argv[0], argv[1]); + else + return trivial_merge(argv[0], argv[1], argv[2]); } diff --git a/git.c b/git.c index 5ff21be21f3..6090a1289db 100644 --- a/git.c +++ b/git.c @@ -558,7 +558,7 @@ static struct cmd_struct commands[] = { { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, - { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT }, + { "merge-tree", cmd_merge_tree, RUN_SETUP }, { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT }, { "mktree", cmd_mktree, RUN_SETUP }, { "multi-pack-index", cmd_multi_pack_index, RUN_SETUP }, From patchwork Wed Feb 2 07:34:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732667 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53667C433F5 for ; Wed, 2 Feb 2022 07:34:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239012AbiBBHex (ORCPT ); Wed, 2 Feb 2022 02:34:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233140AbiBBHeu (ORCPT ); Wed, 2 Feb 2022 02:34:50 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40298C061741 for ; Tue, 1 Feb 2022 23:34:48 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id i82so369376wma.1 for ; Tue, 01 Feb 2022 23:34:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=jiWw73ElfvDNzg9QG12H1L3cZ/9znWEQgBx121aVEwg=; b=YWSIWI3ZpsPOpcQBFb+LDwrItHfmjz96KXSumSAbNjjJrpPgxTYFUYS/c4e5qJY5Mo PAWihK70DPaFdknzcCLgQ/k5lBjB64l+ms6pFO6yaGfbtM+1uXxyvuRGIFMw3k1KcOLN a9PADo14yCgwks6c0jAM+roGoSXskZq4L0CZsuLfYdBzLfjIcnHryMcOXaxpNZvo4Bv6 ltnLLQNsxx22l8PgKJQpuoyEJQjnuPCiYCFaeLBusxBeNQTJY6ezlZEWQIlXuftphAtf bQUGLl/KAzOeBalxi2ZFwOa3FeOJDi9vg8QOPftkra+9fdzO5WAdvLnoo0yN6zh5r2+I gcRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=jiWw73ElfvDNzg9QG12H1L3cZ/9znWEQgBx121aVEwg=; b=Avtm7eYHq/NKSjwEY/tNZAbZtBH8GS+sDncG4EJ2eAToZ3KTe1qNw5Wa2AmML/iRwg /MVcRePq0XBByhyzzErwnjXljsdIGIFuMQaNrTNOYnwAOQEgtDK5HJ0mtr15RvUyHI9L hfZpw2C885FvipgY+PxqLis268WfxCkCzXFRV83YzWiBQ0dJwbdgWsnU2WSBstz3fBf+ OrB7CqJb77j63xF2pzkQ1KSJSQoguaSaK/SmdcDsmdcFmoTiHSg7nAvXglIF06Xxh3+2 PW0zdXPk1bTgV1Dii8KclxExxjaP8mQNTP2JW2oku8dOM+LOena+7u4frNA+xs+glERR 6o3Q== X-Gm-Message-State: AOAM530ZvZYvOak2gqLAWbWPrYszUsHbpBGtx4Gdx2p/8OZD35IUSvNH 8qDPBp6KbptakXR7ZDClyK6MU4nnIBI= X-Google-Smtp-Source: ABdhPJw7mSJAByeOI8iTab8VMhfaCMM4s7/KLW4i59/IKeFh79xxlt86lbjupSfQPeMB1KcCw3ynCg== X-Received: by 2002:a1c:a5d0:: with SMTP id o199mr4966799wme.65.1643787286617; Tue, 01 Feb 2022 23:34:46 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n14sm17096949wri.75.2022.02.01.23.34.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:46 -0800 (PST) Message-Id: <02c29f920d0d5fde6d85f7b86a69be92e3f0f34d.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:30 +0000 Subject: [PATCH v3 04/15] merge-tree: implement real merges Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This adds the ability to perform real merges rather than just trivial merges (meaning handling three way content merges, recursive ancestor consolidation, renames, proper directory/file conflict handling, and so forth). However, unlike `git merge`, the working tree and index are left alone and no branch is updated. The only output is: - the toplevel resulting tree printed on stdout - exit status of 0 (clean), 1 (conflicts present), anything else (merge could not be performed; unknown if clean or conflicted) This output is meant to be used by some higher level script, perhaps in a sequence of steps like this: NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) test $? -eq 0 || die "There were conflicts..." NEWCOMMIT=$(git commit-tree $NEWTREE -p $BRANCH1 -p $BRANCH2) git update-ref $BRANCH1 $NEWCOMMIT Note that higher level scripts may also want to access the conflict/warning messages normally output during a merge, or have quick access to a list of files with conflicts. That is not available in this preliminary implementation, but subsequent commits will add that ability. This also marks the traditional trivial merge of merge-tree as deprecated. The trivial merge not only had limited applicability, the output format was also difficult to work with (and its format undocumented), and will generally be less performant than real merges. Signed-off-by: Elijah Newren Signed-off-by: Johannes Schindelin --- Documentation/git-merge-tree.txt | 71 +++++++++++++++++++++----- builtin/merge-tree.c | 44 +++++++++++++++- t/t4301-merge-tree-write-tree.sh | 88 ++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 13 deletions(-) create mode 100755 t/t4301-merge-tree-write-tree.sh diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 58731c19422..569485815a0 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -3,26 +3,73 @@ git-merge-tree(1) NAME ---- -git-merge-tree - Show three-way merge without touching index +git-merge-tree - Perform merge without touching index or working tree SYNOPSIS -------- [verse] -'git merge-tree' +'git merge-tree' [--write-tree] +'git merge-tree' [--trivial-merge] (deprecated) DESCRIPTION ----------- -Reads three tree-ish, and output trivial merge results and -conflicting stages to the standard output. This is similar to -what three-way 'git read-tree -m' does, but instead of storing the -results in the index, the command outputs the entries to the -standard output. - -This is meant to be used by higher level scripts to compute -merge results outside of the index, and stuff the results back into the -index. For this reason, the output from the command omits -entries that match the tree. + +Performs a merge, but does not make any new commits and does not read +from or write to either the working tree or index. + +The second form is deprecated and supported only for backward +compatibility. It will likely be removed in the future, and will not +be discussed further in this manual. + +The first form will merge the two branches, doing a real merge. A real +merge is distinguished from a trivial merge in that it includes: + + * three way content merges of individual files + * rename detection + * proper directory/file conflict handling + * recursive ancestor consolidation (i.e. when there is more than one + merge base, creating a virtual merge base by merging the merge bases) + * etc. + +After the merge completes, it will create a new toplevel tree object. +See `OUTPUT` below for details. + +OUTPUT +------ + +For either a successful or conflicted merge, the output from +git-merge-tree is simply one line: + + + +The printed tree object corresponds to what would be checked out in +the working tree at the end of `git merge`, and thus may have files +with conflict markers in them. + +EXIT STATUS +----------- + +For a successful, non-conflicted merge, the exit status is 0. When the +merge has conflicts, the exit status is 1. If the merge is not able to +complete (or start) due to some kind of error, the exit status is +something other than 0 or 1. + +USAGE NOTES +----------- + +git-merge-tree was written to be low-level plumbing, similar to +hash-object, mktree, commit-tree, update-ref, and mktag. Thus, it could +be used as a part of a series of steps such as + + NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) + test $? -eq 0 || die "There were conflicts..." + NEWCOMMIT=$(git commit-tree $NEWTREE -p $BRANCH1 -p $BRANCH2) + git update-ref $BRANCH1 $NEWCOMMIT + +However, it does not quite fit into the same category of low-level +plumbing commands since the possibility of merge conflicts give it a +much higher chance of the command not succeeding. GIT --- diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index e98ec8a9f1d..d14c9f6e44e 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -2,6 +2,9 @@ #include "builtin.h" #include "tree-walk.h" #include "xdiff-interface.h" +#include "help.h" +#include "commit-reach.h" +#include "merge-ort.h" #include "object-store.h" #include "parse-options.h" #include "repository.h" @@ -392,7 +395,46 @@ struct merge_tree_options { static int real_merge(struct merge_tree_options *o, const char *branch1, const char *branch2) { - die(_("real merges are not yet implemented")); + struct commit *parent1, *parent2; + struct commit_list *common; + struct commit_list *merge_bases = NULL; + struct commit_list *j; + struct merge_options opt; + struct merge_result result = { 0 }; + + parent1 = get_merge_parent(branch1); + if (!parent1) + help_unknown_ref(branch1, "merge-tree", + _("not something we can merge")); + + parent2 = get_merge_parent(branch2); + if (!parent2) + help_unknown_ref(branch2, "merge-tree", + _("not something we can merge")); + + init_merge_options(&opt, the_repository); + + opt.show_rename_progress = 0; + + opt.branch1 = branch1; + opt.branch2 = branch2; + + /* + * Get the merge bases, in reverse order; see comment above + * merge_incore_recursive in merge-ort.h + */ + common = get_merge_bases(parent1, parent2); + if (!common) + die(_("refusing to merge unrelated histories")); + for (j = common; j; j = j->next) + commit_list_insert(j->item, &merge_bases); + + merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result); + if (result.clean < 0) + die(_("failure to merge")); + puts(oid_to_hex(&result.tree->object.oid)); + merge_finalize(&opt, &result); + return !result.clean; /* result.clean < 0 handled above */ } int cmd_merge_tree(int argc, const char **argv, const char *prefix) diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh new file mode 100755 index 00000000000..66c3eaf2021 --- /dev/null +++ b/t/t4301-merge-tree-write-tree.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='git merge-tree --write-tree' + +. ./test-lib.sh + +# This test is ort-specific +if test "${GIT_TEST_MERGE_ALGORITHM}" != "ort" +then + skip_all="GIT_TEST_MERGE_ALGORITHM != ort" + test_done +fi + +test_expect_success setup ' + test_write_lines 1 2 3 4 5 >numbers && + echo hello >greeting && + echo foo >whatever && + git add numbers greeting whatever && + test_tick && + git commit -m initial && + + git branch side1 && + git branch side2 && + + git checkout side1 && + test_write_lines 1 2 3 4 5 6 >numbers && + echo hi >greeting && + echo bar >whatever && + git add numbers greeting whatever && + test_tick && + git commit -m modify-stuff && + + git checkout side2 && + test_write_lines 0 1 2 3 4 5 >numbers && + echo yo >greeting && + git rm whatever && + mkdir whatever && + >whatever/empty && + git add numbers greeting whatever/empty && + test_tick && + git commit -m other-modifications +' + +test_expect_success 'Content merge and a few conflicts' ' + git checkout side1^0 && + test_must_fail git merge side2 && + expected_tree=$(cat .git/AUTO_MERGE) && + + # We will redo the merge, while we are still in a conflicted state! + test_when_finished "git reset --hard" && + + test_expect_code 1 git merge-tree --write-tree side1 side2 >RESULT && + actual_tree=$(head -n 1 RESULT) && + + # Due to differences of e.g. "HEAD" vs "side1", the results will not + # exactly match. Dig into individual files. + + # Numbers should have three-way merged cleanly + test_write_lines 0 1 2 3 4 5 6 >expect && + git show ${actual_tree}:numbers >actual && + test_cmp expect actual && + + # whatever and whatever~ should have same HASHES + git rev-parse ${expected_tree}:whatever ${expected_tree}:whatever~HEAD >expect && + git rev-parse ${actual_tree}:whatever ${actual_tree}:whatever~side1 >actual && + test_cmp expect actual && + + # greeting should have a merge conflict + git show ${expected_tree}:greeting >tmp && + cat tmp | sed -e s/HEAD/side1/ >expect && + git show ${actual_tree}:greeting >actual && + test_cmp expect actual +' + +test_expect_success 'Barf on misspelled option, with exit code other than 0 or 1' ' + # Mis-spell with single "s" instead of double "s" + test_expect_code 129 git merge-tree --write-tree --mesages FOOBAR side1 side2 2>expect && + + grep "error: unknown option.*mesages" expect +' + +test_expect_success 'Barf on too many arguments' ' + test_expect_code 129 git merge-tree --write-tree side1 side2 side3 2>expect && + + grep "^usage: git merge-tree" expect +' + +test_done From patchwork Wed Feb 2 07:34:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin X-Patchwork-Id: 12732668 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 541ADC433F5 for ; Wed, 2 Feb 2022 07:34:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239287AbiBBHe4 (ORCPT ); Wed, 2 Feb 2022 02:34:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238436AbiBBHeu (ORCPT ); Wed, 2 Feb 2022 02:34:50 -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 014A1C061744 for ; Tue, 1 Feb 2022 23:34:49 -0800 (PST) Received: by mail-wr1-x431.google.com with SMTP id a13so36590852wrh.9 for ; Tue, 01 Feb 2022 23:34:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=/Hd+gHGQwZ5LygnSwiXiwkGrK0fyJvSF73snz4VsFvU=; b=BP+61sE4fQ7qF6hiaopb5hgbLJhuG3aeqO4RxBAyGGJW8YPWB1dBNeGOu1o5aAtGQB dlhpLuZ5HIw5qcTUgHtV0lkeLlzHp3aMti0vky0MqoYeoKLOwZu3U7go+TOj7oUDee21 pfIB8QMvXUGU5ywtsGkUYDToFr0IuCt4SW5dy48FplC3K8fmYDg9tNMFVSBU9ySDHFZF VsWLeHcAT/sBojbyCsXRmd2cc19nowaB24sOvWC0pAmYuBNd8DD+2IlM58/EhKLrUjCu 5L/wmIMsp2haOHVEFQ6/iiZGvHNVu8dMpXG6mXddq/gaXUeXewaVri2rnwislYsWRN7u /kbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=/Hd+gHGQwZ5LygnSwiXiwkGrK0fyJvSF73snz4VsFvU=; b=Iq00eAOLI51vSHUHVjoKwI6FrU8Ejw6tsR4sCgJ3Kxa4wWAGTJqKETtCnmr23anAIv baXTQzmnInsE/dmAZ5nbUOmnZon03WjK/YBMoWnl2DChtrv24OF26BUZ9KBweq4HcDpC t70X4sS/8z3ou+1YhDF+5jEIY7w9i0b072UmYZg+t4Za/pVAlyGl6+r5Hqy71e4S3ph2 MdE3z3WcO/zR7azaWMLAulfKcAoALLiINI6GrQOZUWBVdnrwajTNHr3vaVDs524w8mim 6eMshNeeRMMRrZwh0uGAew8OHi3qCyyZvXhbXgzxKhfNGMefO8pKBFwjCSVktKwMiJS1 J8hg== X-Gm-Message-State: AOAM532WhgJEOVBPBPREKYIkuzGxo6QXKdguGuUrR4GJqYFy9s5xY33u GGYU4a1DFqpCPOaVMy73SrBSxwMCV3A= X-Google-Smtp-Source: ABdhPJyUi8Msd5k9+zRQZfQpuD+f1+uQunkUgR6iSlNvsSHJLbhvbh3/EPKp/Dxh+l1zkEXl3zm7YQ== X-Received: by 2002:adf:ef47:: with SMTP id c7mr24244957wrp.330.1643787287434; Tue, 01 Feb 2022 23:34:47 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x13sm16525796wru.28.2022.02.01.23.34.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:47 -0800 (PST) Message-Id: <290b42846b5557055b84e4237ddc8c3532752d5d.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:31 +0000 Subject: [PATCH v3 05/15] Introduce a variant of the `warning()` function that takes a `FILE *` Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Johannes Schindelin Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Johannes Schindelin From: Johannes Schindelin We are about to teach `diff_warn_rename_limit()` to write into a file instead of `stderr`. That function wants to call `warning()` when writing to `stderr`, though, allowing for the `warn_routine` to be overridden. Let's introduce a helper for that. Note: Since there is currently no need to provide similar functions for `error()` or `die()`, let alone for the `_errno` variants, we will leave that to a date when the need for those should arise, if ever. Signed-off-by: Johannes Schindelin Signed-off-by: Elijah Newren --- git-compat-util.h | 1 + usage.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/git-compat-util.h b/git-compat-util.h index d70ce142861..64ba60e5c71 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -475,6 +475,7 @@ int error(const char *err, ...) __attribute__((format (printf, 1, 2))); int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); +void warning_fp(FILE *out, const char *warn, ...) __attribute__((format (printf, 2, 3))); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index c7d233b0de9..0bfd2c603c0 100644 --- a/usage.c +++ b/usage.c @@ -253,6 +253,20 @@ void warning(const char *warn, ...) va_end(params); } +void warning_fp(FILE *out, const char *warn, ...) +{ + va_list params; + + va_start(params, warn); + if (out == stderr) + warn_routine(warn, params); + else { + vfprintf(out, warn, params); + fputc('\n', out); + } + va_end(params); +} + /* Only set this, ever, from t/helper/, when verifying that bugs are caught. */ int BUG_exit_code; From patchwork Wed Feb 2 07:34:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Schindelin X-Patchwork-Id: 12732669 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD7CDC433EF for ; Wed, 2 Feb 2022 07:35:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239028AbiBBHfL (ORCPT ); Wed, 2 Feb 2022 02:35:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238595AbiBBHeu (ORCPT ); Wed, 2 Feb 2022 02:34:50 -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 B642EC061749 for ; Tue, 1 Feb 2022 23:34:49 -0800 (PST) Received: by mail-wr1-x42e.google.com with SMTP id v13so36493682wrv.10 for ; Tue, 01 Feb 2022 23:34:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=CCJu1qRgU+efLvJ/97QHm+4PR5UCSFt0TFjS1CluVM4=; b=DSj/kmkMdH89j+WKFJACQ4qfdoS5X5a9rfT8T/NPgnRTUScPHChoQCfkhxlyqEAd9k 0Ya4/1Fh/MW5mweLx/YPqblP53jBFR0vLihev9ldOMRPylpk8lWVq5ACMxoPNgimaTwo sAcvHh89TTBSItMx8/Jpeem6nd55lxEpNGdpkx87bAm9m6+yxeXskGvoVw+jr3lGIOjX ZdNmzgmW4LQ+Y7Rrnx7AcBTiLpaE7gH4HzWwxUQyhFcRXebsEgylBLm6xZzUDg9z1PBb mYrDQaBPf/Ohr7cTSKcqirjfXvs0+T6VVhYTKa2YhMSTQLK3mjfXTdwKNk0B4ewDScpR +hjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=CCJu1qRgU+efLvJ/97QHm+4PR5UCSFt0TFjS1CluVM4=; b=Z/eKy6hcfHwCjF7NiXeaR7ZiFfUtxTxw45y65czYRgcpQRDUhV2HN6U+kr8ApMkdwd GVJBYaeEz87yXbmNPIWj+h++9J4qzoDywOKZI+GLZwRROCdh5It4EZk0xLWW0DSRd/Wh BafIFi5heqcc9K3C2H/Ipf9+VTeEopSW8Cwlj01uVJVL8je55A2T1i9bnh5kZrWBeEju iUiLtnRIf83iUY2I0kTcLoH5TFoJId4V6fwgIyAk5pVq5rZ9hzsxx20XXaMgRkesIM5E YSSsbxmdjPEpCr+lIOfpA93HzPnqlagptm7gO1XU/9i6slpo6ViX8APH4LtLliddNhWC 4Ycw== X-Gm-Message-State: AOAM533kFuAww/0Sj8p59ByeFHqFhLBOsTN/jZHhc2KBZPd/uGfOZXsu o5iny2gk4PvMJHVdDfwWZ00TWmeOkzU= X-Google-Smtp-Source: ABdhPJxlSK7f9dMBm6FGGRPbHWN6QeDe8ErMz/FUYpS9bj5xZ2Qaxt1Ygc9vYIBmABZaSnoYJrVXBw== X-Received: by 2002:adf:dc44:: with SMTP id m4mr24559929wrj.355.1643787288221; Tue, 01 Feb 2022 23:34:48 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id m14sm20596793wrp.4.2022.02.01.23.34.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:47 -0800 (PST) Message-Id: <2083fbe9b2e3e1deb94c9903fd0fa2dddd619b3c.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:32 +0000 Subject: [PATCH v3 06/15] diff: allow diff_warn_rename_limit to write somewhere besides stderr Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Johannes Schindelin Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Johannes Schindelin From: Johannes Schindelin diff_warn_rename_limit() is hardcoded to write to stderr. Make it accept a file stream parameter to make it more flexible. Signed-off-by: Johannes Schindelin Signed-off-by: Elijah Newren --- diff.c | 13 ++++++++----- diff.h | 3 ++- merge-ort.c | 2 +- merge-recursive.c | 3 ++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/diff.c b/diff.c index 1bfb01c18ec..28368110147 100644 --- a/diff.c +++ b/diff.c @@ -6377,17 +6377,20 @@ static const char rename_limit_advice[] = N_("you may want to set your %s variable to at least " "%d and retry the command."); -void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc) +void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc, + FILE *out) { fflush(stdout); if (degraded_cc) - warning(_(degrade_cc_to_c_warning)); + warning_fp(out, _(degrade_cc_to_c_warning)); else if (needed) - warning(_(rename_limit_warning)); + warning_fp(out, _(rename_limit_warning)); else return; + + if (0 < needed) - warning(_(rename_limit_advice), varname, needed); + warning_fp(out, _(rename_limit_advice), varname, needed); } static void create_filepairs_for_header_only_notifications(struct diff_options *o) @@ -6870,7 +6873,7 @@ int diff_result_code(struct diff_options *opt, int status) diff_warn_rename_limit("diff.renameLimit", opt->needed_rename_limit, - opt->degraded_cc_to_c); + opt->degraded_cc_to_c, stderr); if (!opt->flags.exit_with_status && !(opt->output_format & DIFF_FORMAT_CHECKDIFF)) return status; diff --git a/diff.h b/diff.h index ce9e2cf2e4f..40c5b78fb0a 100644 --- a/diff.h +++ b/diff.h @@ -597,7 +597,8 @@ void diffcore_fix_diff_index(void); int diff_queue_is_empty(struct diff_options *o); void diff_flush(struct diff_options*); void diff_free(struct diff_options*); -void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc); +void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc, + FILE *out); /* diff-raw status letters */ #define DIFF_STATUS_ADDED 'A' diff --git a/merge-ort.c b/merge-ort.c index 9bf15a01db8..46e72b62880 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4305,7 +4305,7 @@ void merge_switch_to_result(struct merge_options *opt, /* Also include needed rename limit adjustment now */ diff_warn_rename_limit("merge.renamelimit", - opti->renames.needed_limit, 0); + opti->renames.needed_limit, 0, stderr); trace2_region_leave("merge", "display messages", opt->repo); } diff --git a/merge-recursive.c b/merge-recursive.c index 9ec1e6d043a..01ca82773cc 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -3738,7 +3738,8 @@ static void merge_finalize(struct merge_options *opt) strbuf_release(&opt->obuf); if (show(opt, 2)) diff_warn_rename_limit("merge.renamelimit", - opt->priv->needed_rename_limit, 0); + opt->priv->needed_rename_limit, 0, + stderr); FREE_AND_NULL(opt->priv); } From patchwork Wed Feb 2 07:34:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732670 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48546C433F5 for ; Wed, 2 Feb 2022 07:35:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238596AbiBBHfN (ORCPT ); Wed, 2 Feb 2022 02:35:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238277AbiBBHev (ORCPT ); Wed, 2 Feb 2022 02:34:51 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA674C061714 for ; Tue, 1 Feb 2022 23:34:50 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id a13so36590974wrh.9 for ; Tue, 01 Feb 2022 23:34:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=3b+i8wSzWUdkX2iYVL0L852mgfOFWSqFUSZSzKk1xq0=; b=THk0xAJlzmmZU6bg+AZs8YW9EWIWiYljE7AkJrneQVJaKw4KsfVfkpmajWRviN0htj BKEpACmsu56dr6jbdUEU/lfFTrWkrZ6vZ3zmBl2ocpR588erjRkJ7CukrYrFACufRBAY MTc1BmjlRzbVYt7ac9g+jUeFioxrFTpY7fEftVdK/orYafDgJGHSY8nluwBIWfJgJypq 1IgbneSZHgAXCqkeHtf5kjV657oYZeJfYz4NDfMs+w7wrSYExGgV/P/HS5AZ+dGhF7lT zIPTVKPAkDwH0LdTdEteZjvViA31wOH4Mwjt+wbsePdQr1YLkB8YPAv3NxLbniGdipGS wrcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=3b+i8wSzWUdkX2iYVL0L852mgfOFWSqFUSZSzKk1xq0=; b=3AivnMqEgIdhTb9B+Z1p6Wfp8qF9O60Hrs7HX4a7UtphKsf9YnnrRWU27rwsw9yklf BQ5ac5ccv+5YlR66YnfqBr8av1PsRfZU8QGz9DZtSN5vxbRzMlRx/VA9F6gKK/gAS4PD qs4FWDuoSb2EB1DniQz0pVH2LS22Wrhrg8URMkWheNTJJVMAG1ex+FARMB0+g3mD2E7p D692m2zcs+7YvkofVeFrAOhDPszJwS3vwX7pgE5OYifP6vLqdACMOpm6JzJjYy5jTL/6 VJLNfETjsxXfdcUwVa+iycZlP5ZjGKFHEeonG1+5PA9g405onpmZgzOc6N3tT8kbPzXF 2NSg== X-Gm-Message-State: AOAM533II72dnRZUdMZQxlQ+TLv8X2DboHC3H6IOHzFOWStPFekn+TQX 2a3Zjjgp3Yy9ucmTgQ1u4ZAHhrCqXd0= X-Google-Smtp-Source: ABdhPJwrfG+aloMymP6XrOMXDTgwdqRzg63tv223sSdIP9K37czdZkdK91uLr6s5vk6QbhACcLMIKw== X-Received: by 2002:a5d:590b:: with SMTP id v11mr23814503wrd.74.1643787289095; Tue, 01 Feb 2022 23:34:49 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j5sm900576wrq.31.2022.02.01.23.34.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:48 -0800 (PST) Message-Id: <1be858e6aa64e6c04f827bf2cabe39a29283454d.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:33 +0000 Subject: [PATCH v3 07/15] merge-ort: split out a separate display_update_messages() function Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This patch includes no new code; it simply moves a bunch of lines into a new function. As such, there are no functional changes. This is just a preparatory step to allow the printed messages to be handled differently by other callers, such as in `git merge-tree --write-tree`. (Patch best viewed with --color-moved --color-moved-ws=allow-indentation-change to see that it is a simple code movement.) Signed-off-by: Elijah Newren --- merge-ort.c | 77 ++++++++++++++++++++++++++++------------------------- merge-ort.h | 8 ++++++ 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 46e72b62880..82d2faf5bf9 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4235,6 +4235,45 @@ static int record_conflicted_index_entries(struct merge_options *opt) return errs; } +void merge_display_update_messages(struct merge_options *opt, + struct merge_result *result) +{ + struct merge_options_internal *opti = result->priv; + struct hashmap_iter iter; + struct strmap_entry *e; + struct string_list olist = STRING_LIST_INIT_NODUP; + int i; + + if (opt->record_conflict_msgs_as_headers) + BUG("Either display conflict messages or record them as headers, not both"); + + trace2_region_enter("merge", "display messages", opt->repo); + + /* Hack to pre-allocate olist to the desired size */ + ALLOC_GROW(olist.items, strmap_get_size(&opti->output), + olist.alloc); + + /* Put every entry from output into olist, then sort */ + strmap_for_each_entry(&opti->output, &iter, e) { + string_list_append(&olist, e->key)->util = e->value; + } + string_list_sort(&olist); + + /* Iterate over the items, printing them */ + for (i = 0; i < olist.nr; ++i) { + struct strbuf *sb = olist.items[i].util; + + 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, stderr); + + trace2_region_leave("merge", "display messages", opt->repo); +} + void merge_switch_to_result(struct merge_options *opt, struct tree *head, struct merge_result *result, @@ -4273,42 +4312,8 @@ void merge_switch_to_result(struct merge_options *opt, trace2_region_leave("merge", "write_auto_merge", opt->repo); } - if (display_update_msgs) { - struct merge_options_internal *opti = result->priv; - struct hashmap_iter iter; - struct strmap_entry *e; - struct string_list olist = STRING_LIST_INIT_NODUP; - int i; - - if (opt->record_conflict_msgs_as_headers) - BUG("Either display conflict messages or record them as headers, not both"); - - trace2_region_enter("merge", "display messages", opt->repo); - - /* Hack to pre-allocate olist to the desired size */ - ALLOC_GROW(olist.items, strmap_get_size(&opti->output), - olist.alloc); - - /* Put every entry from output into olist, then sort */ - strmap_for_each_entry(&opti->output, &iter, e) { - string_list_append(&olist, e->key)->util = e->value; - } - string_list_sort(&olist); - - /* Iterate over the items, printing them */ - for (i = 0; i < olist.nr; ++i) { - struct strbuf *sb = olist.items[i].util; - - 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, stderr); - - trace2_region_leave("merge", "display messages", opt->repo); - } + if (display_update_msgs) + merge_display_update_messages(opt, result); merge_finalize(opt, result); } diff --git a/merge-ort.h b/merge-ort.h index fe599b87868..e5aec45b18f 100644 --- a/merge-ort.h +++ b/merge-ort.h @@ -80,6 +80,14 @@ void merge_switch_to_result(struct merge_options *opt, int update_worktree_and_index, int display_update_msgs); +/* + * Display messages about conflicts and which files were 3-way merged. + * Automatically called by merge_switch_to_result() with stream == stdout, + * so only call this when bypassing merge_switch_to_result(). + */ +void merge_display_update_messages(struct merge_options *opt, + struct merge_result *result); + /* Do needed cleanup when not calling merge_switch_to_result() */ void merge_finalize(struct merge_options *opt, struct merge_result *result); From patchwork Wed Feb 2 07:34:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732671 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3194DC433EF for ; Wed, 2 Feb 2022 07:35:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238791AbiBBHfO (ORCPT ); Wed, 2 Feb 2022 02:35:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238048AbiBBHev (ORCPT ); Wed, 2 Feb 2022 02:34:51 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47761C06173B for ; Tue, 1 Feb 2022 23:34:51 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id h21so36591240wrb.8 for ; Tue, 01 Feb 2022 23:34:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=k2ZlxCTFDYzSmpOeGJxUNf6f5dpCk/vHuvJ4srC3B9s=; b=NNrycH5fde6IEuPga/Rd70bfXihZ26z66fx/lUUjNxZcV9Wf82IPcEnZlVWJphZQXG g+tiK9Fv/fN/64CruaqL/BviNKNQONOHrQE0sSrVjh1sT59u3hXzM4ZQL+R8V+i4850f Nq4GJ7cRAHaSwAtO/sLJZQWP8MJv9W1ElhP+emWYCEQ/jjXaxr2YI5ypDckvZAMma6Ra LKVVtMGylbGqkWg3NcK4WHhlCUT40Mfb5bnsCzo7DQ2C3tWEROOCrw2gTvWmzVBcr5E9 U+CYPj0Y41l0UUByaOIdIBPKYx+1hsNwv7RiQGl0reQpj03M726VuIjiXGOX3fgqBRXS ALrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=k2ZlxCTFDYzSmpOeGJxUNf6f5dpCk/vHuvJ4srC3B9s=; b=ymFKInT86/l22xfJDU9AwcMViVcESguse/fkcy+gHL+/RiyXot4WMoyMBBcemqVt2j byNv/Zr9tJdSkp88y8UiLXYgfx42VWOLZBzNhjMFbS1FiAofSNMANNaaByEHPtxAslHJ dRMO9UJv6nJ1sv4ygfyQ7KYlL1bfYqFAF4t8ABIWIKfeL3JBr82om7seZI7YZqvjTxep 1S13ng1HCQzHmq5zc0wHxxqv6W3CoLXaQ8wslY5AR+QzS8sGwcMIHcpgHdgmEqO1cawH dbUIZnyssw2D8z6t+8S4X4fLSSohYlF2VpHJGcBxRXvsdNx0sQ+lUyhL/b3nbPKrufWj pyaA== X-Gm-Message-State: AOAM533RlhL8T2kvluQGS2Rirem101QCHEn5timjCGcY7qHTyIwJ49fO OQfflf7/bIVstvaqmkYcbmhYNqAFrf4= X-Google-Smtp-Source: ABdhPJxXuna/4CBitkgsodVIJVH4fdPa7urkrNCnIVAlQI9yXxwe9Qs+L6FsEBiBKLP4ZUzwS8ux4g== X-Received: by 2002:adf:f703:: with SMTP id r3mr24785747wrp.354.1643787289790; Tue, 01 Feb 2022 23:34:49 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c8sm4664604wmq.34.2022.02.01.23.34.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:49 -0800 (PST) Message-Id: <04c3bdc44d2c76ffc82a95db3ca4fd07270f94cf.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:34 +0000 Subject: [PATCH v3 08/15] merge-ort: allow update messages to be written to different file stream Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren This modifies the new display_update_messages() function to allow printing to somewhere other than stdout. It also consolidates the location of the diff_warn_rename_limit() message with the rest of the CONFLICT and other update messages to all go to the same stream. Signed-off-by: Elijah Newren --- merge-ort.c | 9 +++++---- merge-ort.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/merge-ort.c b/merge-ort.c index 82d2faf5bf9..d28d1721d14 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4236,7 +4236,8 @@ static int record_conflicted_index_entries(struct merge_options *opt) } void merge_display_update_messages(struct merge_options *opt, - struct merge_result *result) + struct merge_result *result, + FILE *stream) { struct merge_options_internal *opti = result->priv; struct hashmap_iter iter; @@ -4263,13 +4264,13 @@ void merge_display_update_messages(struct merge_options *opt, for (i = 0; i < olist.nr; ++i) { struct strbuf *sb = olist.items[i].util; - printf("%s", sb->buf); + strbuf_write(sb, stream); } string_list_clear(&olist, 0); /* Also include needed rename limit adjustment now */ diff_warn_rename_limit("merge.renamelimit", - opti->renames.needed_limit, 0, stderr); + opti->renames.needed_limit, 0, stream); trace2_region_leave("merge", "display messages", opt->repo); } @@ -4313,7 +4314,7 @@ void merge_switch_to_result(struct merge_options *opt, } if (display_update_msgs) - merge_display_update_messages(opt, result); + merge_display_update_messages(opt, result, stdout); merge_finalize(opt, result); } diff --git a/merge-ort.h b/merge-ort.h index e5aec45b18f..d643b47cb7c 100644 --- a/merge-ort.h +++ b/merge-ort.h @@ -86,7 +86,8 @@ void merge_switch_to_result(struct merge_options *opt, * so only call this when bypassing merge_switch_to_result(). */ void merge_display_update_messages(struct merge_options *opt, - struct merge_result *result); + struct merge_result *result, + FILE *stream); /* Do needed cleanup when not calling merge_switch_to_result() */ void merge_finalize(struct merge_options *opt, From patchwork Wed Feb 2 07:34:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732672 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FE3EC433F5 for ; Wed, 2 Feb 2022 07:35:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239094AbiBBHfP (ORCPT ); Wed, 2 Feb 2022 02:35:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239034AbiBBHez (ORCPT ); Wed, 2 Feb 2022 02:34:55 -0500 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D16EC061401 for ; Tue, 1 Feb 2022 23:34:52 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id s18so36535861wrv.7 for ; Tue, 01 Feb 2022 23:34:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ic5JyJUYhqiS8qLrTIu1x3UTrzMNVC/cJm9nrqcJlvg=; b=EVQARIicZB72pB6IV9Fgw/kfxELpVcCrqrJ76anbKn1m3eNkF7HFilaac1DAR4xsnz sE06F9E49xooRlU/yCaVbwyH+w2mAQ4PX3xpdYPFDxWvqprpUP+whbfGI+5wuEyLCWOg +/NUFVyaQXVBlA3KHLmoO5jCF9be0WMXHldy1TsnrP592BZLvtXaDrhpCTktDMrXDuql 2nnCYDa4WfZtAB4UAMMy8WQYJG55Gi7siXpR+Seyvxb2WNl7sLr3HxnpgFCdykI8o/k0 CzK+SLBiObNz3ijGX6ZdQyraKSA6Re1KWrvv20kjM0Xug2Bz0CTZXZFeofuS3wNIBTXl 76rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ic5JyJUYhqiS8qLrTIu1x3UTrzMNVC/cJm9nrqcJlvg=; b=1G1cJzBmbCH+V8anCvqdx9nUusrZAcP9DsHyXXUA9EcZ6f+eAoj3TX+hjPsjv7OncZ HdfpPQGHkO9FJFtJ3Vzwq4pWI4BAPccvoN68DPWwXoZy27V4voeaePorxsIB6AK8jwUE 6PP/UKa8IP09EyooEMqSZlePAmsNQi10BgnBmTWU4FT8ar4BUjsAPZGFRIRHYAqbP0+I z7edbkYBgoJDD1S3r8X/2LAsQs8zXYdJt1sRkLxlaDPIaw6KLi2Ztbm4vHqkI4YQ5w+2 qV1WYRgrnNSV2suekKri/zJ2097v+RmDq08vIvBm1Vj2BiFoMctgcD9BeAKIZXI3INhG oZvQ== X-Gm-Message-State: AOAM531CFWBql8Pl3BAmpNtxmDZAp2AyabJHsntO0d3i8ky61oSC/yN0 SUtX51jzw5WKx9CkYHqFWmV7j73nwuA= X-Google-Smtp-Source: ABdhPJzzH3FR/WYFhCgLOuvB19BTepQhtuxTxsVKG3y33sIsjLMzVWOuJer2AVlYo89VYkU2mNDK1g== X-Received: by 2002:a5d:5343:: with SMTP id t3mr24949231wrv.521.1643787290780; Tue, 01 Feb 2022 23:34:50 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g6sm16038755wrq.97.2022.02.01.23.34.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:50 -0800 (PST) Message-Id: In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:35 +0000 Subject: [PATCH v3 09/15] merge-tree: support including merge messages in output Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren When running `git merge-tree --write-tree`, we previously would only return an exit status reflecting the cleanness of a merge, and print out the toplevel tree of the resulting merge. Merges also have informational messages, such as: * "Auto-merging " * "CONFLICT (content): ..." * "CONFLICT (file/directory)" * etc. In fact, when non-content conflicts occur (such as file/directory, modify/delete, add/add with differing modes, rename/rename (1to2), etc.), these informational messages may be the only notification the user gets since these conflicts are not representable in the contents of the file. Add a --[no-]messages option so that callers can request these messages be included at the end of the output. Include such messages by default when there are conflicts, and omit them by default when the merge is clean. Signed-off-by: Elijah Newren --- Documentation/git-merge-tree.txt | 45 +++++++++++++++++++++++++++----- builtin/merge-tree.c | 19 ++++++++++++-- t/t4301-merge-tree-write-tree.sh | 21 +++++++++++++++ 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 569485815a0..42e0f8f6183 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -9,7 +9,7 @@ git-merge-tree - Perform merge without touching index or working tree SYNOPSIS -------- [verse] -'git merge-tree' [--write-tree] +'git merge-tree' [--write-tree] [] 'git merge-tree' [--trivial-merge] (deprecated) DESCRIPTION @@ -35,17 +35,47 @@ merge is distinguished from a trivial merge in that it includes: After the merge completes, it will create a new toplevel tree object. See `OUTPUT` below for details. +OPTIONS +------- + +--[no-]messages:: + Write any informational messages such as "Auto-merging " + or CONFLICT notices to the end of stdout. If unspecified, the + default is to include these messages if there are merge + conflicts, and to omit them otherwise. + OUTPUT ------ -For either a successful or conflicted merge, the output from -git-merge-tree is simply one line: +By default, for a successful merge, the output from git-merge-tree is +simply one line: + + + +Whereas for a conflicted merge, the output is by default of the form: + + +These are discussed individually below. + +OID of toplevel tree +~~~~~~~~~~~~~~~~~~~~ + +This is a tree object that represents what would be checked out in the +working tree at the end of `git merge`. If there were conflicts, then +files within this tree may have embedded conflict markers. + +Informational messages +~~~~~~~~~~~~~~~~~~~~~~ + +This always starts with a blank line to separate it from the previous +section, and then has free-form messages about the merge, such as: -The printed tree object corresponds to what would be checked out in -the working tree at the end of `git merge`, and thus may have files -with conflict markers in them. + * "Auto-merging " + * "CONFLICT (rename/delete): renamed...but deleted in..." + * "Failed to merge submodule ()" + * "Warning: cannot merge binary files: " EXIT STATUS ----------- @@ -69,7 +99,8 @@ be used as a part of a series of steps such as However, it does not quite fit into the same category of low-level plumbing commands since the possibility of merge conflicts give it a -much higher chance of the command not succeeding. +much higher chance of the command not succeeding (and NEWTREE containing +a bunch of stuff other than just a toplevel tree). GIT --- diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index d14c9f6e44e..6a556ab1c9c 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -390,6 +390,7 @@ static int trivial_merge(const char *base, struct merge_tree_options { int mode; + int show_messages; }; static int real_merge(struct merge_tree_options *o, @@ -432,18 +433,27 @@ static int real_merge(struct merge_tree_options *o, merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result); if (result.clean < 0) die(_("failure to merge")); + + if (o->show_messages == -1) + o->show_messages = !result.clean; + puts(oid_to_hex(&result.tree->object.oid)); + if (o->show_messages) { + printf("\n"); + merge_display_update_messages(&opt, &result, stdout); + } merge_finalize(&opt, &result); return !result.clean; /* result.clean < 0 handled above */ } int cmd_merge_tree(int argc, const char **argv, const char *prefix) { - struct merge_tree_options o = { 0 }; + struct merge_tree_options o = { .show_messages = -1 }; int expected_remaining_argc; + int original_argc; const char * const merge_tree_usage[] = { - N_("git merge-tree [--write-tree] "), + N_("git merge-tree [--write-tree] [] "), N_("git merge-tree [--trivial-merge] "), NULL }; @@ -453,10 +463,13 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) 'w'), OPT_CMDMODE(0, "trivial-merge", &o.mode, N_("do a trivial merge only"), 't'), + OPT_BOOL(0, "messages", &o.show_messages, + N_("also show informational/conflict messages")), OPT_END() }; /* Parse arguments */ + original_argc = argc; argc = parse_options(argc, argv, prefix, mt_options, merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (o.mode) { @@ -468,6 +481,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) usage_with_options(merge_tree_usage, mt_options); o.mode = (argc == 2 ? 'w' : 't'); } + if (o.mode == 't' && original_argc < argc) + die(_("--trivial-merge is incompatible with all other options")); /* Do the relevant type of merge */ if (o.mode == 'w') diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index 66c3eaf2021..e2255711f9c 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -85,4 +85,25 @@ test_expect_success 'Barf on too many arguments' ' grep "^usage: git merge-tree" expect ' +test_expect_success 'test conflict notices and such' ' + test_expect_code 1 git merge-tree --write-tree side1 side2 >out && + sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && + + # Expected results: + # "greeting" should merge with conflicts + # "numbers" should merge cleanly + # "whatever" has *both* a modify/delete and a file/directory conflict + cat <<-EOF >expect && + HASH + + Auto-merging greeting + CONFLICT (content): Merge conflict in greeting + Auto-merging numbers + CONFLICT (file/directory): directory in the way of whatever from side1; moving it to whatever~side1 instead. + CONFLICT (modify/delete): whatever~side1 deleted in side2 and modified in side1. Version side1 of whatever~side1 left in tree. + EOF + + test_cmp expect actual +' + test_done From patchwork Wed Feb 2 07:34:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732676 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84525C433FE for ; Wed, 2 Feb 2022 07:35:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238277AbiBBHfW (ORCPT ); Wed, 2 Feb 2022 02:35:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239560AbiBBHfG (ORCPT ); Wed, 2 Feb 2022 02:35:06 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53AF8C061755 for ; Tue, 1 Feb 2022 23:34:53 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id s9so36528893wrb.6 for ; Tue, 01 Feb 2022 23:34:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=PlInyUqRBx0ASPfJ5p3RLGlX6fpaPltpQjbFbwbFWcs=; b=hHijD8mFatRRSzvkW76yjJRTSUcUNNqh98UN2FBZl0fl8Ch2ytDGd5IVC/aZqWv1DE AQs19QQS6VWjXbtRDdvDGG7vHG2835LCOLoFLQU5b7/eBNfvQaJlC1HcDZEYJShFt9jJ CGBNI5rliBhnsN4G6faooFcSIsFP46aX/LRx7JKoXzRjVepa+fvLqr7UGi/g7pv395UN h2I+Id1HJOmAXq5BEN2IHDUFealCSkaPTrkxbxdBtdvv+8+ugwOEaK0UMyz1rVLLg6GT JLanSkRW3lMsv6U6vyODsvaYKcsj9Mx3VAcKyJIF3tZY1M/cyyLB7TLsoc7R8zFRMqb9 zSJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=PlInyUqRBx0ASPfJ5p3RLGlX6fpaPltpQjbFbwbFWcs=; b=L08bfQOjaFLTr9M0HphZQjCAQzOvA2rPkEVB6HObflUrlRFn9wxGk0GA8wLfG30IGA voXySCIETtSi7mPf/5cCQ6q2Xk0q86Biw7LqyjF9x/r9ojjwkqU0TFP7e7m1ro/I31oD 1DHU587T3kheSgAuZBrZFZnjHqhiCighsKVOWB0c17YL/M2flj/0WeabWCa/sPuEqz5C RWpmoLTOXFUji0e61qniG+G3rbq0ZLyI0Ac8lezpMjyxevJ+37lO8WcvAoFYOesJVVWR A2OCMPehnlLk9qM4VjyiHNYYEV1HgYWxdIKaNMg8bc3awauLqvAip7QNbJd56AEpaHXx 8B2g== X-Gm-Message-State: AOAM532yfbf03HwhiWt/Qc0wN409DOS0ceVg4V9pyZFnkFEc5NtTIy5o 1Jy7ydj2O9PWRvr0R0DEsKyOqlKUt58= X-Google-Smtp-Source: ABdhPJySzK4rxhT9r+C9b7LxwtecuENaMTIBoEfy5b2jfja8DEDNkHfi+Ft+5pOr7Bz1KFyBjhU6cw== X-Received: by 2002:a5d:5450:: with SMTP id w16mr24486530wrv.44.1643787291783; Tue, 01 Feb 2022 23:34:51 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i3sm16184981wru.33.2022.02.01.23.34.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:51 -0800 (PST) Message-Id: <1c2a3f5ef63cbc8ac5a61c97e42cc4cce55ee663.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:36 +0000 Subject: [PATCH v3 10/15] merge-ort: provide a merge_get_conflicted_files() helper function Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren After a merge, this function allows the user to extract the same information that would be printed by `ls-files -u`, which means files with their mode, oid, and stage. Signed-off-by: Elijah Newren --- merge-ort.c | 31 +++++++++++++++++++++++++++++++ merge-ort.h | 21 +++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/merge-ort.c b/merge-ort.c index d28d1721d14..c4ce6027dc4 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -4275,6 +4275,37 @@ void merge_display_update_messages(struct merge_options *opt, trace2_region_leave("merge", "display messages", opt->repo); } +void merge_get_conflicted_files(struct merge_result *result, + struct string_list *conflicted_files) +{ + struct hashmap_iter iter; + struct strmap_entry *e; + struct merge_options_internal *opti = result->priv; + + strmap_for_each_entry(&opti->conflicted, &iter, e) { + const char *path = e->key; + struct conflict_info *ci = e->value; + int i; + + VERIFY_CI(ci); + + for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) { + struct stage_info *si; + + if (!(ci->filemask & (1ul << i))) + continue; + + si = xmalloc(sizeof(*si)); + si->stage = i+1; + si->mode = ci->stages[i].mode; + oidcpy(&si->oid, &ci->stages[i].oid); + string_list_append(conflicted_files, path)->util = si; + } + } + /* string_list_sort() uses a stable sort, so we're good */ + string_list_sort(conflicted_files); +} + void merge_switch_to_result(struct merge_options *opt, struct tree *head, struct merge_result *result, diff --git a/merge-ort.h b/merge-ort.h index d643b47cb7c..e635a294ea8 100644 --- a/merge-ort.h +++ b/merge-ort.h @@ -2,6 +2,7 @@ #define MERGE_ORT_H #include "merge-recursive.h" +#include "hash.h" struct commit; struct tree; @@ -89,6 +90,26 @@ void merge_display_update_messages(struct merge_options *opt, struct merge_result *result, FILE *stream); +struct stage_info { + struct object_id oid; + int mode; + int stage; +}; + +/* + * Provide a list of path -> {struct stage_info*} mappings for + * all conflicted files. Note that each path could appear up to three + * times in the list, corresponding to 3 different stage entries. In short, + * this basically provides the info that would be printed by `ls-files -u`. + * + * result should have been populated by a call to + * one of the merge_incore_[non]recursive() functions. + * + * conflicted_files should be empty before calling this function. + */ +void merge_get_conflicted_files(struct merge_result *result, + struct string_list *conflicted_files); + /* Do needed cleanup when not calling merge_switch_to_result() */ void merge_finalize(struct merge_options *opt, struct merge_result *result); From patchwork Wed Feb 2 07:34:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5F69C433EF for ; Wed, 2 Feb 2022 07:35:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240047AbiBBHf0 (ORCPT ); Wed, 2 Feb 2022 02:35:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239626AbiBBHfH (ORCPT ); Wed, 2 Feb 2022 02:35:07 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12F7AC061758 for ; Tue, 1 Feb 2022 23:34:54 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id k18so36620441wrg.11 for ; Tue, 01 Feb 2022 23:34:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=QUAEoi4aLmkdvqTyeW5+zkc86dJRK8t2CDOBRn9/dKI=; b=FXhwF2jSpNA1viXxQZoFozvXsl1UKQUJt9evkVGTHOlf8lSocG/PQLeLbUeeP/H3wL I/pTD0yo0DOm/prjCXYGcxIiuXsLhOVXz8hkMhQmaF+eqHQvLhdAs1mxWn0aGVg8mVxN ++yd8bGCATJz0jxhKfv/GGbAkwvZ7Xtq2up1xKOpREHkZ8Pf15n66NObiCSXQ3Mu6IyQ V5xoyJ5WqFhTKXJ9wQ2n5cVDV9TcF5aRVooLv151f4addsPc4UzgZ7wbNJqb1LJbUJs2 ADf19BiZAqzkndo0fcr5cCSpnHBKyFcZHBD3nxpWz31yaPs4fVBYgj95eqqFw/RNpat7 51qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=QUAEoi4aLmkdvqTyeW5+zkc86dJRK8t2CDOBRn9/dKI=; b=di/1SI2d0+YWZjHLAmTI3/g6mr3IHRuGQvbVNfga+SxNVksQGHPQCWIv56ZaSDen3H Q7SpdQp/Z2mEZH3m6Qpr945vrLHuBt22ufyeUbAfZuGz5XWBWdcrldMFVUWGoy5sDM46 lfKzdIDh0z7XyX5xLj+HMxegv+ftNTK1H+zMVOYKiRzN9Fa1/b8Q7+fKPQniUqQWDE3K eVIh0xkacmgHviR3drubXB/s74mAj7BA4mgk7px1k7d4aql6uDDx9EftBl7vyibkGMKd nlnZy98FziR1Gznhqce7M+YnwsuTI0Y4yKGkV9J8BqzlrlXQBujug+HOlCPqBEdaKQgs Q3mA== X-Gm-Message-State: AOAM532KanTRh7aYSWWY67D84K7KJDhzC/lljVxK+Jr2CSrBhzoEavgl TnEDl1s7oLj9U07bF2NqOSfOzefgeYs= X-Google-Smtp-Source: ABdhPJzWZ0yANo40okGvCsttWGlZefHp3JRRJDG+LIO6bBaNCoGZjz5clSnMZRMONxVZB+VmB/djXA== X-Received: by 2002:a5d:65ce:: with SMTP id e14mr24683392wrw.245.1643787292531; Tue, 01 Feb 2022 23:34:52 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k12sm16547609wrd.98.2022.02.01.23.34.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:52 -0800 (PST) Message-Id: <9c2389eef0e7c8813e0522011132d7f5e530d858.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:37 +0000 Subject: [PATCH v3 11/15] merge-tree: provide a list of which files have conflicts Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Callers of `git merge-tree --write-tree` will often want to know which files had conflicts. While they could potentially attempt to parse the CONFLICT notices printed, those messages are not meant to be machine readable. Provide a simpler mechanism of just printing the files (in the same format as `git ls-files` with quoting, but restricted to unmerged files) in the output before the free-form messages. Signed-off-by: Elijah Newren --- Documentation/git-merge-tree.txt | 8 ++++++++ builtin/merge-tree.c | 24 ++++++++++++++++++++++-- t/t4301-merge-tree-write-tree.sh | 11 +++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 42e0f8f6183..160e8f44b62 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -55,6 +55,7 @@ simply one line: Whereas for a conflicted merge, the output is by default of the form: + These are discussed individually below. @@ -66,6 +67,13 @@ This is a tree object that represents what would be checked out in the working tree at the end of `git merge`. If there were conflicts, then files within this tree may have embedded conflict markers. +Conflicted file list +~~~~~~~~~~~~~~~~~~~~ + +This is a sequence of lines containing a filename on each line, quoted +as explained for the configuration variable `core.quotePath` (see +linkgit:git-config[1]). + Informational messages ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 6a556ab1c9c..54dae018203 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -11,6 +11,9 @@ #include "blob.h" #include "exec-cmd.h" #include "merge-blobs.h" +#include "quote.h" + +static int line_termination = '\n'; struct merge_list { struct merge_list *next; @@ -394,7 +397,8 @@ struct merge_tree_options { }; static int real_merge(struct merge_tree_options *o, - const char *branch1, const char *branch2) + const char *branch1, const char *branch2, + const char *prefix) { struct commit *parent1, *parent2; struct commit_list *common; @@ -438,6 +442,22 @@ static int real_merge(struct merge_tree_options *o, o->show_messages = !result.clean; puts(oid_to_hex(&result.tree->object.oid)); + if (!result.clean) { + struct string_list conflicted_files = STRING_LIST_INIT_NODUP; + const char *last = NULL; + int i; + + merge_get_conflicted_files(&result, &conflicted_files); + for (i = 0; i < conflicted_files.nr; i++) { + const char *name = conflicted_files.items[i].string; + if (last && !strcmp(last, name)) + continue; + write_name_quoted_relative( + name, prefix, stdout, line_termination); + last = name; + } + string_list_clear(&conflicted_files, 1); + } if (o->show_messages) { printf("\n"); merge_display_update_messages(&opt, &result, stdout); @@ -486,7 +506,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) /* Do the relevant type of merge */ if (o.mode == 'w') - return real_merge(&o, argv[0], argv[1]); + return real_merge(&o, argv[0], argv[1], prefix); else return trivial_merge(argv[0], argv[1], argv[2]); } diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index e2255711f9c..7113d060bc5 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -95,6 +95,8 @@ test_expect_success 'test conflict notices and such' ' # "whatever" has *both* a modify/delete and a file/directory conflict cat <<-EOF >expect && HASH + greeting + whatever~side1 Auto-merging greeting CONFLICT (content): Merge conflict in greeting @@ -106,4 +108,13 @@ test_expect_success 'test conflict notices and such' ' test_cmp expect actual ' +test_expect_success 'Just the conflicted files without the messages' ' + test_expect_code 1 git merge-tree --write-tree --no-messages side1 side2 >out && + sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && + + test_write_lines HASH greeting whatever~side1 >expect && + + test_cmp expect actual +' + test_done From patchwork Wed Feb 2 07:34:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732678 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4A8CC433EF for ; Wed, 2 Feb 2022 07:35:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240383AbiBBHf2 (ORCPT ); Wed, 2 Feb 2022 02:35:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239775AbiBBHfI (ORCPT ); Wed, 2 Feb 2022 02:35:08 -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 E2B4CC06175C for ; Tue, 1 Feb 2022 23:34:54 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id k6-20020a05600c1c8600b003524656034cso3262998wms.2 for ; Tue, 01 Feb 2022 23:34:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=4vpK7gvSSTnnlTHW028zn/66BNp2/IopKxZgoFX/3Ek=; b=m9zIqm9GYNfkjsOB2hqOSbb/Y0GE/saa5LcIlOcZG0dSHzf88hZZlXQ30+IkJOwPMb x5zWGwouk5WadZj/CvkO8Vml1/1SzqDqJcQgR4zJ5S1B7Yv3/YHJOrrvjtk9tG8by3n7 tPGcj3rfq8Yx1Hx8Msv6ay5NgomDWdsAV/dIJsp9nbW3VtEOISaBmenMna5x4NbmTYF4 VEZbbbqXC+C7eqMnYD36NZoJ54iYDcEeL4UkBGT16Rvr9MjWodfgZBbhhG54nPNUgvuD vCMrz507A2qtf7aZslbmcclhhG1/5KaaEmfzY8pkGgzV5IVb2bOg8Femg5WwSGjbjy5V Hk0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=4vpK7gvSSTnnlTHW028zn/66BNp2/IopKxZgoFX/3Ek=; b=T1QejF9c13eB9fqtNcaA96rtGVuKr5MvTbz5QV/ID/15vTlKKPYhdizquWWFnDd4ZG 5n4jsBYWRi+QK36JWL0tRkSiwxYuZeqjLBur0J4s8qK2LORnixAUdLoHmWeDsxiR0doy 54DwH7KQovwlFjvNZR0UEYjxbgGanUUjwv/MDqjdK8A4eIvi793aVhDe/JK5lbg6RriX kEKaU7zrnpt5PkV8oCEh3GpnFve4BGv2hClWS6ituGNfQxSELtAuPNqaKYg2EKzqRCPP Xu+Qb1adE9oITH1btjHejAVbKSQFkjbUpGk/WIzPb3XXfTh4XUTDCKaoEPwUAkv/HhJx yZyQ== X-Gm-Message-State: AOAM532C4i9uvVt7j68tMVcrZn/T73dV0FWr5CGFuiMVyxC3tFvxMkbg MWwJODtbF9wWTMwcKg6KbWCLt+xi9k4= X-Google-Smtp-Source: ABdhPJxVmqV9/4EVogYJQIVK0wR+2uk4gEBAybkAp49SbNzk90yA+wYTop6F78DU0TyeYsrsVlISAQ== X-Received: by 2002:a1c:7416:: with SMTP id p22mr4945718wmc.30.1643787293332; Tue, 01 Feb 2022 23:34:53 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o2sm4148212wmq.21.2022.02.01.23.34.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:52 -0800 (PST) Message-Id: <2188a8ca1e77f2f5f8249f8b810775205ad529a6.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:38 +0000 Subject: [PATCH v3 12/15] merge-tree: provide easy access to `ls-files -u` style info Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Much like `git merge` updates the index with information of the form (mode, oid, stage, name) provide this output for conflicted files for merge-tree as well. Provide an --exclude-modes-oids-stages/-l option for users to exclude the mode, oid, and stage and only get the list of conflicted filenames. Signed-off-by: Elijah Newren --- Documentation/git-merge-tree.txt | 30 ++++++++++++++++++++++++------ builtin/merge-tree.c | 11 ++++++++++- t/t4301-merge-tree-write-tree.sh | 26 ++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 160e8f44b62..55bb7bc61c1 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -38,6 +38,11 @@ See `OUTPUT` below for details. OPTIONS ------- +--exclude-oids-and-modes:: + Instead of writing a list of (mode, oid, stage, path) tuples + to output for conflicted files, just provide a list of + filenames with conflicts. + --[no-]messages:: Write any informational messages such as "Auto-merging " or CONFLICT notices to the end of stdout. If unspecified, the @@ -55,7 +60,7 @@ simply one line: Whereas for a conflicted merge, the output is by default of the form: - + These are discussed individually below. @@ -67,18 +72,23 @@ This is a tree object that represents what would be checked out in the working tree at the end of `git merge`. If there were conflicts, then files within this tree may have embedded conflict markers. -Conflicted file list +Conflicted file info ~~~~~~~~~~~~~~~~~~~~ -This is a sequence of lines containing a filename on each line, quoted -as explained for the configuration variable `core.quotePath` (see -linkgit:git-config[1]). +This is a sequence of lines with the format + + + +The filename will be quoted as explained for the configuration +variable `core.quotePath` (see linkgit:git-config[1]). However, if +the `--exclude-oids-and-modes` option is passed, the mode, object, and +stage will be omitted. Informational messages ~~~~~~~~~~~~~~~~~~~~~~ This always starts with a blank line to separate it from the previous -section, and then has free-form messages about the merge, such as: +sections, and then has free-form messages about the merge, such as: * "Auto-merging " * "CONFLICT (rename/delete): renamed...but deleted in..." @@ -110,6 +120,14 @@ plumbing commands since the possibility of merge conflicts give it a much higher chance of the command not succeeding (and NEWTREE containing a bunch of stuff other than just a toplevel tree). +git-merge-tree was written to provide users with the same information +that they'd have access to if using `git merge`: + * what would be written to the working tree (the ) + * the higher order stages that would be written to the index (the + ) + * any messages that would have been printed to stdout (the ) + GIT --- Part of the linkgit:git[1] suite diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 54dae018203..dc52cd02dce 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -394,6 +394,7 @@ static int trivial_merge(const char *base, struct merge_tree_options { int mode; int show_messages; + int exclude_modes_oids_stages; }; static int real_merge(struct merge_tree_options *o, @@ -450,7 +451,11 @@ static int real_merge(struct merge_tree_options *o, merge_get_conflicted_files(&result, &conflicted_files); for (i = 0; i < conflicted_files.nr; i++) { const char *name = conflicted_files.items[i].string; - if (last && !strcmp(last, name)) + struct stage_info *c = conflicted_files.items[i].util; + if (!o->exclude_modes_oids_stages) + printf("%06o %s %d\t", + c->mode, oid_to_hex(&c->oid), c->stage); + else if (last && !strcmp(last, name)) continue; write_name_quoted_relative( name, prefix, stdout, line_termination); @@ -485,6 +490,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) N_("do a trivial merge only"), 't'), OPT_BOOL(0, "messages", &o.show_messages, N_("also show informational/conflict messages")), + OPT_BOOL_F('l', "exclude-modes-oids-stages", + &o.exclude_modes_oids_stages, + N_("list conflicted files without modes/oids/stages"), + PARSE_OPT_NONEG), OPT_END() }; diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index 7113d060bc5..1572f460da0 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -47,6 +47,7 @@ test_expect_success 'Content merge and a few conflicts' ' expected_tree=$(cat .git/AUTO_MERGE) && # We will redo the merge, while we are still in a conflicted state! + git ls-files -u >conflicted-file-info && test_when_finished "git reset --hard" && test_expect_code 1 git merge-tree --write-tree side1 side2 >RESULT && @@ -86,7 +87,7 @@ test_expect_success 'Barf on too many arguments' ' ' test_expect_success 'test conflict notices and such' ' - test_expect_code 1 git merge-tree --write-tree side1 side2 >out && + test_expect_code 1 git merge-tree --write-tree --exclude-modes-oids-stages side1 side2 >out && sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && # Expected results: @@ -109,7 +110,7 @@ test_expect_success 'test conflict notices and such' ' ' test_expect_success 'Just the conflicted files without the messages' ' - test_expect_code 1 git merge-tree --write-tree --no-messages side1 side2 >out && + test_expect_code 1 git merge-tree --write-tree --no-messages --exclude-modes-oids-stages side1 side2 >out && sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && test_write_lines HASH greeting whatever~side1 >expect && @@ -117,4 +118,25 @@ test_expect_success 'Just the conflicted files without the messages' ' test_cmp expect actual ' +test_expect_success 'Check conflicted oids and modes without messages' ' + test_expect_code 1 git merge-tree --write-tree --no-messages side1 side2 >out && + sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && + + # Compare the basic output format + q_to_tab >expect <<-\EOF && + HASH + 100644 HASH 1Qgreeting + 100644 HASH 2Qgreeting + 100644 HASH 3Qgreeting + 100644 HASH 1Qwhatever~side1 + 100644 HASH 2Qwhatever~side1 + EOF + + test_cmp expect actual && + + # Check the actual hashes against the `ls-files -u` output too + tail -n +2 out | sed -e s/side1/HEAD/ >actual && + test_cmp conflicted-file-info actual +' + test_done From patchwork Wed Feb 2 07:34:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732673 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A0CCC433EF for ; Wed, 2 Feb 2022 07:35:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239311AbiBBHfR (ORCPT ); Wed, 2 Feb 2022 02:35:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240047AbiBBHfJ (ORCPT ); Wed, 2 Feb 2022 02:35:09 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3E70C061760 for ; Tue, 1 Feb 2022 23:34:55 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id v123so14537786wme.2 for ; Tue, 01 Feb 2022 23:34:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ob2Mrmg1rskHNmkAusKEMik4COjQ1FXYLgs6bVr8714=; b=OJYk8uwwx00QhdwTnht5I1HQ0OTADo5LLPe6vhUEBUFNeb0n5mkeCM2Di6gwrm/tlX sNmvACO8B38okrmKV1haMRlUzHSJc0ZhmdyQc4SQKEQxfitpC4DpHud1CUR6LwJTys54 WIiVahoq4m1qTCBbRbKJNaC9gkQcMkJM4Hs+2LCI1RFPmRruqj90Sfr5T46a6OC/mubg f07lahla6wx5zkJzQk5/Y50UuOlMINp+o51SdUFQ96DNAXViQuEFMknbvUrEi0rLXlKi 4pbmZDYxa+x91uIk+2CUi1hWMuH/PctUQ/igS19gxYF2CFO0Fckn1HacKT0Qq2iYVpib Xd7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ob2Mrmg1rskHNmkAusKEMik4COjQ1FXYLgs6bVr8714=; b=TLEIp1e9J7gLf0qGjP2TfEZMMDzW5wyT8raRh0CmWudx9dLAB3lM6LFdc8AAlcU49K IueOE0jutcmQFBZMvoOjN8cDrASqz7s2Ke53PrE2cXWZip281h/rc5qxdLM8s7ReyOkB 6niNI0R1qJ/eO2BkQepNvjbABdJFTapKpGertqbZbw67peWAzofrC8dK9mBhntthatVh KrCANQ6wxWeK8JYPaPVfpO4EKss4KZ1mA6Epv09G6JcHKIv8wvBSMDBjtYSTZ6JYNqsT jei9O+hPKcXuh0T7ONJD224DT7c0cPCFGx0w9Q4lE2+tAJfODBDxb/b4pRs0/NTS9A/Y 29FQ== X-Gm-Message-State: AOAM530692Zq7b2jSnYXOo65vYvzw8uXfdTxYXg2lQcReOVGwOMEb20k XK35kMX0hXN+X/QaGQ3MruBDCngQ8Vs= X-Google-Smtp-Source: ABdhPJzXgAQyCNvarRfrszeY4B2AdFlowXxq6vpLK1n8xLjonJ9Se0jSdSrbV+FgXCrGTPv2tzRE2w== X-Received: by 2002:a05:600c:3b90:: with SMTP id n16mr4813448wms.178.1643787294081; Tue, 01 Feb 2022 23:34:54 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x6sm19486293wrn.18.2022.02.01.23.34.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:53 -0800 (PST) Message-Id: <52339b396fac6c3ae7a7dfa42d4d2d6eccc4ede7.1643787281.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:39 +0000 Subject: [PATCH v3 13/15] merge-tree: allow `ls-files -u` style info to be NUL terminated Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Much as `git ls-files` has a -z option, let's add one to merge-tree so that the conflict-info section can be NUL terminated (and avoid quoting of unusual filenames). Signed-off-by: Elijah Newren --- Documentation/git-merge-tree.txt | 21 +++++++++++++---- builtin/merge-tree.c | 4 +++- t/t4301-merge-tree-write-tree.sh | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 55bb7bc61c1..02f766716f9 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -38,6 +38,12 @@ See `OUTPUT` below for details. OPTIONS ------- +-z:: + Do not quote filenames in the section, + and end each filename with a NUL character rather than + newline. Also begin the messages section with a NUL character + instead of a newline. See OUTPUT below for more information. + --exclude-oids-and-modes:: Instead of writing a list of (mode, oid, stage, path) tuples to output for conflicted files, just provide a list of @@ -70,7 +76,8 @@ OID of toplevel tree This is a tree object that represents what would be checked out in the working tree at the end of `git merge`. If there were conflicts, then -files within this tree may have embedded conflict markers. +files within this tree may have embedded conflict markers. This section +is always followed by a newline. Conflicted file info ~~~~~~~~~~~~~~~~~~~~ @@ -82,19 +89,25 @@ This is a sequence of lines with the format The filename will be quoted as explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). However, if the `--exclude-oids-and-modes` option is passed, the mode, object, and -stage will be omitted. +stage will be omitted. If `-z` is passed, the "lines" are terminated +by a NUL character instead of a newline character. Informational messages ~~~~~~~~~~~~~~~~~~~~~~ -This always starts with a blank line to separate it from the previous -sections, and then has free-form messages about the merge, such as: +This always starts with a blank line (or NUL if `-z` is passed) to +separate it from the previous sections, and then has free-form +messages about the merge, such as: * "Auto-merging " * "CONFLICT (rename/delete): renamed...but deleted in..." * "Failed to merge submodule ()" * "Warning: cannot merge binary files: " +Note that these free-form messages will never have a NUL character +in or between them, even if -z is passed. It is simply a large block +of text taking up the remainder of the output. + EXIT STATUS ----------- diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index dc52cd02dce..7e55f0fa301 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -464,7 +464,7 @@ static int real_merge(struct merge_tree_options *o, string_list_clear(&conflicted_files, 1); } if (o->show_messages) { - printf("\n"); + putchar(line_termination); merge_display_update_messages(&opt, &result, stdout); } merge_finalize(&opt, &result); @@ -490,6 +490,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) N_("do a trivial merge only"), 't'), OPT_BOOL(0, "messages", &o.show_messages, N_("also show informational/conflict messages")), + OPT_SET_INT('z', NULL, &line_termination, + N_("separate paths with the NUL character"), '\0'), OPT_BOOL_F('l', "exclude-modes-oids-stages", &o.exclude_modes_oids_stages, N_("list conflicted files without modes/oids/stages"), diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index 1572f460da0..f89d87c26b7 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -139,4 +139,44 @@ test_expect_success 'Check conflicted oids and modes without messages' ' test_cmp conflicted-file-info actual ' +test_expect_success 'NUL terminated conflicted file "lines"' ' + git checkout -b tweak1 side1 && + test_write_lines zero 1 2 3 4 5 6 >numbers && + git add numbers && + git mv numbers "Αυτά μου φαίνονται κινέζικα" && + git commit -m "Renamed numbers" && + + test_expect_code 1 git merge-tree --write-tree -z tweak1 side2 >out && + sed -e "s/[0-9a-f]\{40,\}/HASH/g" out >actual && + + # Expected results: + # "greeting" should merge with conflicts + # "whatever" has *both* a modify/delete and a file/directory conflict + # "Αυτά μου φαίνονται κινέζικα" should have a conflict + echo HASH >expect && + + q_to_tab <<-EOF | lf_to_nul >>expect && + 100644 HASH 1Qgreeting + 100644 HASH 2Qgreeting + 100644 HASH 3Qgreeting + 100644 HASH 1Qwhatever~tweak1 + 100644 HASH 2Qwhatever~tweak1 + 100644 HASH 1QΑυτά μου φαίνονται κινέζικα + 100644 HASH 2QΑυτά μου φαίνονται κινέζικα + 100644 HASH 3QΑυτά μου φαίνονται κινέζικα + + EOF + + cat <<-EOF >>expect && + Auto-merging greeting + CONFLICT (content): Merge conflict in greeting + CONFLICT (file/directory): directory in the way of whatever from tweak1; moving it to whatever~tweak1 instead. + CONFLICT (modify/delete): whatever~tweak1 deleted in side2 and modified in tweak1. Version tweak1 of whatever~tweak1 left in tree. + Auto-merging Αυτά μου φαίνονται κινέζικα + CONFLICT (content): Merge conflict in Αυτά μου φαίνονται κινέζικα + EOF + + test_cmp expect actual +' + test_done From patchwork Wed Feb 2 07:34:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732674 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 114FFC433F5 for ; Wed, 2 Feb 2022 07:35:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239334AbiBBHfU (ORCPT ); Wed, 2 Feb 2022 02:35:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240083AbiBBHfJ (ORCPT ); Wed, 2 Feb 2022 02:35:09 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F856C061763 for ; Tue, 1 Feb 2022 23:34:56 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id h21so36591560wrb.8 for ; Tue, 01 Feb 2022 23:34:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=6P8p3UrrMLUBxcnuyQxuozseE287fxxGacDfprCvR48=; b=ItN+4O4b0ln5iMNA6pawn/Su0MSgqMTXGTShPlGK01zH6T4jqwrrui4LpGuco/GxX0 4AXQB7PCpo0rq/82DD0CsQnUW4kMPDeeijMYL77mvHX+OpuXf++Wm90pLY5qtqueWPVR kzt4n0of1ym33pEW9azE4gcsJ+mlAzv6vLFp6j5J9TX8tYGG4x9UNGqMHIBLMeuMomh5 Xi+a/rUmbZnjfDdr9k7ac2hhfhaxodyqcKj6JuePdbuSGsx81H3p5nwFoVhFQ+2rocck zLdLpN5bTLdvig7Aq2+nifcb/4V8rM21SPbuED5caK8kWN6Ynx31whIwqTdWj5F2PoWQ Vlaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=6P8p3UrrMLUBxcnuyQxuozseE287fxxGacDfprCvR48=; b=Hr4V/+vbJ/5wWaWynRxGxHKGu98jpgBwGcZAF0JNauYPkYGDRc8j2bzLXiEbFT+QLD SdFPUH9jpu/duA/KFgHcvKYVCFVsWyrQCw1T7Gi+akV1U+H+3oCePxvwlnch5kf8Rvgt 2EkzTX/etDYjeQ2fzdTIqYia+A6y4NO85wy+eZyhcnkpcssIVqVl2GLqn9W9tiD6rUvT UJlOT9QBmZlFlVDP8b8LhNbsvuntkJA6zf4zXm0LKpu/11BcRPdEm1vlWIIxpCQgEVCh jCAYh5vOCi9yNjxP9K4XTrnxkI4N83QwPdeY57b/C3V3R1QAqGIn8Eu8J5SyAegCqzRn OLgw== X-Gm-Message-State: AOAM530h2CSSOh7fPU5yAQ7Ei9eTMix6usNeXBcXnxxK3eAsnHm84S/X sZnzArjvPHSrVtGgLed78uD/GvVWWnA= X-Google-Smtp-Source: ABdhPJxLwUP73nI3sgHLdsPuu+BwCOcnEDr+/30W9C9b/NUwD9pWN8iJJk3nS8yqV+EerG9naa1kBw== X-Received: by 2002:a5d:64c4:: with SMTP id f4mr25142039wri.278.1643787294889; Tue, 01 Feb 2022 23:34:54 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i6sm3838873wma.22.2022.02.01.23.34.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:54 -0800 (PST) Message-Id: In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:40 +0000 Subject: [PATCH v3 14/15] merge-tree: add a --allow-unrelated-histories flag Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , Elijah Newren , Elijah Newren Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren From: Elijah Newren Folks may want to merge histories that have no common ancestry; provide a flag with the same name as used by `git merge` to allow this. Signed-off-by: Elijah Newren --- Documentation/git-merge-tree.txt | 5 +++++ builtin/merge-tree.c | 7 ++++++- t/t4301-merge-tree-write-tree.sh | 24 +++++++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 02f766716f9..e6a9ff2768b 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -55,6 +55,11 @@ OPTIONS default is to include these messages if there are merge conflicts, and to omit them otherwise. +--allow-unrelated-histories:: + merge-tree will by default error out if the two branches specified + share no common history. This flag can be given to override that + check and make the merge proceed anyway. + OUTPUT ------ diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 7e55f0fa301..58c0ddc5a32 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -393,6 +393,7 @@ static int trivial_merge(const char *base, struct merge_tree_options { int mode; + int allow_unrelated_histories; int show_messages; int exclude_modes_oids_stages; }; @@ -430,7 +431,7 @@ static int real_merge(struct merge_tree_options *o, * merge_incore_recursive in merge-ort.h */ common = get_merge_bases(parent1, parent2); - if (!common) + if (!common && !o->allow_unrelated_histories) die(_("refusing to merge unrelated histories")); for (j = common; j; j = j->next) commit_list_insert(j->item, &merge_bases); @@ -496,6 +497,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) &o.exclude_modes_oids_stages, N_("list conflicted files without modes/oids/stages"), PARSE_OPT_NONEG), + OPT_BOOL_F(0, "allow-unrelated-histories", + &o.allow_unrelated_histories, + N_("allow merging unrelated histories"), + PARSE_OPT_NONEG), OPT_END() }; diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index f89d87c26b7..4de089d976d 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -38,7 +38,13 @@ test_expect_success setup ' >whatever/empty && git add numbers greeting whatever/empty && test_tick && - git commit -m other-modifications + git commit -m other-modifications && + + git switch --orphan unrelated && + >something-else && + git add something-else && + test_tick && + git commit -m first-commit ' test_expect_success 'Content merge and a few conflicts' ' @@ -179,4 +185,20 @@ test_expect_success 'NUL terminated conflicted file "lines"' ' test_cmp expect actual ' +test_expect_success 'error out by default for unrelated histories' ' + test_expect_code 128 git merge-tree --write-tree side1 unrelated 2>error && + + grep "refusing to merge unrelated histories" error +' + +test_expect_success 'can override merge of unrelated histories' ' + git merge-tree --write-tree --allow-unrelated-histories side1 unrelated >tree && + TREE=$(cat tree) && + + git rev-parse side1:numbers side1:greeting side1:whatever unrelated:something-else >expect && + git rev-parse $TREE:numbers $TREE:greeting $TREE:whatever $TREE:something-else >actual && + + test_cmp expect actual +' + test_done From patchwork Wed Feb 2 07:34:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elijah Newren X-Patchwork-Id: 12732675 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA158C433EF for ; Wed, 2 Feb 2022 07:35:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239508AbiBBHfW (ORCPT ); Wed, 2 Feb 2022 02:35:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239137AbiBBHfJ (ORCPT ); Wed, 2 Feb 2022 02:35:09 -0500 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26A27C061768 for ; Tue, 1 Feb 2022 23:34:57 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id f17so36592185wrx.1 for ; Tue, 01 Feb 2022 23:34:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=6SVI/G9lzVJsL+RL6mpaPU8pp+ZN1o5bN2bojCFt7TM=; b=F8YSo2Dia7SGLichN7oLY2NSAPE/mBCZ1g80iFDMfj3iBVMzp1DF2nQpLTUHltSFju Ca/XCtnf0rrfvSnJnCxiT38mPYNquSXpX65XFSk6HETqUv8dSHphDVQlZPvS6mtDqoGd pbgUcR3icu20HplAYnbr/Y8AvOYU05t/AvmEsu6pvYthQX6Exo5PTrwvCiqQC1WMljSL XwB1pEnDDWGgYKfUnPJMg7CJRFFO7jlNF0zADiJTKKKdDjDrehBhFqyFyQBzO65KF8BP YwFsH7mk6L+Agzdw3Tsj8W4QUWsG2Qo9kbDXQ4cyfPQRkrgRzAwxBaIqzmBGMu0YpisG Zvvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=6SVI/G9lzVJsL+RL6mpaPU8pp+ZN1o5bN2bojCFt7TM=; b=17e1pWTHmftbSAgrNRxAAFhzIERK3Jfktfzv/z/xKTm0lO1xB8Ditq5zplKUS1reE3 UcNx50dtDxAcXkvZSutcurO1mQuvso+sDIbUI3lN0996wXLI93+Nv0ytk6R+q/2fAgRr 87ZE3CWhD7w1wSaZLJWiBWh8o0fCb8Nn3bmMSqr3OSG6GQ215i2vor7RgW2LnAJijORI 0cwSN54HqnTdt5+NDFpdpxEKbsdMru6m3GUs6Lm9ug+vcGIOYC78s7SHELyduTXkF9rU nBWsmH8u1Cs4SDINgFi4yMmUm7UFRz1AYcuOTBI/YHo1SOaYsV0Tdj2zGzbHBtdU82wx yYgQ== X-Gm-Message-State: AOAM533DAriijh/krTPWc/f37peKCeiKLyiyurGcL7qZDCKAhdU+Jpo0 VQGyc0mDZsgSZNcKfgEf94lP4DVQvuw= X-Google-Smtp-Source: ABdhPJz+t9qXdqX6FsNhGQqlKdyYysjauTkY6qo+hPAsdamcIlGbGl9u0hTzCLQkdyiHgwy+IXgSeA== X-Received: by 2002:a5d:5583:: with SMTP id i3mr24826553wrv.411.1643787295636; Tue, 01 Feb 2022 23:34:55 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h6sm4055564wmq.26.2022.02.01.23.34.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Feb 2022 23:34:55 -0800 (PST) Message-Id: In-Reply-To: References: Date: Wed, 02 Feb 2022 07:34:41 +0000 Subject: [PATCH v3 15/15] git-merge-tree.txt: add a section on potentional usage mistakes Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Christian Couder , Taylor Blau , Johannes Altmanninger , Ramsay Jones , Johannes Schindelin , Christian Couder , =?utf-8?b?UmVuw6k=?= Scharfe , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7A=?= Bjarmason , Elijah Newren , Johannes Sixt , 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 --- Documentation/git-merge-tree.txt | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index e6a9ff2768b..6a2ed475106 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -146,6 +146,52 @@ that they'd have access to if using `git merge`: * any messages that would have been printed to stdout (the ) +MISTAKES TO AVOID +----------------- + +Do NOT look through the resulting toplevel tree to try to find which +files conflict; parse the section instead. Not +only would parsing an entire tree be horrendously slow in large +repositories, there are numerous types of conflicts not representable by +conflict markers (modify/delete, mode conflict, binary file changed on +both sides, file/directory conflicts, various rename conflict +permutations, etc.) + +Do NOT interpret an empty list as a clean merge; +check the exit status. A merge can have conflicts without having +individual files conflict (there are a few types of directory rename +conflicts that fall into this category, and others might also be added +in the future). + +Do NOT attempt to guess or make the user guess the conflict types from +the list. The information there is insufficient +to do so. For example: Rename/rename(1to2) conflicts (both sides +renamed the same file differently) will result in three different file +having higher order stages (but each only has one higher order stage), +with no way (short of the section) to determine +which three files are related. File/directory conflicts also result in +a file with exactly one higher order stage. +Possibly-involved-in-directory-rename conflicts (when +"merge.directoryRenames" is unset or set to "conflicts") also result in +a file with exactly one higher order stage. In all cases, the + section has the necessary info, though it is +not designed to be machine parseable. + +Do NOT assume all filenames listed in the +section had conflicts. Messages can be included for files that have no +conflicts, such as "Auto-merging ". + +AVOID taking the OIDS from the and re-merging +them to present the conflicts to the user. This will lose information. +Instead, look up the version of the file found within the and show that instead. In particular, the latter will +have conflict markers annotated with the original branch/commit being +merged and, if renames were involved, the original filename. While you +could include the original branch/commit in the conflict marker +annotations when re-merging, the original filename is not available from +the and thus you would be losing information that +might help the user resolve the conflict. + GIT --- Part of the linkgit:git[1] suite