From patchwork Mon Mar 20 05:59:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Henrie X-Patchwork-Id: 13180744 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 96D08C76195 for ; Mon, 20 Mar 2023 06:00:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229511AbjCTGAK (ORCPT ); Mon, 20 Mar 2023 02:00:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229486AbjCTGAH (ORCPT ); Mon, 20 Mar 2023 02:00:07 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F26EB1CBD7 for ; Sun, 19 Mar 2023 23:00:05 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id lr16-20020a17090b4b9000b0023f187954acso11210776pjb.2 for ; Sun, 19 Mar 2023 23:00:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679292005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mG0Eh42iXR92/z6npu4aNTODQkar2R2pkU5LgoUXoUQ=; b=VurweSm2MJdaJdodbdvCtiIcyNDpDnYaA54bAWG1TUhEuWMNtkgwFO/ILPlPXIQzKo BXEoSmav2sCJCF2/dAvE44Gcd0P7RQKz4ZV3XqdeDSsdqEj/nnbXab5ruYZ52fNHSn0E Wy/Zy1cCtE09S/qgJ5X6LLgKBCANMHPy6kqESJsf8ZamNAdmb5w8P4KIqKp9kXulc2f5 bVZmsREqyRVbWkYC8hSY9KPbmpHhv50OzWAezVXK8JPvCqD6J05qkce/IE06HAvg3egK JnPndn8KGp2P1nW5n41xKlfXxAGVOzSaEr3ZPRp0SLhfghieEHJtV32FB7fBEI5f/TP/ DT0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679292005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mG0Eh42iXR92/z6npu4aNTODQkar2R2pkU5LgoUXoUQ=; b=2bnojGdH/ig/RTASCs1TivT9UBkr5TEmRb8mvvIr5oTMNaXDb25QHWYFlQ7zeUEOKw QM1HyhEpQXzGSZa3FP0B1Yn/ks8VmRP3OhZT8c+8ER0+QVO/SAPmDpPAUuRg1Ct78rIb aOn8s6tuFBuB6+8w6mDfyBuLnQE++qSr7wq/T28SqKtn8k/c956t7c/wJGsfIXbSCes0 UNe9SzyVCEzcHFRSJuMW7dZ6gjZnNZoyyZymaHT/82LhR19+Y4Zt2JUnR3gzMURFcRHa pJ+5dZB+118HQAyIfvM5PndrrDbfOzeZ14fduee2DLG7ZlImn1rcLr2/5famlHhKVQ+o vEvg== X-Gm-Message-State: AO0yUKWGOmK3LPIgCK3GxT6ZW7O1SvxI+cuEW14bPHrlHLTN7Oeo6Gdk 0ANuAMi45X+kt0qPbiE554c2fgbxepmJgg== X-Google-Smtp-Source: AK7set/+MCljcX01pSqCU1FOiSvdDSP2aLvIu0SqxHIuBXKtjahj8ta4M1N93UDfbY5uFawrMSMfmQ== X-Received: by 2002:a17:90b:4a49:b0:23d:4241:af0 with SMTP id lb9-20020a17090b4a4900b0023d42410af0mr18822491pjb.3.1679292005206; Sun, 19 Mar 2023 23:00:05 -0700 (PDT) Received: from xavier.lan ([2607:fa18:92fe:92b::2a2]) by smtp.gmail.com with ESMTPSA id cc13-20020a17090af10d00b002353082958csm7814075pjb.10.2023.03.19.23.00.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 23:00:04 -0700 (PDT) From: Alex Henrie To: git@vger.kernel.org, tao@klerks.biz, gitster@pobox.com, newren@gmail.com, phillip.wood123@gmail.com, Johannes.Schindelin@gmx.de, sorganov@gmail.com, chooglen@google.com, calvinwan@google.com, jonathantanmy@google.com, felipe.contreras@gmail.com Cc: Alex Henrie Subject: [PATCH v8 1/3] rebase: add documentation and test for --no-rebase-merges Date: Sun, 19 Mar 2023 23:59:53 -0600 Message-Id: <20230320055955.461138-2-alexhenrie24@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230320055955.461138-1-alexhenrie24@gmail.com> References: <20230312210456.92364-1-alexhenrie24@gmail.com> <20230320055955.461138-1-alexhenrie24@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org As far as I can tell, --no-rebase-merges has always worked, but has never been documented. It is especially important to document it before a rebase.rebaseMerges option is introduced so that users know how to override the config option on the command line. It's also important to clarify that --rebase-merges without an argument is not the same as --no-rebase-merges and not passing --rebase-merges is not the same as passing --rebase-merges=no-rebase-cousins. A test case is necessary to make sure that --no-rebase-merges keeps working after its code is refactored in the following patches of this series. The test case is a little contrived: It's unlikely that a user would type both --rebase-merges and --no-rebase-merges at the same time. However, if an alias is defined which includes --rebase-merges, the user might decide to add --no-rebase-merges to countermand that part of the alias but leave alone other flags set by the alias. Signed-off-by: Alex Henrie --- Documentation/git-rebase.txt | 18 +++++++++++------- t/t3430-rebase-merges.sh | 10 ++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 9a295bcee4..4e57a87624 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -529,20 +529,24 @@ See also INCOMPATIBLE OPTIONS below. -r:: --rebase-merges[=(rebase-cousins|no-rebase-cousins)]:: +--no-rebase-merges:: By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a single, linear branch. With `--rebase-merges`, the rebase will instead try to preserve the branching structure within the commits that are to be rebased, by recreating the merge commits. Any resolved merge conflicts or manual amendments in these merge commits will have to be - resolved/re-applied manually. + resolved/re-applied manually. `--no-rebase-merges` can be used to + countermand a previous `--rebase-merges`. + -By default, or when `no-rebase-cousins` was specified, commits which do not -have `` as direct ancestor will keep their original branch point, -i.e. commits that would be excluded by linkgit:git-log[1]'s -`--ancestry-path` option will keep their original ancestry by default. If -the `rebase-cousins` mode is turned on, such commits are instead rebased -onto `` (or ``, if specified). +When rebasing merges, there are two modes: `rebase-cousins` and +`no-rebase-cousins`. If the mode is not specified, it defaults to +`no-rebase-cousins`. In `no-rebase-cousins` mode, commits which do not have +`` as direct ancestor will keep their original branch point, i.e. +commits that would be excluded by linkgit:git-log[1]'s `--ancestry-path` +option will keep their original ancestry by default. In `rebase-cousins` mode, +such commits are instead rebased onto `` (or ``, if +specified). + It is currently only possible to recreate the merge commits using the `ort` merge strategy; different merge strategies can be used only via diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index fa2a06c19f..d46d9545f2 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -250,6 +250,16 @@ test_expect_success 'with a branch tip that was cherry-picked already' ' EOF ' +test_expect_success '--no-rebase-merges countermands --rebase-merges' ' + git checkout -b no-rebase-merges E && + git rebase --rebase-merges --no-rebase-merges C && + test_cmp_graph C.. <<-\EOF + * B + * D + o C + EOF +' + test_expect_success 'do not rebase cousins unless asked for' ' git checkout -b cousins main && before="$(git rev-parse --verify HEAD)" && From patchwork Mon Mar 20 05:59:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Henrie X-Patchwork-Id: 13180745 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 2D55CC7618A for ; Mon, 20 Mar 2023 06:00:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229639AbjCTGAO (ORCPT ); Mon, 20 Mar 2023 02:00:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229446AbjCTGAI (ORCPT ); Mon, 20 Mar 2023 02:00:08 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 024581CAFE for ; Sun, 19 Mar 2023 23:00:08 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id ja10so11337973plb.5 for ; Sun, 19 Mar 2023 23:00:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679292007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5OcqydCjhMDY5jspeKXxXjsJOwU6BQ4iAns2dmsHl9w=; b=WLxhPCqIRxrEANLlXcHLZIsQ0AldEiwO5TvIvwFwiIioDE4q/u/aM+WOZyEEBNM1Nu A/gGe08xs5LORKkjNO7D29etwpLt8i6rxVlyhDIr6ldu/1bpRtIRwJIBrv25iHHHkhC6 qnqmbbDwBYepRofb9nkh0mVO9G4v7s1Yl0ZGMR1zrZbfyJZzfzpvyK+LYWWz3/lAvS/Y bc4hqOzl1oQMvXcftkrS2zq1DkYZXc8QdwesKxpT4+i2Jc2qrOWkhvRdL5gBxF+ttSMc r5S5ZPZW7+CwMHKSDwN6M98rbRl8qC2hBX0FsaQW+sVQ3fr2v7zhg30FN4vfLKuuiCtu QTKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679292007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5OcqydCjhMDY5jspeKXxXjsJOwU6BQ4iAns2dmsHl9w=; b=QA0mpcDbAkGOZowPqFY7iVwfLaPewH5rIoCZQQRBTixsE0FrGmm0+o8ZROTQIReHB7 sqXWWpRtdDk8/AIzGISXaQstr2VrffNfTyy2vsPOOx7CkYXqxJ5kSyPEvjMpFa9RS2d+ rTFThLj8eusocv6oxdcBj7ISMG8Nxp4X8hYWbQIZcnfr4rdTiGFeDXs7IVabRvKpYj8c awvvh42nzNbRYt9QE2QmFB7VwVovgasii7V16qzGoq5r76EiYsrOhb3hf7eqpxLsdf6b puj7jvyxnf7dAmOeIsMAVHwR/pGE4a+efBfe197r/b0zVH101J9Lspr0UxMJD973klbW Qwzg== X-Gm-Message-State: AO0yUKWbz7h5edAOe37OoslYPMHluRVZELEHXTiUqZWAy3INUSuUxDOi Bn1JLQ0Lyi56exhkOro3rwMGshmaOA7QKQ== X-Google-Smtp-Source: AK7set84NBE4Tw+VuoORAPGuvSJChq92AH+iNq5Dh3JXOh00mnHkoH5+Hp2JH3zLwGLd40J4zUSBOw== X-Received: by 2002:a17:90b:1b06:b0:23f:8752:98be with SMTP id nu6-20020a17090b1b0600b0023f875298bemr6952001pjb.4.1679292007201; Sun, 19 Mar 2023 23:00:07 -0700 (PDT) Received: from xavier.lan ([2607:fa18:92fe:92b::2a2]) by smtp.gmail.com with ESMTPSA id cc13-20020a17090af10d00b002353082958csm7814075pjb.10.2023.03.19.23.00.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 23:00:06 -0700 (PDT) From: Alex Henrie To: git@vger.kernel.org, tao@klerks.biz, gitster@pobox.com, newren@gmail.com, phillip.wood123@gmail.com, Johannes.Schindelin@gmx.de, sorganov@gmail.com, chooglen@google.com, calvinwan@google.com, jonathantanmy@google.com, felipe.contreras@gmail.com Cc: Alex Henrie Subject: [PATCH v8 2/3] rebase: deprecate --rebase-merges="" Date: Sun, 19 Mar 2023 23:59:54 -0600 Message-Id: <20230320055955.461138-3-alexhenrie24@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230320055955.461138-1-alexhenrie24@gmail.com> References: <20230312210456.92364-1-alexhenrie24@gmail.com> <20230320055955.461138-1-alexhenrie24@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The unusual syntax --rebase-merges="" (that is, --rebase-merges with an empty string argument) has been an undocumented synonym of --rebase-merges without an argument. Deprecate that syntax to avoid confusion when a rebase.rebaseMerges config option is introduced, where rebase.rebaseMerges="" will be equivalent to --no-rebase-merges. It is not likely that anyone is actually using this syntax, but just in case, deprecate the empty string argument instead of dropping support for it immediately. Signed-off-by: Alex Henrie --- builtin/rebase.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/builtin/rebase.c b/builtin/rebase.c index dd31d5ab91..4b3f29a449 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1141,7 +1141,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) {OPTION_STRING, 'r', "rebase-merges", &rebase_merges, N_("mode"), N_("try to rebase merges instead of skipping them"), - PARSE_OPT_OPTARG, NULL, (intptr_t)""}, + PARSE_OPT_OPTARG, NULL, (intptr_t)"no-rebase-cousins"}, OPT_BOOL(0, "fork-point", &options.fork_point, N_("use 'merge-base --fork-point' to refine upstream")), OPT_STRING('s', "strategy", &options.strategy, @@ -1439,7 +1439,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (rebase_merges) { if (!*rebase_merges) - ; /* default mode; do nothing */ + warning(_("--rebase-merges with an empty string " + "argument is deprecated and will stop " + "working in a future version of Git. Use " + "--rebase-merges without an argument " + "instead, which does the same thing.")); else if (!strcmp("rebase-cousins", rebase_merges)) options.rebase_cousins = 1; else if (strcmp("no-rebase-cousins", rebase_merges)) From patchwork Mon Mar 20 05:59:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Henrie X-Patchwork-Id: 13180746 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 8A4A0C6FD1D for ; Mon, 20 Mar 2023 06:00:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229635AbjCTGAQ (ORCPT ); Mon, 20 Mar 2023 02:00:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229493AbjCTGAM (ORCPT ); Mon, 20 Mar 2023 02:00:12 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 739DD1CAFF for ; Sun, 19 Mar 2023 23:00:09 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id iw3so11330429plb.6 for ; Sun, 19 Mar 2023 23:00:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679292008; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=07ldifHYPVkaWQtQFeZnG/t/tyD/rJuc3VqSBBl5sjo=; b=Xt2qSZ9TXyDS+WpjsK6pTR5HJCZw7qLDDC60ddTrq1ORMqSS1oLHudEToTJRNbJiGP 1y4rMDRfcBYAssVZCRWWwgN3oNYmJ4Zp4RTSZPKGDYtZ5PNDNI+q43D1UH/eNg10dVrF qUmloAT+iI83e652DV5Db4OpNmr2s3l7tS2lrQdjLhDdzvHzDpneHMCJXbn9TIjtYVsJ XIUh2s35uN3mOhVbM3j25h3PElIk3zQsrm2yamw1givgXv3h+1wxgPsFqYVjI6GlC8at 7jAh0I+EEuboEPPIbItBoylijvU1iN1cYFW8+T2NEao7WVO2zwd1EiORnJ2RsrjeAfi8 YPAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679292008; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=07ldifHYPVkaWQtQFeZnG/t/tyD/rJuc3VqSBBl5sjo=; b=T0kzsLREjHpPjH32RUTpNuh4z/qx78m8oU4tGYTbEpHNChO5pLqtazwvuo3hlnAmCT WVd7ZPvR6Wvk0PJn9qZp6uLnZBmY5lyUvxbu5c91TE8GSAV1fmD7HsFmA8Nwhk3cFBUs Xcx+RVB1VLG5FkZ4SSRyaCeHLWi1EeoD0CpuXwOUL0c/x2siaMm48Ckg+CWTZrksuHQB koSNTrGxsNwAKcCh2kP8d0V1ZDmnASGZa9oEiBl3+/uA79Kh4OtQUIcYa19QVgtxNRDM 42t1ISfRLQscUgdyp3K2mTUKkP3bOHiULucRqZ7HPlqtKIjOYbGRxB+ScujEJWDu8iCi vswQ== X-Gm-Message-State: AO0yUKVHN8L6r+DCinQ5fpVT/VJzrhLz9Uu07rL5LnmmBq5GSwPxTeRW zY37n21FZcvrLtUEZ2xT0NOyTX3XsOZmuQ== X-Google-Smtp-Source: AK7set9dNHOmbQqNZFRkEwcm+2IlAwopwbU2OnHVjdtg31aBoWu3zHN5CPzmQQxXEMkJEA2fkZRxCw== X-Received: by 2002:a17:90b:1a8a:b0:23f:4370:2c67 with SMTP id ng10-20020a17090b1a8a00b0023f43702c67mr13981359pjb.26.1679292008597; Sun, 19 Mar 2023 23:00:08 -0700 (PDT) Received: from xavier.lan ([2607:fa18:92fe:92b::2a2]) by smtp.gmail.com with ESMTPSA id cc13-20020a17090af10d00b002353082958csm7814075pjb.10.2023.03.19.23.00.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 23:00:08 -0700 (PDT) From: Alex Henrie To: git@vger.kernel.org, tao@klerks.biz, gitster@pobox.com, newren@gmail.com, phillip.wood123@gmail.com, Johannes.Schindelin@gmx.de, sorganov@gmail.com, chooglen@google.com, calvinwan@google.com, jonathantanmy@google.com, felipe.contreras@gmail.com Cc: Alex Henrie Subject: [PATCH v8 3/3] rebase: add a config option for --rebase-merges Date: Sun, 19 Mar 2023 23:59:55 -0600 Message-Id: <20230320055955.461138-4-alexhenrie24@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230320055955.461138-1-alexhenrie24@gmail.com> References: <20230312210456.92364-1-alexhenrie24@gmail.com> <20230320055955.461138-1-alexhenrie24@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The purpose of the new option is to accommodate users who would like --rebase-merges to be on by default and to facilitate turning on --rebase-merges by default without configuration in a future version of Git. Name the new option rebase.rebaseMerges, even though it is a little redundant, for consistency with the name of the command line option and to be clear when scrolling through values in the [rebase] section of .gitconfig. Support setting rebase.rebaseMerges to the nonspecific value "true" for users who don't need to or don't want to learn about the difference between rebase-cousins and no-rebase-cousins. Make --rebase-merges without an argument on the command line override any value of rebase.rebaseMerges in the configuration, for consistency with other command line flags with optional arguments that have an associated config option. Signed-off-by: Alex Henrie --- Documentation/config/rebase.txt | 10 ++++ Documentation/git-rebase.txt | 3 +- builtin/rebase.c | 81 ++++++++++++++++++-------- t/t3422-rebase-incompatible-options.sh | 17 ++++++ t/t3430-rebase-merges.sh | 34 +++++++++++ 5 files changed, 121 insertions(+), 24 deletions(-) diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt index f19bd0e040..afaf6dad99 100644 --- a/Documentation/config/rebase.txt +++ b/Documentation/config/rebase.txt @@ -67,3 +67,13 @@ rebase.rescheduleFailedExec:: rebase.forkPoint:: If set to false set `--no-fork-point` option by default. + +rebase.rebaseMerges:: + Whether and how to set the `--rebase-merges` option by default. Can + be `rebase-cousins`, `no-rebase-cousins`, or a boolean. Setting to + true or to `no-rebase-cousins` is equivalent to + `--rebase-merges=no-rebase-cousins`, setting to `rebase-cousins` is + equivalent to `--rebase-merges=rebase-cousins`, and setting to false is + equivalent to `--no-rebase-merges`. Passing `--rebase-merges` on the + command line, with or without an argument, overrides any + `rebase.rebaseMerges` configuration. diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 4e57a87624..e7b39ad244 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -537,7 +537,8 @@ See also INCOMPATIBLE OPTIONS below. by recreating the merge commits. Any resolved merge conflicts or manual amendments in these merge commits will have to be resolved/re-applied manually. `--no-rebase-merges` can be used to - countermand a previous `--rebase-merges`. + countermand both the `rebase.rebaseMerges` config option and a previous + `--rebase-merges`. + When rebasing merges, there are two modes: `rebase-cousins` and `no-rebase-cousins`. If the mode is not specified, it defaults to diff --git a/builtin/rebase.c b/builtin/rebase.c index 4b3f29a449..fd284e24ab 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -124,6 +124,7 @@ struct rebase_options { int fork_point; int update_refs; int config_autosquash; + int config_rebase_merges; int config_update_refs; }; @@ -141,6 +142,8 @@ struct rebase_options { .allow_empty_message = 1, \ .autosquash = -1, \ .config_autosquash = -1, \ + .rebase_merges = -1, \ + .config_rebase_merges = -1, \ .update_refs = -1, \ .config_update_refs = -1, \ } @@ -772,6 +775,16 @@ static int run_specific_rebase(struct rebase_options *opts) return status ? -1 : 0; } +static void parse_rebase_merges_value(struct rebase_options *options, const char *value) +{ + if (!strcmp("no-rebase-cousins", value)) + options->rebase_cousins = 0; + else if (!strcmp("rebase-cousins", value)) + options->rebase_cousins = 1; + else + die(_("Unknown rebase-merges mode: %s"), value); +} + static int rebase_config(const char *var, const char *value, void *data) { struct rebase_options *opts = data; @@ -801,6 +814,16 @@ static int rebase_config(const char *var, const char *value, void *data) return 0; } + if (!strcmp(var, "rebase.rebasemerges")) { + opts->config_rebase_merges = git_parse_maybe_bool(value); + if (opts->config_rebase_merges < 0) { + opts->config_rebase_merges = 1; + parse_rebase_merges_value(opts, value); + } else + opts->rebase_cousins = 0; + return 0; + } + if (!strcmp(var, "rebase.updaterefs")) { opts->config_update_refs = git_config_bool(var, value); return 0; @@ -981,6 +1004,28 @@ static int parse_opt_empty(const struct option *opt, const char *arg, int unset) return 0; } +static int parse_opt_rebase_merges(const struct option *opt, const char *arg, int unset) +{ + struct rebase_options *options = opt->value; + + options->rebase_merges = !unset; + options->rebase_cousins = 0; + + if (arg) { + if (!*arg) { + warning(_("--rebase-merges with an empty string " + "argument is deprecated and will stop " + "working in a future version of Git. Use " + "--rebase-merges without an argument " + "instead, which does the same thing.")); + return 0; + } + parse_rebase_merges_value(options, arg); + } + + return 0; +} + static void NORETURN error_on_missing_default_upstream(void) { struct branch *current_branch = branch_get(NULL); @@ -1036,7 +1081,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) struct object_id branch_base; int ignore_whitespace = 0; const char *gpg_sign = NULL; - const char *rebase_merges = NULL; struct string_list strategy_options = STRING_LIST_INIT_NODUP; struct object_id squash_onto; char *squash_onto_name = NULL; @@ -1138,10 +1182,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) &options.allow_empty_message, N_("allow rebasing commits with empty messages"), PARSE_OPT_HIDDEN), - {OPTION_STRING, 'r', "rebase-merges", &rebase_merges, - N_("mode"), + OPT_CALLBACK_F('r', "rebase-merges", &options, N_("mode"), N_("try to rebase merges instead of skipping them"), - PARSE_OPT_OPTARG, NULL, (intptr_t)"no-rebase-cousins"}, + PARSE_OPT_OPTARG, parse_opt_rebase_merges), OPT_BOOL(0, "fork-point", &options.fork_point, N_("use 'merge-base --fork-point' to refine upstream")), OPT_STRING('s', "strategy", &options.strategy, @@ -1437,21 +1480,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.exec.nr) imply_merge(&options, "--exec"); - if (rebase_merges) { - if (!*rebase_merges) - warning(_("--rebase-merges with an empty string " - "argument is deprecated and will stop " - "working in a future version of Git. Use " - "--rebase-merges without an argument " - "instead, which does the same thing.")); - else if (!strcmp("rebase-cousins", rebase_merges)) - options.rebase_cousins = 1; - else if (strcmp("no-rebase-cousins", rebase_merges)) - die(_("Unknown mode: %s"), rebase_merges); - options.rebase_merges = 1; - imply_merge(&options, "--rebase-merges"); - } - if (options.type == REBASE_APPLY) { if (ignore_whitespace) strvec_push(&options.git_am_opts, @@ -1514,13 +1542,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) break; if (i >= 0 || options.type == REBASE_APPLY) { - if (is_merge(&options)) - die(_("apply options and merge options " - "cannot be used together")); - else if (options.autosquash == -1 && options.config_autosquash == 1) + if (options.autosquash == -1 && options.config_autosquash == 1) die(_("apply options are incompatible with rebase.autoSquash. Consider adding --no-autosquash")); + else if (options.rebase_merges == -1 && options.config_rebase_merges == 1) + die(_("apply options are incompatible with rebase.rebaseMerges. Consider adding --no-rebase-merges")); else if (options.update_refs == -1 && options.config_update_refs == 1) die(_("apply options are incompatible with rebase.updateRefs. Consider adding --no-update-refs")); + else if (is_merge(&options)) + die(_("apply options and merge options " + "cannot be used together")); else options.type = REBASE_APPLY; } @@ -1531,6 +1561,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) options.update_refs = (options.update_refs >= 0) ? options.update_refs : ((options.config_update_refs >= 0) ? options.config_update_refs : 0); + if (options.rebase_merges == 1) + imply_merge(&options, "--rebase-merges"); + options.rebase_merges = (options.rebase_merges >= 0) ? options.rebase_merges : + ((options.config_rebase_merges >= 0) ? options.config_rebase_merges : 0); + if (options.autosquash == 1) imply_merge(&options, "--autosquash"); options.autosquash = (options.autosquash >= 0) ? options.autosquash : diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh index 4711b37a28..2eba00bdf5 100755 --- a/t/t3422-rebase-incompatible-options.sh +++ b/t/t3422-rebase-incompatible-options.sh @@ -85,6 +85,11 @@ test_rebase_am_only () { test_must_fail git rebase $opt --reapply-cherry-picks A " + test_expect_success "$opt incompatible with --rebase-merges" " + git checkout B^0 && + test_must_fail git rebase $opt --rebase-merges A + " + test_expect_success "$opt incompatible with --update-refs" " git checkout B^0 && test_must_fail git rebase $opt --update-refs A @@ -101,6 +106,12 @@ test_rebase_am_only () { grep -e --no-autosquash err " + test_expect_success "$opt incompatible with rebase.rebaseMerges" " + git checkout B^0 && + test_must_fail git -c rebase.rebaseMerges=true rebase $opt A 2>err && + grep -e --no-rebase-merges err + " + test_expect_success "$opt incompatible with rebase.updateRefs" " git checkout B^0 && test_must_fail git -c rebase.updateRefs=true rebase $opt A 2>err && @@ -113,6 +124,12 @@ test_rebase_am_only () { git -c rebase.autosquash=true rebase --no-autosquash $opt A " + test_expect_success "$opt okay with overridden rebase.rebaseMerges" " + test_when_finished \"git reset --hard B^0\" && + git checkout B^0 && + git -c rebase.rebaseMerges=true rebase --no-rebase-merges $opt A + " + test_expect_success "$opt okay with overridden rebase.updateRefs" " test_when_finished \"git reset --hard B^0\" && git checkout B^0 && diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index d46d9545f2..f03599c63b 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -278,6 +278,40 @@ test_expect_success 'do not rebase cousins unless asked for' ' EOF ' +test_expect_success 'rebase.rebaseMerges=rebase-cousins is equivalent to --rebase-merges=rebase-cousins' ' + test_config rebase.rebaseMerges rebase-cousins && + git checkout -b config-rebase-cousins main && + git rebase HEAD^ && + test_cmp_graph HEAD^.. <<-\EOF + * Merge the topic branch '\''onebranch'\'' + |\ + | * D + | * G + |/ + o H + EOF +' + +test_expect_success '--no-rebase-merges overrides rebase.rebaseMerges=no-rebase-cousins' ' + test_config rebase.rebaseMerges no-rebase-cousins && + git checkout -b override-config-no-rebase-cousins E && + git rebase --no-rebase-merges C && + test_cmp_graph C.. <<-\EOF + * B + * D + o C + EOF +' + +test_expect_success '--rebase-merges overrides rebase.rebaseMerges=rebase-cousins' ' + test_config rebase.rebaseMerges rebase-cousins && + git checkout -b override-config-rebase-cousins E && + before="$(git rev-parse --verify HEAD)" && + test_tick && + git rebase --rebase-merges C && + test_cmp_rev HEAD $before +' + test_expect_success 'refs/rewritten/* is worktree-local' ' git worktree add wt && cat >wt/script-from-scratch <<-\EOF &&