From patchwork Fri Apr 7 07:24:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204517 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 2969FC76196 for ; Fri, 7 Apr 2023 07:25:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239769AbjDGHZL (ORCPT ); Fri, 7 Apr 2023 03:25:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55874 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239663AbjDGHZH (ORCPT ); Fri, 7 Apr 2023 03:25:07 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4B5986B9 for ; Fri, 7 Apr 2023 00:24:54 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id y14so41638919wrq.4 for ; Fri, 07 Apr 2023 00:24:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852283; 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=GbkG0ugDsYqPtwGXpVzrHvuf+dTdaWeGHc1rAH7NQgM=; b=VssbmRbc+N7iRVxe4E/VYmJQ2SzrRLm+4JrAo3ZnukeC/EIJo0wiSuj5Q7MUgfxTw4 Q7JYq2j+Q2YmaNjX1daIUDBaIXR0+CmDtVflpVsqZL4fQMylwIuF2k2fxhP7ktgFzzO7 Z6gIaZAi3NHCw0RN8v1jKHAgajL+1gE5kmFZ8cJgwiy2VBQCSqJd1goBF3RnLQ72a/7j Usre2vxaaVGJ7Mx7U74V8qxIbZA855NVd+NzvTD0/1jpp7SwnDWzcUZec6/hSj+wqnWK oscAw3slJVss5XtHFv18EIUxholg0q7qLhccBu2981Ac5G2C7xinG2nDIAv/AgsYTsu7 AH5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852283; 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=GbkG0ugDsYqPtwGXpVzrHvuf+dTdaWeGHc1rAH7NQgM=; b=mXqEAu2/JYkuqxpc0gPH4fjzmChJeFtnvOz0+0RzQg0rtnzS4SVElLiCGWZQMJ4Ztl V6wx6In20abisP343MojrWXj443a/uhe+jJvTF//6tjoAVUBd1kyqIaZ80pVEuw7u+Pj 8BtQUsmOmsP2hUy3Dpd/Tc68aUuNAFpwHbWuVAnORMan1k8RfY9LXzFhakf/URoIjxSo yrQ9e9k2UcpJYm+SpUUXOMp/c2RXCWNIuFTmxEEwGzOs/LbH8kPGG47TKqdxovmaWAOv EH7FfDOHJlftx+6IvrP6aXn05YJhmqEFPA6wgjniDeUdjs+32IDLAEFZDsX1dF5lUWWL PpCw== X-Gm-Message-State: AAQBX9fA11pF1Lk2QM29oKBl8D7/mvlXtr0bhAaADEjlrExNr4sSX/0+ ks5N6QaKJNk1rkvcU6DBP14bHXF/hkOdHA== X-Google-Smtp-Source: AKy350a9KCAvRpaDzdl0beFn/kCj5CSyYW3pN6y/yjq4DU+5Z1cljP08WUxtic7E1rYefs6Kdnn8fQ== X-Received: by 2002:adf:facf:0:b0:2e5:25e7:45d2 with SMTP id a15-20020adffacf000000b002e525e745d2mr1034265wrs.66.1680852282677; Fri, 07 Apr 2023 00:24:42 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:42 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 01/14] replay: introduce new builtin Date: Fri, 7 Apr 2023 09:24:02 +0200 Message-Id: <20230407072415.1360068-2-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren For now, this is just a rename from `t/helper/test-fast-rebase.c` into `builtin/replay.c` with minimal changes to make it build appropriately. Subsequent commits will flesh out its capabilities and make it a more standard regular builtin. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- .gitignore | 1 + Makefile | 2 +- builtin.h | 1 + .../test-fast-rebase.c => builtin/replay.c | 23 ++++------------ command-list.txt | 1 + git.c | 1 + t/helper/test-tool.c | 1 - t/helper/test-tool.h | 1 - t/t6429-merge-sequence-rename-caching.sh | 27 +++++++------------ 9 files changed, 19 insertions(+), 39 deletions(-) rename t/helper/test-fast-rebase.c => builtin/replay.c (89%) diff --git a/.gitignore b/.gitignore index e875c59054..b5f025a296 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ /git-remote-ext /git-repack /git-replace +/git-replay /git-request-pull /git-rerere /git-reset diff --git a/Makefile b/Makefile index 60ab1a8b4f..44546f74dc 100644 --- a/Makefile +++ b/Makefile @@ -799,7 +799,6 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o TEST_BUILTINS_OBJS += test-dump-untracked-cache.o TEST_BUILTINS_OBJS += test-env-helper.o TEST_BUILTINS_OBJS += test-example-decorate.o -TEST_BUILTINS_OBJS += test-fast-rebase.o TEST_BUILTINS_OBJS += test-fsmonitor-client.o TEST_BUILTINS_OBJS += test-genrandom.o TEST_BUILTINS_OBJS += test-genzeros.o @@ -1286,6 +1285,7 @@ BUILTIN_OBJS += builtin/remote-fd.o BUILTIN_OBJS += builtin/remote.o BUILTIN_OBJS += builtin/repack.o BUILTIN_OBJS += builtin/replace.o +BUILTIN_OBJS += builtin/replay.o BUILTIN_OBJS += builtin/rerere.o BUILTIN_OBJS += builtin/reset.o BUILTIN_OBJS += builtin/rev-list.o diff --git a/builtin.h b/builtin.h index 46cc789789..6ad9efd6cd 100644 --- a/builtin.h +++ b/builtin.h @@ -204,6 +204,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix); int cmd_remote_ext(int argc, const char **argv, const char *prefix); int cmd_remote_fd(int argc, const char **argv, const char *prefix); int cmd_repack(int argc, const char **argv, const char *prefix); +int cmd_replay(int argc, const char **argv, const char *prefix); int cmd_rerere(int argc, const char **argv, const char *prefix); int cmd_reset(int argc, const char **argv, const char *prefix); int cmd_restore(int argc, const char **argv, const char *prefix); diff --git a/t/helper/test-fast-rebase.c b/builtin/replay.c similarity index 89% rename from t/helper/test-fast-rebase.c rename to builtin/replay.c index b1edb92a03..154a976ca6 100644 --- a/t/helper/test-fast-rebase.c +++ b/builtin/replay.c @@ -1,18 +1,11 @@ /* - * "git fast-rebase" builtin command - * - * FAST: Forking Any Subprocesses (is) Taboo - * - * This is meant SOLELY as a demo of what is possible. sequencer.c and - * rebase.c should be refactored to use the ideas here, rather than attempting - * to extend this file to replace those (unless Phillip or Dscho say that - * refactoring is too hard and we need a clean slate, but I'm guessing that - * refactoring is the better route). + * "git replay" builtin command */ #define USE_THE_INDEX_VARIABLE -#include "test-tool.h" +#include "git-compat-util.h" +#include "builtin.h" #include "cache-tree.h" #include "commit.h" #include "hex.h" @@ -86,7 +79,7 @@ static struct commit *create_commit(struct tree *tree, return (struct commit *)obj; } -int cmd__fast_rebase(int argc, const char **argv) +int cmd_replay(int argc, const char **argv, const char *prefix) { struct commit *onto; struct commit *last_commit = NULL, *last_picked_commit = NULL; @@ -102,12 +95,6 @@ int cmd__fast_rebase(int argc, const char **argv) struct strbuf branch_name = STRBUF_INIT; int ret = 0; - /* - * test-tool stuff doesn't set up the git directory by default; need to - * do that manually. - */ - setup_git_directory(); - if (argc == 2 && !strcmp(argv[1], "-h")) { printf("Sorry, I am not a psychiatrist; I can not give you the help you need. Oh, you meant usage...\n"); exit(129); @@ -128,7 +115,7 @@ int cmd__fast_rebase(int argc, const char **argv) if (repo_read_index(the_repository) < 0) BUG("Could not read index"); - repo_init_revisions(the_repository, &revs, NULL); + repo_init_revisions(the_repository, &revs, prefix); revs.verbose_header = 1; revs.max_parents = 1; revs.cherry_mark = 1; diff --git a/command-list.txt b/command-list.txt index 54b2a50f5f..d74836ab21 100644 --- a/command-list.txt +++ b/command-list.txt @@ -160,6 +160,7 @@ git-reflog ancillarymanipulators complete git-remote ancillarymanipulators complete git-repack ancillarymanipulators complete git-replace ancillarymanipulators complete +git-replay mainporcelain history git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain history diff --git a/git.c b/git.c index ae2134f29a..e4ce39fd4d 100644 --- a/git.c +++ b/git.c @@ -571,6 +571,7 @@ static struct cmd_struct commands[] = { { "remote-fd", cmd_remote_fd, NO_PARSEOPT }, { "repack", cmd_repack, RUN_SETUP }, { "replace", cmd_replace, RUN_SETUP }, + { "replay", cmd_replay, RUN_SETUP }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, { "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE }, diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index abe8a785eb..9ca1586de7 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -30,7 +30,6 @@ static struct test_cmd cmds[] = { { "dump-untracked-cache", cmd__dump_untracked_cache }, { "env-helper", cmd__env_helper }, { "example-decorate", cmd__example_decorate }, - { "fast-rebase", cmd__fast_rebase }, { "fsmonitor-client", cmd__fsmonitor_client }, { "genrandom", cmd__genrandom }, { "genzeros", cmd__genzeros }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index ea2672436c..a03bbfc6b2 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -24,7 +24,6 @@ int cmd__dump_untracked_cache(int argc, const char **argv); int cmd__dump_reftable(int argc, const char **argv); int cmd__env_helper(int argc, const char **argv); int cmd__example_decorate(int argc, const char **argv); -int cmd__fast_rebase(int argc, const char **argv); int cmd__fsmonitor_client(int argc, const char **argv); int cmd__genrandom(int argc, const char **argv); int cmd__genzeros(int argc, const char **argv); diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index d02fa16614..40505c9054 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -71,8 +71,7 @@ test_expect_success 'caching renames does not preclude finding new ones' ' git switch upstream && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic + git replay --onto HEAD upstream~1 topic && git ls-files >tracked-files && test_line_count = 2 tracked-files && @@ -140,8 +139,7 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1 topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 1 calls @@ -199,8 +197,7 @@ test_expect_success 'rename same file identically, then reintroduce it' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1 topic && git ls-files >tracked && test_line_count = 2 tracked && @@ -276,8 +273,7 @@ test_expect_success 'rename same file identically, then add file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1 topic && git ls-files >tracked && test_line_count = 4 tracked && @@ -353,8 +349,7 @@ test_expect_success 'cached dir rename does not prevent noticing later conflict' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test_must_fail test-tool fast-rebase --onto HEAD upstream~1 topic >output && - #git cherry-pick upstream..topic && + test_must_fail git replay --onto HEAD upstream~1 topic >output && grep CONFLICT..rename/rename output && @@ -455,8 +450,7 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1 topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 2 calls && @@ -521,8 +515,7 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1 topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 3 calls && @@ -623,8 +616,7 @@ test_expect_success 'caching renames only on upstream side, part 1' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1 topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 1 calls && @@ -681,8 +673,7 @@ test_expect_success 'caching renames only on upstream side, part 2' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1 topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 2 calls && From patchwork Fri Apr 7 07:24:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204516 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 D1EA3C76196 for ; Fri, 7 Apr 2023 07:25:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237539AbjDGHZI (ORCPT ); Fri, 7 Apr 2023 03:25:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239571AbjDGHZG (ORCPT ); Fri, 7 Apr 2023 03:25:06 -0400 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 C39D5E56 for ; Fri, 7 Apr 2023 00:24:54 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id j11so1933913wrd.2 for ; Fri, 07 Apr 2023 00:24:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852283; 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=z46jcp9KTGA6+ezDSwyafz68Ve6a+SRUErWWbqC9IqE=; b=hAQgJppOHmjmnga1IT/61bTd5lCeWt5ppcZ6P5+Y/SrfvxELShGbUO5az34yDW+Kp/ QuhlLxOjWNFUt4/EW/0SEQKzr1FR6uuyIZIFUgthN9eBEWyl5eFfJT4YqiFjiUD7R5Qh sgq+JvB80gNkAHSDDWMhEiiHBFbmo73P2KkyfhQdZHUSgGE6OOPKEQCdOAVj1+d0vRv0 pfpQUnF6gpspho+k0qz3UrTXARh4EPLnDsdR5SDqc4PBYp9JJTqZYBwc27OjjcwEFgGg rdln7VKlNegUUkc4Jxf5Wvjp2g0sXwFycPTCeoc2cwlx6CIs9HelBuUIaujzFyk83s5F 4WnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852283; 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=z46jcp9KTGA6+ezDSwyafz68Ve6a+SRUErWWbqC9IqE=; b=8IiKOwX103XOYl0dEM3dieuFXRznF4Sm9T1iZ7PJD1huh3uFHjlCym8bkIzpx0xzrq QST5X6PqruTL8oTTRBOkZ3MuPzSKaAJkU1Dg9mM8bU3Uf9WYugAliqTrD19XczHxMZfc U0JFqv6WbS5XvKBwrREm2Cr/b6U3Jgsm6vhB146CzXjSFrooGHwU8QpeVlMU1ADq8QIb jrBzLmsdLx3ke4eNyoc5tZynx9j8x4SAsfoX8voJE6FR5K2NoPXD0e3SJhS7ukDkvgqq 2RZUJ07243lfT4xhnpyLNxZUgKUTf01nScBNK7s1GkhmsWndUbjGrL0OswTwxO4AI6r3 y+7g== X-Gm-Message-State: AAQBX9eylXcZHG4T3MpDpI8yfct589N4bhqrz2w35Q4r6CuyY+kLVNjM 8v8mDjUHWiOdDqEmjH0kNI1cQbPPgz2cQg== X-Google-Smtp-Source: AKy350brHbHO80E1++FckWM+C4ynFd8FWcgIeyJ16LiOeV4LlrfYMY9HyJMBltFnB3kk9CeWUHMbzw== X-Received: by 2002:a5d:526b:0:b0:2ce:a835:83d4 with SMTP id l11-20020a5d526b000000b002cea83583d4mr641439wrc.27.1680852283434; Fri, 07 Apr 2023 00:24:43 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:43 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 02/14] replay: start using parse_options API Date: Fri, 7 Apr 2023 09:24:03 +0200 Message-Id: <20230407072415.1360068-3-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Instead of manually parsing arguments, let's start using the parse_options API. This way this new builtin will look more standard, and in some upcoming commits will more easily be able to handle more command line options. Note that we plan to later use standard revision ranges instead of hardcoded " " arguments. When we will use standard revision ranges, it will be easier to check if there are no spurious arguments if we keep ARGV[0], so let's call parse_options() with PARSE_OPT_KEEP_ARGV0 even if we don't need ARGV[0] right now to avoid some useless code churn. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index 154a976ca6..ca931dee41 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -11,6 +11,7 @@ #include "hex.h" #include "lockfile.h" #include "merge-ort.h" +#include "parse-options.h" #include "refs.h" #include "revision.h" #include "sequencer.h" @@ -82,6 +83,7 @@ static struct commit *create_commit(struct tree *tree, int cmd_replay(int argc, const char **argv, const char *prefix) { struct commit *onto; + const char *onto_name = NULL; struct commit *last_commit = NULL, *last_picked_commit = NULL; struct object_id head; struct lock_file lock = LOCK_INIT; @@ -95,16 +97,32 @@ int cmd_replay(int argc, const char **argv, const char *prefix) struct strbuf branch_name = STRBUF_INIT; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) { - printf("Sorry, I am not a psychiatrist; I can not give you the help you need. Oh, you meant usage...\n"); - exit(129); + const char * const replay_usage[] = { + N_("git replay --onto "), + NULL + }; + struct option replay_options[] = { + OPT_STRING(0, "onto", &onto_name, + N_("revision"), + N_("replay onto given commit")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, replay_options, replay_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); + + if (!onto_name) { + error(_("option --onto is mandatory")); + usage_with_options(replay_usage, replay_options); } - if (argc != 5 || strcmp(argv[1], "--onto")) - die("usage: read the code, figure out how to use it, then do so"); + if (argc != 3) { + error(_("bad number of arguments")); + usage_with_options(replay_usage, replay_options); + } - onto = peel_committish(argv[2]); - strbuf_addf(&branch_name, "refs/heads/%s", argv[4]); + onto = peel_committish(onto_name); + strbuf_addf(&branch_name, "refs/heads/%s", argv[2]); /* Sanity check */ if (get_oid("HEAD", &head)) @@ -116,6 +134,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) BUG("Could not read index"); repo_init_revisions(the_repository, &revs, prefix); + revs.verbose_header = 1; revs.max_parents = 1; revs.cherry_mark = 1; @@ -124,7 +143,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix) revs.right_only = 1; revs.sort_order = REV_SORT_IN_GRAPH_ORDER; revs.topo_order = 1; - strvec_pushl(&rev_walk_args, "", argv[4], "--not", argv[3], NULL); + + strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL); if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) { ret = error(_("unhandled options")); @@ -187,8 +207,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix) &last_commit->object.oid, &last_picked_commit->object.oid, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[4]); - die("Failed to update %s", argv[4]); + error(_("could not update %s"), argv[2]); + die("Failed to update %s", argv[2]); } if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0) die(_("unable to update HEAD")); @@ -203,8 +223,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix) &last_commit->object.oid, &head, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[4]); - die("Failed to update %s", argv[4]); + error(_("could not update %s"), argv[2]); + die("Failed to update %s", argv[2]); } } if (write_locked_index(&the_index, &lock, From patchwork Fri Apr 7 07:24:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204518 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 B5C45C76196 for ; Fri, 7 Apr 2023 07:25:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239896AbjDGHZU (ORCPT ); Fri, 7 Apr 2023 03:25:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239692AbjDGHZI (ORCPT ); Fri, 7 Apr 2023 03:25:08 -0400 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 4F18C93ED for ; Fri, 7 Apr 2023 00:24:57 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id e18so41597143wra.9 for ; Fri, 07 Apr 2023 00:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852284; 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=QZGEHAN43hCo20KnFAhasAWJxHrvQIQ713ezcf+4WHE=; b=IAeveeg10M1yYpe8glFdEJ30RTkcBAgMAOZIfzc6UDJKodckHZQWlHQ25SEKIUE2Rg YC/2pL1WncELKJQlkF279MF737LLyR/hfup9TQtGxvZyoFlLCaiIOkxTeaANrav5sBR+ ucASQhPzgKAErkK0wZM3dnBLflG2+pQfpvYlqYBC7+PcDJkBKlkaca+vQR9sXiHQVKoY thZ/0/688P6WnQc2eyrWnwPIo7XTEQnRypIlC/BAywAR7/hgbzlSFTqELNjO5JQCazNt gTER2E6VW143K46WW0Seh7fnzxzhJIZL4x/suxNWNM/FO1b1XRYYCftoEL4/z3J+sPAU 9MIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852284; 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=QZGEHAN43hCo20KnFAhasAWJxHrvQIQ713ezcf+4WHE=; b=Tpkhgz9QghfGE8cSUYjUPX3FuBrqhT5xKxBiWLf8hMWktn6Fao92znk5Lj2lzwFXbR X5wgYhtiSPAHdUlVIKgm8gw6kpgeeE/kQah0nOdfQayonL9VK0EqFpcXvDcWuv3bF0w5 jQfQNAnmkA2FDj6GIhkGFiT+m2gjScFG+0ihwoWQkp/KZAtt9GwUX4CDAIlMiOwWN6eA wmL61aZxrSFnOCI/Sw3MtlkcR19iZiZKCLzgIYpFCjkm1BzClJbXOUdZDTC89hKGI+PX kbbaNTCeTySEkfksNPAoXaCoYdWj2YCKGz/qIYErT1TO9aLMg7kHUEO0sEP7P7delm4M 2vWw== X-Gm-Message-State: AAQBX9fXcCRAVEsfjvr5m+xN8aNiieDJIz82KvywL/V7vxbHTLD/Bb6I +xFP4UIPJCI9nbyFGR3toGkCeksNhuzzNg== X-Google-Smtp-Source: AKy350ZU9AYoAHxV8zMVO+gv6d8kJUvYwQaCycLR3Irzxr8b+ojlY5EOIibSuqE+DEvR7EmcRglyYw== X-Received: by 2002:a05:6000:1b0a:b0:2ef:b3e6:8293 with SMTP id f10-20020a0560001b0a00b002efb3e68293mr169072wrz.9.1680852284134; Fri, 07 Apr 2023 00:24:44 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:43 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 03/14] replay: die() instead of failing assert() Date: Fri, 7 Apr 2023 09:24:04 +0200 Message-Id: <20230407072415.1360068-4-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren It's not a good idea for regular Git commands to use an assert() to check for things that could happen but are not supported. Let's die() with an explanation of the issue instead. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/builtin/replay.c b/builtin/replay.c index ca931dee41..16efac11ab 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -170,7 +170,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix) fprintf(stderr, "Rebasing %s...\r", oid_to_hex(&commit->object.oid)); - assert(commit->parents && !commit->parents->next); + + if (!commit->parents) + die(_("replaying down to root commit is not supported yet!")); + if (commit->parents->next) + die(_("replaying merge commits is not supported yet!")); + base = commit->parents->item; next_tree = get_commit_tree(commit); From patchwork Fri Apr 7 07:24:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204520 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 E5A5CC76196 for ; Fri, 7 Apr 2023 07:25:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239949AbjDGHZW (ORCPT ); Fri, 7 Apr 2023 03:25:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233324AbjDGHZS (ORCPT ); Fri, 7 Apr 2023 03:25:18 -0400 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 4ED7D93E2 for ; Fri, 7 Apr 2023 00:24:57 -0700 (PDT) Received: by mail-wm1-x32a.google.com with SMTP id l26-20020a05600c1d1a00b003edd24054e0so387464wms.4 for ; Fri, 07 Apr 2023 00:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852285; 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=35EQYnVpyBv2lx48nBGZzSKw1yCFkFEMZT2pqp7DgYA=; b=Quk3BJtao/GxDZ507pm63rbTI9gIdRufCrbCGQfgQLItxd+RnciVzSDS3yf5OEfyly s7o+j89ft3stm9WDWOhcIqnF0rD6/1rhFu6bJrSSegOEI3amXM2QnCYNNrJAk37DvI1j 8re6jZLLHG4TD7UIOCz0PT/nW18v2yfSTnm9d0Z9S1jRw6KwiHzzdvk0Q9t88C5YBm/H E9yljOcpAjsEz04iE5BHWZ/B/3xWGbQ+v0n5j9cFx9OiYHGX0WbD+7rdLP7aXtXX8Mz2 jvuZ1MYlz7CvMMEb1OfpYp/U+9K5OclWfcLzhvbsmOpW8Z6Sy85lQBJEzlqtmrbl3qpC aYxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852285; 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=35EQYnVpyBv2lx48nBGZzSKw1yCFkFEMZT2pqp7DgYA=; b=5JFhsiebr8wU+RXfn3fzB/8FZNcCFgj0K6ToeaXXngKBlE65NGljDPTaoSjSGdf6UN 4DPFFTXyMZOHSSubBcUpPsufvqlvOPsX2qFHP0D7DRlVqK2zqhSwljf9UxtPC7jRns0G 7MPJR1sn0xZB7F9ldKhgD41zc6KneAe7Y2bpvkK98Io53J7QWrjHOpsbr5BxKphoRZZM /KZa7Gpo9dPWxCpJHalVVeBKxECMJ4BFE5pJHu6rKH19z21cyQV9o8DpJWehdnX+cTto IAl6Nf5yvhC3JYt0bnSVk0L1mibk5TzBGYDuSD/ogg25EAc+F/5aPbX+Qc6iV/EwDIjs Q8qA== X-Gm-Message-State: AAQBX9f8D+1cyD9a0j52U4ioTMIGH1g07hZo6FFW+/EiSegaGUmJtYJM dLn7vfG0FzrNtc4pzvDWiP+C61Z5Xve2KA== X-Google-Smtp-Source: AKy350YcDW3c+ZtmXwQX/wgp2GBBf2eGFVcfy0NJZAaRATJE3gxQ1kRirc5fkeyIJD5Zm+6Mu4Rl5w== X-Received: by 2002:a7b:ce85:0:b0:3ed:ce6f:e86e with SMTP id q5-20020a7bce85000000b003edce6fe86emr582204wmj.23.1680852284944; Fri, 07 Apr 2023 00:24:44 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:44 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 04/14] replay: introduce pick_regular_commit() Date: Fri, 7 Apr 2023 09:24:05 +0200 Message-Id: <20230407072415.1360068-5-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Let's refactor the code to handle a regular commit (a commit that is neither a root commit nor a merge commit) into a single function instead of keeping it inside cmd_replay(). This is good for separation of concerns, and this will help further work in the future to replay merge commits. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 54 ++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index 16efac11ab..ea12d4c8fe 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -80,6 +80,35 @@ static struct commit *create_commit(struct tree *tree, return (struct commit *)obj; } +static struct commit *pick_regular_commit(struct commit *pickme, + struct commit *last_commit, + struct merge_options *merge_opt, + struct merge_result *result) +{ + struct commit *base; + struct tree *pickme_tree, *base_tree; + + base = pickme->parents->item; + + pickme_tree = get_commit_tree(pickme); + base_tree = get_commit_tree(base); + + merge_opt->branch2 = short_commit_name(pickme); + merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2); + + merge_incore_nonrecursive(merge_opt, + base_tree, + result->tree, + pickme_tree, + result); + + free((char*)merge_opt->ancestor); + merge_opt->ancestor = NULL; + if (!result->clean) + return NULL; + return create_commit(result->tree, pickme, last_commit); +} + int cmd_replay(int argc, const char **argv, const char *prefix) { struct commit *onto; @@ -91,7 +120,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) struct rev_info revs; struct commit *commit; struct merge_options merge_opt; - struct tree *next_tree, *base_tree, *head_tree; + struct tree *head_tree; struct merge_result result; struct strbuf reflog_msg = STRBUF_INIT; struct strbuf branch_name = STRBUF_INIT; @@ -166,7 +195,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) result.tree = head_tree; last_commit = onto; while ((commit = get_revision(&revs))) { - struct commit *base; + struct commit *pick; fprintf(stderr, "Rebasing %s...\r", oid_to_hex(&commit->object.oid)); @@ -176,26 +205,11 @@ int cmd_replay(int argc, const char **argv, const char *prefix) if (commit->parents->next) die(_("replaying merge commits is not supported yet!")); - base = commit->parents->item; - - next_tree = get_commit_tree(commit); - base_tree = get_commit_tree(base); - - merge_opt.branch2 = short_commit_name(commit); - merge_opt.ancestor = xstrfmt("parent of %s", merge_opt.branch2); - - merge_incore_nonrecursive(&merge_opt, - base_tree, - result.tree, - next_tree, - &result); - - free((char*)merge_opt.ancestor); - merge_opt.ancestor = NULL; - if (!result.clean) + pick = pick_regular_commit(commit, last_commit, &merge_opt, &result); + if (!pick) break; + last_commit = pick; last_picked_commit = commit; - last_commit = create_commit(result.tree, commit, last_commit); } merge_switch_to_result(&merge_opt, head_tree, &result, 1, !result.clean); From patchwork Fri Apr 7 07:24:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204521 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 38DEDC6FD1D for ; Fri, 7 Apr 2023 07:25:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232563AbjDGHZY (ORCPT ); Fri, 7 Apr 2023 03:25:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56212 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239225AbjDGHZS (ORCPT ); Fri, 7 Apr 2023 03:25:18 -0400 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 A89AFA5D3 for ; Fri, 7 Apr 2023 00:24:57 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id t4so36368238wra.7 for ; Fri, 07 Apr 2023 00:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852286; 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=ppV69I8CpIOb2f5UaGJDykgFidnkTVaT2dBaMGHXrfw=; b=YKXN9DjOacVGOq6vvX+JwToUtp3O+z1sNvgaoaisW6sTxc2o31wLBzTz7hTnYQTTz+ TNVVfk3I7oaZmkE0BUAMflGwV4XsQr6ORdMkkjxq7CbUaVUHE15qNeaMy7aopqUk6FoW 9Fm9Lsvi5r3UfjyasHc8vJaBrta5hK3Lshr86E1ICfNZZkRfZqMzjrOW+EZ6ALWd3FD6 12f95Rx8TMFfwPqrfqISfJmXpmGZ730Sj67Y614rWcFEZzknhvJoVvPTIDT9kod2kFcd +3ntSM6thdo1C+Hm378XWPKInrkD5nv8qOVHRuw7a7NK9SvnqKLaFCB/VT+Z8DORDQI0 Lnxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852286; 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=ppV69I8CpIOb2f5UaGJDykgFidnkTVaT2dBaMGHXrfw=; b=LIBWJgacXVAmIY3kBHVxVfM/ojNPzDPwKj7tZLzJkmaU4eQqbbTftHAZVaa1WMPXl8 DOrN2GJ9hhZhBOz1W7UXgU93OQp6UyO9KnM4xo7wu+a5qQ4eitPUf3DpTO5XQLsN2OZN eQ9dpEFHXkCLJSBKrx9NapamaXJFKI+aXS8ZKYxJaZUuth/6CJOb27M1hoe5pTNqPHt6 7MmjcR/MFLRRmpba1MGfC7UNDFtHSA+96UEZjQ9GyBwjCi3K/7vHfc/pGpWM3I00SXCf 6DQqw1JLREfpZTmvAHv2suKg607AudlKksqZapKuq/E36LnpNIux5S1vwYW53PbIraqE DVrQ== X-Gm-Message-State: AAQBX9eEaEse9cz1hSw0AhUref91EcKxkiRWN3f+FaaEufHbGrwqUBwU c4djan2U4ejhPTWI4TOIcCY4ZFzvIrd95A== X-Google-Smtp-Source: AKy350Zy0miSwxoxBaqxuAEpzuNAXDmUYnOivlaDB95jmcPxtqr2z97SzHaRp7wL1ETOpUf3TyMi3g== X-Received: by 2002:adf:f20f:0:b0:2ef:64cd:46cf with SMTP id p15-20020adff20f000000b002ef64cd46cfmr604660wro.60.1680852285655; Fri, 07 Apr 2023 00:24:45 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:45 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 05/14] replay: don't simplify history Date: Fri, 7 Apr 2023 09:24:06 +0200 Message-Id: <20230407072415.1360068-6-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Let's set the rev walking options we need after calling setup_revisions() instead of before. This makes it clearer which options we need. Also we don't want history simplification, as we want to deal with all the commits in the affected range. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index ea12d4c8fe..59ebbc3b8f 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -164,15 +164,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) repo_init_revisions(the_repository, &revs, prefix); - revs.verbose_header = 1; - revs.max_parents = 1; - revs.cherry_mark = 1; - revs.limited = 1; - revs.reverse = 1; - revs.right_only = 1; - revs.sort_order = REV_SORT_IN_GRAPH_ORDER; - revs.topo_order = 1; - strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL); if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) { @@ -180,6 +171,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix) goto cleanup; } + /* requirements/overrides for revs */ + revs.reverse = 1; + revs.sort_order = REV_SORT_IN_GRAPH_ORDER; + revs.topo_order = 1; + revs.simplify_history = 0; + strvec_clear(&rev_walk_args); if (prepare_revision_walk(&revs) < 0) { From patchwork Fri Apr 7 07:24:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204519 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 D7C30C77B6E for ; Fri, 7 Apr 2023 07:25:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239799AbjDGHZU (ORCPT ); Fri, 7 Apr 2023 03:25:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232242AbjDGHZS (ORCPT ); Fri, 7 Apr 2023 03:25:18 -0400 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 DD97AA5E7 for ; Fri, 7 Apr 2023 00:24:57 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id l12so41583435wrm.10 for ; Fri, 07 Apr 2023 00:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852286; 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=LCHu72tliax/6QnCO3CIqeARYQNoCHdi+JnM8Kz2BKw=; b=fHlNx2hw2B7XpikQ089CGm9rtRi+Z8jRDLc0X0SGwk6QlYrOVTPq5areH/xu5ctxa6 IlufoKVYpqjVgsuipEZYQyzRe/ZDmA4anORvo0TGoNf/ZfCf3ZtyydF7D8Q29teyKU2I LeyClkSTzDtRPxsdnXYzBECkaRfN4UMYHED9lsSyCW7Ttt3mWocCXAah7Flqyw87Ma0G PV2eZsmYCC0kV9Xa2bJsITDifvNfJTXxYuanQ1JPlGBwxT7OZXEh36PCpQHuXBeS3ZWg In9kNN5c+djZ8e3dqvafF2R9OA/0Mq9cwMfNpCHQTT02ZDQCeb8MsGwsK3r4I8ZYoD6I yBIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852286; 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=LCHu72tliax/6QnCO3CIqeARYQNoCHdi+JnM8Kz2BKw=; b=4jcC5aFaHAmhPzz70dR5gJK1/pAuZpXyxKmyQzpRgJ+ACs1zUlTKwQuBQRp1RJKpUH UyiQtgkZEms+mAbMn5KdBhrxPLppGlATNbQSB97Mtov6U8DrG9AK3T6ya+rD0yxoJTG5 4MgCXXZ5Ixmyc5vmPoSB4uvOhibsY62VCY8DJkuUm1V7N7bAwNKjS8GZWBWzxn/4Uq5v DTUvugOASOhZBskuiT57GjCJkzKTdwThvNWgp+xRWhMG2/I7/KQX+njpi+8grK5+WLjY UetH4JyytnWsS3PpAL4Riq4szvHh+hQaWcW1dHgiaF+G0ZRLIuQ6x21AVmMqCzXZ+3IU vRIg== X-Gm-Message-State: AAQBX9fA9mkFecs2MY/Y1sGz957oPde5wqhrQb6ZkuUrCZP4QjDENsf7 ksbs7qyeTk1bm1wpz8dTNAzMtS42HVVRZw== X-Google-Smtp-Source: AKy350YBZnal6FjvJZNA3casX1j8Y3A5Yy747WRSGcFjAw8O8yYhlfbRUSBGYNAyRdoSbUM5ZFukMA== X-Received: by 2002:adf:f84f:0:b0:2ef:5066:7bd8 with SMTP id d15-20020adff84f000000b002ef50667bd8mr750613wrq.43.1680852286269; Fri, 07 Apr 2023 00:24:46 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:45 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 06/14] replay: add an important FIXME comment about gpg signing Date: Fri, 7 Apr 2023 09:24:07 +0200 Message-Id: <20230407072415.1360068-7-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren We want to be able to handle signed commits in some way in the future, but we are not ready to do it now. So for the time being let's just add a FIXME comment to remind us about it. These are different ways we could handle them: - in case of a cli user and if there was an interactive mode, we could perhaps ask if the user wants to sign again - we could add an option to just fail if there are signed commits Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/replay.c b/builtin/replay.c index 59ebbc3b8f..ffd7ce1fde 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -54,7 +54,7 @@ static struct commit *create_commit(struct tree *tree, struct object *obj; struct commit_list *parents = NULL; char *author; - char *sign_commit = NULL; + char *sign_commit = NULL; /* FIXME: cli users might want to sign again */ struct commit_extra_header *extra; struct strbuf msg = STRBUF_INIT; const char *out_enc = get_commit_output_encoding(); From patchwork Fri Apr 7 07:24:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204523 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 9B6D1C6FD1D for ; Fri, 7 Apr 2023 07:25:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239872AbjDGHZ1 (ORCPT ); Fri, 7 Apr 2023 03:25:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239778AbjDGHZT (ORCPT ); Fri, 7 Apr 2023 03:25:19 -0400 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 4CBBCA5E8 for ; Fri, 7 Apr 2023 00:24:58 -0700 (PDT) Received: by mail-wm1-x336.google.com with SMTP id eo6-20020a05600c82c600b003ee5157346cso399467wmb.1 for ; Fri, 07 Apr 2023 00:24:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852287; 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=1itwQJtJLYK1b9fii+eiwv2KZu14RsH9gKBV6iIaEB4=; b=IP6uyRgCZw4RwOsLVsCIbpyoRV6W/akW4V5kSawk32J9ZUV0baVCNsVnktIVZZibPh 3cniAw6r3YExT7aCKvoWgRcev+7egXB+QwnMLZJex9OEj7xCECkdhU0snD7pCwPojVTL KaesmqGMxsJjCn6DITw9pqedzGb8lVCKi8mgsm1ZAHdR9N43iRVxOYLSkTVJlNA9/77y bwc1n6JPQmvRhlmO9vvgrYUAvB5mrflEYPqNqUkkCgn6NngZrymUitCFpK4sCxHkp/Oq smdP+zWAZmeJgtNt82LwM5lCXg8ukRjgi+WjFlBkdvvgssPAt8yVgxkO8AZgN4s/Qlr5 CdNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852287; 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=1itwQJtJLYK1b9fii+eiwv2KZu14RsH9gKBV6iIaEB4=; b=2KAhws3aapDOcslYPCfHRAIFN+m9hyFv2/TrZJcqchYVERo2gQblrbAETaZ6L1rV/0 NQAEZRvQxB4SfU45xo2U11AFDEmq7vDePwdpsEbxR/Ztps6I6AaeYi2SSDe4ZmBLutYE 1KRZYuIrrF6to2pDdrM8/3/dQfL7XV/fpX9/chMIBFTzS9OalQNkqWp9zwoonRe4LRqA MiwMWWn37bCifPQVluXsyEPNs0yrjrexIOMYzH+U3yba472taRQW+7D9gCxXenptdwPs ZUfeXQ+me6yBIdPGVCkGlmAOotm/+P/W3smBy3XTgthtP7adhoY/OcqRlp5sTx0PjmDw mrTA== X-Gm-Message-State: AAQBX9d24eyzT14hGi4MLZYyQazJHH6lqo8VPy4MBSxqEltCCN/ii6sC YzWRh30LTpWMc5dizKykVEqe0BfOMzh2pw== X-Google-Smtp-Source: AKy350b7m9gJzfLmbuIbOgNZX1vW8rtrdau+FRyvQxb+aBcVkwOJIH32/NzoMH/s7X3zpEtKfSkQig== X-Received: by 2002:a7b:c018:0:b0:3ee:775:c573 with SMTP id c24-20020a7bc018000000b003ee0775c573mr579015wmb.20.1680852287217; Fri, 07 Apr 2023 00:24:47 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:46 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 07/14] replay: remove progress and info output Date: Fri, 7 Apr 2023 09:24:08 +0200 Message-Id: <20230407072415.1360068-8-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren The replay command will be changed in a follow up commit, so that it will not update refs directly, but instead it will print on stdout a list of commands that can be consumed by `git update-ref --stdin`. We don't want this output to be polluted by its current low value output, so let's just remove the latter. In the future, when the command gets an option to update refs by itself, it will make a lot of sense to display a progress meter, but we are not there yet. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index ffd7ce1fde..0a23ea70dc 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -186,7 +186,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); - merge_opt.show_rename_progress = 1; + merge_opt.show_rename_progress = 0; merge_opt.branch1 = "HEAD"; head_tree = get_commit_tree(onto); result.tree = head_tree; @@ -194,9 +194,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) while ((commit = get_revision(&revs))) { struct commit *pick; - fprintf(stderr, "Rebasing %s...\r", - oid_to_hex(&commit->object.oid)); - if (!commit->parents) die(_("replaying down to root commit is not supported yet!")); if (commit->parents->next) @@ -215,7 +212,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) exit(128); if (result.clean) { - fprintf(stderr, "\nDone.\n"); strbuf_addf(&reflog_msg, "finish rebase %s onto %s", oid_to_hex(&last_picked_commit->object.oid), oid_to_hex(&last_commit->object.oid)); @@ -232,7 +228,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) prime_cache_tree(the_repository, the_repository->index, result.tree); } else { - fprintf(stderr, "\nAborting: Hit a conflict.\n"); strbuf_addf(&reflog_msg, "rebase progress up to %s", oid_to_hex(&last_picked_commit->object.oid)); if (update_ref(reflog_msg.buf, "HEAD", From patchwork Fri Apr 7 07:24:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204522 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 D2F76C77B6E for ; Fri, 7 Apr 2023 07:25:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239735AbjDGHZZ (ORCPT ); Fri, 7 Apr 2023 03:25:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237645AbjDGHZS (ORCPT ); Fri, 7 Apr 2023 03:25:18 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B13A900F for ; Fri, 7 Apr 2023 00:24:58 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id l12so41583484wrm.10 for ; Fri, 07 Apr 2023 00:24:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852288; 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=DfqQwIohKbbgtpS2B90XM3z2fAUoZYTF196DGcdHY6A=; b=Bc/h1CsW0TwYEjDRxsO8JSd5xBs0DFpkiXRse/LBVgnAiw2fXXnm+Ay1Rk0qtv8yr6 VuyouJKR/4Wl2joxTfC/1tevee/nCTm06wtHb4YHGtYPeTtuPgBPu9qkG8Xp/iMX5n33 GO90XlIqXN69CPdLIlzXq1ldPBM4UP/1fHZ4caIpI8qcZJ9XpDAvNfmxgIJAqaZzy2Uy dRltr5xcDUxiUNcJ+Tnmj3Sk0IitdEQAIZPGHrOUoGxpjDs3yCjfRcf4/018Etb4Hdsx fr56wBm6s8DtSByGZYOrQjCABwjkOpR1WPIq1jXi87Tve0pZjQJP9qU2CVIph70evSdT jgrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852288; 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=DfqQwIohKbbgtpS2B90XM3z2fAUoZYTF196DGcdHY6A=; b=UCySXDhNieP9fZqy1jcOCZYzUlWGGPxmGtCW2HqcD5GQ4JS8KH+vmlR+kGkkBkyo2D BNTkxYwIei8ob7+3ZuT0J9w8I1K0RJih+lrkmg+K6AAtnCAgvzKZNdd5VebIqFv3Zv2K 3BlJOyfKhK5gs0GR6WFflh/97p+DjtR44yz3y6UT+8Ox8ok1igzpX5q/HaQWPpAgdK5n eO9KxddDned3xU+Js8f+M2k/HeseDB5OkMz0cWmd1UDKupPXFQM008n2GZWgnxXvP+fv UW1fZPkOVkPEiT3s6BQbfaVa1UdRxOoU41BKwx9zrLzMxU5+4UwlR9YoKvyzDuBDNjio ISlA== X-Gm-Message-State: AAQBX9c5Lg0CkAdrfy5WT1wxZfuITSu5kFN3E23P4iQ1HwaW70HCsioK Q06+ypFwbCnQRoRo/gEkfMlI+S0u59uAFA== X-Google-Smtp-Source: AKy350YBHCqI2TmBtsIivgKFXWj0Lmb2yqDY2znD8/ddah0MG15R1taBnAAW944CTuip5vVNQZR9UQ== X-Received: by 2002:adf:ed47:0:b0:2ce:a897:9fd0 with SMTP id u7-20020adfed47000000b002cea8979fd0mr747097wro.6.1680852288117; Fri, 07 Apr 2023 00:24:48 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:47 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 08/14] replay: remove HEAD related sanity check Date: Fri, 7 Apr 2023 09:24:09 +0200 Message-Id: <20230407072415.1360068-9-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren We want replay to be a command that can be used on the server side on any branch, not just the current one, so we are going to stop updating HEAD in a future commit. A "sanity check" that makes sure we are replaying the current branch doesn't make sense anymore. Let's remove it. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index 0a23ea70dc..a331887d12 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -114,7 +114,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) struct commit *onto; const char *onto_name = NULL; struct commit *last_commit = NULL, *last_picked_commit = NULL; - struct object_id head; struct lock_file lock = LOCK_INIT; struct strvec rev_walk_args = STRVEC_INIT; struct rev_info revs; @@ -153,11 +152,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) onto = peel_committish(onto_name); strbuf_addf(&branch_name, "refs/heads/%s", argv[2]); - /* Sanity check */ - if (get_oid("HEAD", &head)) - die(_("Cannot read HEAD")); - assert(oideq(&onto->object.oid, &head)); - repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); if (repo_read_index(the_repository) < 0) BUG("Could not read index"); @@ -232,7 +226,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) oid_to_hex(&last_picked_commit->object.oid)); if (update_ref(reflog_msg.buf, "HEAD", &last_commit->object.oid, - &head, + &onto->object.oid, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { error(_("could not update %s"), argv[2]); die("Failed to update %s", argv[2]); From patchwork Fri Apr 7 07:24:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204524 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 427AFC77B6E for ; Fri, 7 Apr 2023 07:25:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240003AbjDGHZ3 (ORCPT ); Fri, 7 Apr 2023 03:25:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239780AbjDGHZT (ORCPT ); Fri, 7 Apr 2023 03:25:19 -0400 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 E276FAA for ; Fri, 7 Apr 2023 00:24:58 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id t4so36368310wra.7 for ; Fri, 07 Apr 2023 00:24:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852289; 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=hN9vFUWxPoulKIlSZYk1lZU5x2q73yl+mO73oAkxjtY=; b=KbUXGU25uIKlGr3taKKE24MSYGp+6Ru39qjPq2mZm+HWFnzOADA6JPPTL5TmGHxgdp S4L5XmwoHQfSugINu+XnECOevF2pqVTkT2mWlUjAHTaLx8PZCepvCLEZk7Hwd5yv9rym f0QoIyysCvCVY8NSvOEadXzAjuCjs4N7wde+uWyYflz958PFFs9qEWSCvMfm/wp+SfDN c05PQo84JuIDsaO32PBK65/ZtSxLFZPaJgo9lOpXHTStMt4Tu/k97uPj0+9W+u1B2Mwr 1TVYfiD0ty/Y5kGmugu3aB3TCuiBhU5BzWTeJuRrhoTgtLO4OE6yw8D2sI7570netPVf BUqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852289; 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=hN9vFUWxPoulKIlSZYk1lZU5x2q73yl+mO73oAkxjtY=; b=PNDeGqPuCM7+1dziFtiaP2/+xzlBqdvQYzMTKQfACHV+pSuMF67k2yKB+SBnca11PX qYKi5kFrGhk5GrctU1Il2dkA2rTeoO5DejtWr2VCPof8Y6j/jK4j0/MgnVX80cQ4+bPW OPf12oPGldYAdJfHzi/R6JuLaxDOCCd/Z0yzppUfYY8OJdoyHq719sgk3eEz2H6E74Mg FS+uG4c/LxH5GURwR5BXV6OD0n1CRDulf1E4tY4qiw/zbVT/RehCOGwFKVawsDvuZZao zy8V+Wi5dFkI+OFtqBwODOWmefYA9q0mXRf1TH4hO8GyTGeosd4TO5idof0zfgzlz1Th Ut0w== X-Gm-Message-State: AAQBX9ef6f6AAkCIs5iyj3OC7WxIUUfTLs98GIZBGxZQvXgJDr5aXewL btmT3wnqjQdtWKFenZmpB9pHprFWlFZDZA== X-Google-Smtp-Source: AKy350YOzWuLt9ql+qxCgLruIwHWt2OkQZMmJhXZQrTO7hoagmeYZ0l7CagYqTUWDoKs6JopfmqKNA== X-Received: by 2002:a5d:6b03:0:b0:2ef:b257:b46c with SMTP id v3-20020a5d6b03000000b002efb257b46cmr430251wrw.29.1680852289013; Fri, 07 Apr 2023 00:24:49 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:48 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 09/14] replay: very coarse worktree updating Date: Fri, 7 Apr 2023 09:24:10 +0200 Message-Id: <20230407072415.1360068-10-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren In case of conflict, let's just update the worktree and index. And then let's just die() as this command doesn't have ways to handle conflicts yet. Note that we might want to improve this behavior in the case of a bare repository in a future commit. We also have to lock the index only after all the commits have been picked, so that in case of conflict the index is not already locked. Note that this locking of the index will be removed in a following commit as we will not want to modify it anymore. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index a331887d12..9c795c05a7 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -152,10 +152,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) onto = peel_committish(onto_name); strbuf_addf(&branch_name, "refs/heads/%s", argv[2]); - repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); - if (repo_read_index(the_repository) < 0) - BUG("Could not read index"); - repo_init_revisions(the_repository, &revs, prefix); strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL); @@ -194,12 +190,39 @@ int cmd_replay(int argc, const char **argv, const char *prefix) die(_("replaying merge commits is not supported yet!")); pick = pick_regular_commit(commit, last_commit, &merge_opt, &result); - if (!pick) - break; + if (!pick) { + /* TODO: handle conflicts in sparse worktree instead */ + struct object_id head; + struct tree *head_tree; + struct lock_file lock = LOCK_INIT; + + repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); + if (repo_read_index(the_repository) < 0) + BUG("Could not read index"); + + get_oid("HEAD", &head); + head_tree = parse_tree_indirect(&head); + printf("Switching from %s to %s.\n", + oid_to_hex(&head_tree->object.oid), + oid_to_hex(&result.tree->object.oid)); + merge_switch_to_result(&merge_opt, head_tree, &result, + 1, 1); + if (write_locked_index(&the_index, &lock, + COMMIT_LOCK | SKIP_IF_UNCHANGED)) + die(_("unable to write %s"), get_index_file()); + + die(_("failure to pick %s; cannot handle conflicts yet"), + oid_to_hex(&commit->object.oid)); + } + last_commit = pick; last_picked_commit = commit; } + repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); + if (repo_read_index(the_repository) < 0) + BUG("Could not read index"); + merge_switch_to_result(&merge_opt, head_tree, &result, 1, !result.clean); if (result.clean < 0) From patchwork Fri Apr 7 07:24:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204526 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 A230CC77B6F for ; Fri, 7 Apr 2023 07:25:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239851AbjDGHZb (ORCPT ); Fri, 7 Apr 2023 03:25:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239802AbjDGHZT (ORCPT ); Fri, 7 Apr 2023 03:25:19 -0400 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 806DFA5EC for ; Fri, 7 Apr 2023 00:24:59 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id v1so41606211wrv.1 for ; Fri, 07 Apr 2023 00:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852290; 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=xuVI6Uc5QrlddcahOUKqI+AWxo4BoHUhtAZC++P0hqo=; b=IMHk5mcDIq+IMJ0G4+u1gdtEVubYDVABL/Zw8pTOPo2wbi8vmFwqj6GI/2BvztfFdr Tpwhq2RmTLz04VmZySlgvQxabEMAz6XfzkLblX44IOlT2LT5wasYvThEcfLdmdNhNy3b llcRlNLXqzNx/RGFHV/k+XhBkw4VsVRs+t7Nn8v5NElHxH2urt0y7g7fwmpODGIBtSOR NYrf2uYnUh9ATc8MELp3OVv4y6EFeRu+zcOwToJ/r8eg8PjUPolsjxCN0RLTH3vcXXbB 2sK5IMXmGQyhf1qqirc5wvrlHmi7sEEd7Ku+SEV57IJtvgfBFCUl0hqrQQH1Db7kaV7Z qaJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852290; 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=xuVI6Uc5QrlddcahOUKqI+AWxo4BoHUhtAZC++P0hqo=; b=v3ZQk1TFRMngCQ1hSeDaLkOqYDtkhm6Ls34BDbHL79i6d9cvtB4ULEHf06DyNcIzVP EB3nn24HTx3KyHP+rRudXysSVShr4+t6bBZW1FZ99hcCr4ljsTdwdFGTU1tltuHenqPN JKJLoq0BSoocgDf8x+JXMmOa1gbGt7GNoXnheSwqObnWKA2y9zDAa4zvnZsg0NxjKqq7 4qUKaaXPkqXOBWmM0yauTbKlXBkg2rSK6s5lmOjLRab48CIE7hkSzv0qqkkq5fCRHJmT 9MGJVjdifJ00MyO3dQRBY2qfwQJJtiRDmdodEDobNiCVGS8nHthv0Nzgx2dakvvx/dTm U5Bg== X-Gm-Message-State: AAQBX9fcbp6jTU5imn8MwwEXua307b/K9nhiSMi7u0WN9VUlFXnxXAA5 RF9msWCT2KfFm2WK1H1q2Ptrs23ZJ4qQxw== X-Google-Smtp-Source: AKy350YgiV2wWMf1dBnpA10Ef/UsUVcRd5wDY1803ryoOeeIYPfCP0++JT3CGgWLH9xWMcFPUwOoRQ== X-Received: by 2002:adf:dbc4:0:b0:2ce:ae5b:27a2 with SMTP id e4-20020adfdbc4000000b002ceae5b27a2mr555673wrj.17.1680852289940; Fri, 07 Apr 2023 00:24:49 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:49 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 10/14] replay: make it a minimal server side command Date: Fri, 7 Apr 2023 09:24:11 +0200 Message-Id: <20230407072415.1360068-11-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren We want this command to be a minimal command that just does server side picking of commits, displaying the results on stdout for higher level scripts to consume. So let's simplify it: * remove the worktree and index reading/writing, * remove the ref (and reflog) updating, * remove the assumptions tying us to HEAD, since (a) this is not a rebase and (b) we want to be able to pick commits in a bare repo, i.e. to/from branches that are not checked out and not the main branch, * remove unneeded includes, * handle rebasing multiple branches by printing on stdout the update ref commands that should be performed. The output can be piped into `git update-ref --stdin` for the ref updates to happen. In the future to make it easier for users to use this command directly maybe an option can be added to automatically pipe its output into `git update-ref`. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 86 ++++++++---------------- t/t6429-merge-sequence-rename-caching.sh | 32 ++++++--- 2 files changed, 52 insertions(+), 66 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index 9c795c05a7..119cfecfe7 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -6,17 +6,13 @@ #include "git-compat-util.h" #include "builtin.h" -#include "cache-tree.h" -#include "commit.h" #include "hex.h" #include "lockfile.h" #include "merge-ort.h" #include "parse-options.h" #include "refs.h" #include "revision.h" -#include "sequencer.h" #include "strvec.h" -#include "tree.h" static const char *short_commit_name(struct commit *commit) { @@ -93,6 +89,7 @@ static struct commit *pick_regular_commit(struct commit *pickme, pickme_tree = get_commit_tree(pickme); base_tree = get_commit_tree(base); + merge_opt->branch1 = short_commit_name(last_commit); merge_opt->branch2 = short_commit_name(pickme); merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2); @@ -113,15 +110,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix) { struct commit *onto; const char *onto_name = NULL; - struct commit *last_commit = NULL, *last_picked_commit = NULL; - struct lock_file lock = LOCK_INIT; + struct commit *last_commit = NULL; struct strvec rev_walk_args = STRVEC_INIT; struct rev_info revs; struct commit *commit; struct merge_options merge_opt; - struct tree *head_tree; struct merge_result result; - struct strbuf reflog_msg = STRBUF_INIT; struct strbuf branch_name = STRBUF_INIT; int ret = 0; @@ -177,20 +171,19 @@ int cmd_replay(int argc, const char **argv, const char *prefix) init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); merge_opt.show_rename_progress = 0; - merge_opt.branch1 = "HEAD"; - head_tree = get_commit_tree(onto); - result.tree = head_tree; + result.tree = get_commit_tree(onto); last_commit = onto; while ((commit = get_revision(&revs))) { - struct commit *pick; + const struct name_decoration *decoration; if (!commit->parents) die(_("replaying down to root commit is not supported yet!")); if (commit->parents->next) die(_("replaying merge commits is not supported yet!")); - pick = pick_regular_commit(commit, last_commit, &merge_opt, &result); - if (!pick) { + last_commit = pick_regular_commit(commit, last_commit, &merge_opt, &result); + + if (!last_commit) { /* TODO: handle conflicts in sparse worktree instead */ struct object_id head; struct tree *head_tree; @@ -215,54 +208,31 @@ int cmd_replay(int argc, const char **argv, const char *prefix) oid_to_hex(&commit->object.oid)); } - last_commit = pick; - last_picked_commit = commit; - } - - repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); - if (repo_read_index(the_repository) < 0) - BUG("Could not read index"); - - merge_switch_to_result(&merge_opt, head_tree, &result, 1, !result.clean); - - if (result.clean < 0) - exit(128); - - if (result.clean) { - strbuf_addf(&reflog_msg, "finish rebase %s onto %s", - oid_to_hex(&last_picked_commit->object.oid), - oid_to_hex(&last_commit->object.oid)); - if (update_ref(reflog_msg.buf, branch_name.buf, - &last_commit->object.oid, - &last_picked_commit->object.oid, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[2]); - die("Failed to update %s", argv[2]); - } - if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0) - die(_("unable to update HEAD")); - - prime_cache_tree(the_repository, the_repository->index, - result.tree); - } else { - strbuf_addf(&reflog_msg, "rebase progress up to %s", - oid_to_hex(&last_picked_commit->object.oid)); - if (update_ref(reflog_msg.buf, "HEAD", - &last_commit->object.oid, - &onto->object.oid, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[2]); - die("Failed to update %s", argv[2]); + decoration = get_name_decoration(&commit->object); + if (!decoration) + continue; + + while (decoration) { + if (decoration->type == DECORATION_REF_LOCAL) { + printf("update %s %s %s\n", + decoration->name, + oid_to_hex(&last_commit->object.oid), + oid_to_hex(&commit->object.oid)); + } + decoration = decoration->next; } } - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write %s"), get_index_file()); - ret = (result.clean == 0); + /* Cleanup */ + merge_finalize(&merge_opt, &result); + ret = result.clean; + cleanup: - strbuf_release(&reflog_msg); strbuf_release(&branch_name); release_revisions(&revs); - return ret; + + /* Return */ + if (ret < 0) + exit(128); + return ret ? 0 : 1; } diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index 40505c9054..bfdf7f30b3 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -71,7 +71,9 @@ test_expect_success 'caching renames does not preclude finding new ones' ' git switch upstream && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin tracked-files && test_line_count = 2 tracked-files && @@ -139,7 +141,9 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin calls && test_line_count = 1 calls @@ -197,7 +201,9 @@ test_expect_success 'rename same file identically, then reintroduce it' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin tracked && test_line_count = 2 tracked && @@ -273,7 +279,9 @@ test_expect_success 'rename same file identically, then add file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin tracked && test_line_count = 4 tracked && @@ -450,7 +458,9 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin calls && test_line_count = 2 calls && @@ -515,7 +525,9 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin calls && test_line_count = 3 calls && @@ -616,7 +628,9 @@ test_expect_success 'caching renames only on upstream side, part 1' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin calls && test_line_count = 1 calls && @@ -673,7 +687,9 @@ test_expect_success 'caching renames only on upstream side, part 2' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic && + git replay --onto HEAD upstream~1 topic >out && + git update-ref --stdin calls && test_line_count = 2 calls && From patchwork Fri Apr 7 07:24:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204528 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 D5722C6FD1D for ; Fri, 7 Apr 2023 07:25:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240019AbjDGHZf (ORCPT ); Fri, 7 Apr 2023 03:25:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56214 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239874AbjDGHZU (ORCPT ); Fri, 7 Apr 2023 03:25:20 -0400 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2E57A5EF for ; Fri, 7 Apr 2023 00:24:59 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id e18so41597309wra.9 for ; Fri, 07 Apr 2023 00:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852291; 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=Vxa5OhhmUjOxXPvuIRh3xlWU9K1vh91Ux20n7ja7Wg0=; b=fMoEVRYz0xGTWN7SZjGordNS4JKT/uUXiaXzjFa1jF1LWHMVnNuiM8cUR5jvom4gtN ywFVO1EaoPdFNXgxg0dJ6QsAtIbAcFGT51lXYGNL6GD7SOFXEnUy/pOKWNE0NAZa/gf9 ESGxsKu7xfSzIv5l8CxU5su8rbMIE06CCcANQIoHHPPi1mpxSvPfbHa2aDIuM2RHAG/w 4bPZuZCZPFViLUWmXbq/7pHrlNzJ/fl0/BJIes9KLELuA/zS2jvo+gQrD+6ODOtxD4w7 IzYSsvvZBYXKfDk+X8ydX+Dkk/4zfyt017FbEi3nujX7SEMiCsg7TrxEX4DfdZcN6XVb QXgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852291; 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=Vxa5OhhmUjOxXPvuIRh3xlWU9K1vh91Ux20n7ja7Wg0=; b=gY9vIapuiMdzwjHeFnYtj6sy7WtdBC5OyWheNkYIlkfEU7GLXy+8WpGYbUkpy98yDr ABVtNaM+IR41jzLzTfCm2JJXxsjevA/ng2KK9AGtZzyltt9mtDDPOj+QAZaGtLPJZ4r8 PmscM09mFcyT/5rx9FiG0B9Z4SD49zkuQ+UqkjhUcPBOhQ19NEo6QPmKnOEoW8znw20E R6DQb/e3uFy/y/JdkMWLQ7l88pbZhs418RG8ha8UJgXUd8E2B0Ng1mgappbVxDpG2TjB PsjiEGVlY4avaUKEuiLqaeBqihlEf7jh0gziKbNyUUuogPichh9U2GlhLTEBNQhsXXl8 y6uQ== X-Gm-Message-State: AAQBX9fY3zKCifuFpI3DiOabmsVPMfmzMn3GmAbT1ZCqdJAAm5VKt41J MrhxPmFTVIp0O9L292pBNTIhD60fVuqr8A== X-Google-Smtp-Source: AKy350ZgmwsLFqmr5OKv1+nBUerT0qq3stGIzSB0ewXn2VL30s35BGmIwMBk9w4BUuyr2m3PCeKrMA== X-Received: by 2002:a5d:4610:0:b0:2dc:cad4:87b9 with SMTP id t16-20020a5d4610000000b002dccad487b9mr586526wrq.68.1680852290714; Fri, 07 Apr 2023 00:24:50 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:50 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 11/14] replay: use standard revision ranges Date: Fri, 7 Apr 2023 09:24:12 +0200 Message-Id: <20230407072415.1360068-12-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren Instead of the fixed " " arguments, the replay command now accepts "..." arguments in a similar way as many other Git commands. This makes its interface more standard and more flexible. Also as the interface of the command is now mostly finalized, we can add some documentation as well as testcases to make sure the command will continue to work as designed in the future. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- Documentation/git-replay.txt | 86 ++++++++++++++++++++++++ builtin/replay.c | 21 ++---- t/t3650-replay-basics.sh | 63 +++++++++++++++++ t/t6429-merge-sequence-rename-caching.sh | 18 ++--- 4 files changed, 162 insertions(+), 26 deletions(-) create mode 100644 Documentation/git-replay.txt create mode 100755 t/t3650-replay-basics.sh diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt new file mode 100644 index 0000000000..7a83f70343 --- /dev/null +++ b/Documentation/git-replay.txt @@ -0,0 +1,86 @@ +git-replay(1) +============= + +NAME +---- +git-replay - Replay commits on a different base, without touching working tree + + +SYNOPSIS +-------- +[verse] +'git replay' --onto ... + +DESCRIPTION +----------- + +Takes a range of commits, and replays them onto a new location. Does +not touch the working tree or index, and does not update any +references. However, the output of this command is meant to be used +as input to `git update-ref --stdin`, which would update the relevant +branches. + +OPTIONS +------- + +--onto :: + Starting point at which to create the new commits. May be any + valid commit, and not just an existing branch name. ++ +The update-ref commands in the output will update the branch(es) +in the revision range to point at the new commits (in other +words, this mimics a rebase operation). + +:: + Range of commits to replay; see "Specifying Ranges" in + linkgit:git-rev-parse. + +OUTPUT +------ + +When there are no conflicts, the output of this command is usable as +input to `git update-ref --stdin`. It is basically of the form: + + update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} + update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} + update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} + +where the number of refs updated depend on the arguments passed. + +EXIT STATUS +----------- + +For a successful, non-conflicted replay, the exit status is 0. When +the replay has conflicts, the exit status is 1. If the replay is not +able to complete (or start) due to some kind of error, the exit status +is something other than 0 or 1. + +EXAMPLES +-------- + +To simply rebase mybranch onto target: + +------------ +$ git replay --onto target origin/main..mybranch +update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH} +------------ + +When calling `git replay`, one does not need to specify a range of +commits to replay using the syntax `A..B`; any range expression will +do: + +------------ +$ git replay --onto origin/main ^base branch1 branch2 branch3 +update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} +update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} +update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} +------------ + +This will simultaneously rebase branch1, branch2, and branch3 -- all +commits they have since base, playing them on top of origin/main. +These three branches may have commits on top of base that they have in +common, but that does not need to be the case. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/builtin/replay.c b/builtin/replay.c index 119cfecfe7..63513ea6f1 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -12,7 +12,6 @@ #include "parse-options.h" #include "refs.h" #include "revision.h" -#include "strvec.h" static const char *short_commit_name(struct commit *commit) { @@ -111,16 +110,14 @@ int cmd_replay(int argc, const char **argv, const char *prefix) struct commit *onto; const char *onto_name = NULL; struct commit *last_commit = NULL; - struct strvec rev_walk_args = STRVEC_INIT; struct rev_info revs; struct commit *commit; struct merge_options merge_opt; struct merge_result result; - struct strbuf branch_name = STRBUF_INIT; int ret = 0; const char * const replay_usage[] = { - N_("git replay --onto "), + N_("git replay --onto ..."), NULL }; struct option replay_options[] = { @@ -138,20 +135,13 @@ int cmd_replay(int argc, const char **argv, const char *prefix) usage_with_options(replay_usage, replay_options); } - if (argc != 3) { - error(_("bad number of arguments")); - usage_with_options(replay_usage, replay_options); - } - onto = peel_committish(onto_name); - strbuf_addf(&branch_name, "refs/heads/%s", argv[2]); repo_init_revisions(the_repository, &revs, prefix); - strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL); - - if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) { - ret = error(_("unhandled options")); + argc = setup_revisions(argc, argv, &revs, NULL); + if (argc > 1) { + ret = error(_("unrecognized argument: %s"), argv[1]); goto cleanup; } @@ -161,8 +151,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) revs.topo_order = 1; revs.simplify_history = 0; - strvec_clear(&rev_walk_args); - if (prepare_revision_walk(&revs) < 0) { ret = error(_("error preparing revisions")); goto cleanup; @@ -228,7 +216,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) ret = result.clean; cleanup: - strbuf_release(&branch_name); release_revisions(&revs); /* Return */ diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh new file mode 100755 index 0000000000..f55b71763a --- /dev/null +++ b/t/t3650-replay-basics.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +test_description='basic git replay tests' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +GIT_AUTHOR_NAME=author@name +GIT_AUTHOR_EMAIL=bogus@email@address +export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL + +test_expect_success 'setup' ' + test_commit A && + test_commit B && + + git switch -c topic1 && + test_commit C && + git switch -c topic2 && + test_commit D && + test_commit E && + git switch topic1 && + test_commit F && + git switch -c topic3 && + test_commit G && + test_commit H && + git switch -c topic4 main && + test_commit I && + test_commit J && + + git switch -c next main && + test_commit K && + git merge -m "Merge topic1" topic1 && + git merge -m "Merge topic2" topic2 && + git merge -m "Merge topic3" topic3 && + >evil && + git add evil && + git commit --amend && + git merge -m "Merge topic4" topic4 && + + git switch main && + test_commit L && + test_commit M +' + +test_expect_success 'using replay to rebase two branches, one on top of other' ' + git replay --onto main topic1..topic2 >result && + + test_line_count = 1 result && + + git log --format=%s $(cut -f 3 -d " " result) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic2 " >expect && + printf "%s " $(cut -f 3 -d " " result) >>expect && + git rev-parse topic2 >>expect && + + test_cmp expect result +' + +test_done diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index bfdf7f30b3..8f3c394f0e 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -71,7 +71,7 @@ test_expect_success 'caching renames does not preclude finding new ones' ' git switch upstream && - git replay --onto HEAD upstream~1 topic >out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin output && + test_must_fail git replay --onto HEAD upstream~1..topic >output && grep CONFLICT..rename/rename output && @@ -458,7 +458,7 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - git replay --onto HEAD upstream~1 topic >out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin out && + git replay --onto HEAD upstream~1..topic >out && git update-ref --stdin X-Patchwork-Id: 13204525 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 906ACC76196 for ; Fri, 7 Apr 2023 07:25:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240006AbjDGHZa (ORCPT ); Fri, 7 Apr 2023 03:25:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239851AbjDGHZT (ORCPT ); Fri, 7 Apr 2023 03:25:19 -0400 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3F51A5F8 for ; Fri, 7 Apr 2023 00:24:59 -0700 (PDT) Received: by mail-wm1-x32c.google.com with SMTP id l10-20020a05600c1d0a00b003f04bd3691eso9879917wms.5 for ; Fri, 07 Apr 2023 00:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852291; 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=r99VpLl2c9eXbN/lJ4kLt/D8QaiW9A8ougIHgBkAfEA=; b=KseE3NSvN4+OBG1j1yvICFai7LvU42706n+mpvzlOQXO8fwXmvr6kyG/3L0L/yVwa/ rUEyCQZPlAcvISCqmf78EHGjSOoTlWnwh/cttjPVL9BBvnnY8RHUXNwmS9lV7gdWdr6P C/aLVXfr17TiBds6qvpwnwMMVoRo2eTGLV0GHEd1SO9wv3WpfXNL6nkeeFWgi3zFqP/C 1knYJIGUPzNWriTBzN6AacPVA2KiDnjYLdZfdehWblQ3KnUu8etzXycH5P9EFNjh2pLD /ZU11IikKaL+jrcHjpL/5Gy2creGnLAjGPmW88PwoMPR/NkD0hmWY7tnjUkcocTOYC83 9m9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852291; 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=r99VpLl2c9eXbN/lJ4kLt/D8QaiW9A8ougIHgBkAfEA=; b=s2kcmAK2oD7rmFHyMYie67z/Rd0fHjuNgUMaHBu+QlmwJnoF1CgI4KjW+QIMuRTlnr 0NqEbk/1mNTZGVCO7GCZ9p7DibVdwkPUV/xElRJiuknsijQSIbghSJFzlyTixXmc29WU tCY5FB+hKi0rG1SEg1jOvJz96MAHhNYF9L6L85viXSmF7Uzf61N6fa43KPfVieagZzhj 0KsBTXHw5RRSP4oMBmiy2OrhyJTEII3U6/DHTFrjls3PPTxUZhJpyIeumjOjykC7X/fe w5CqI8+XnBvhCmsqemsXH9cy4v8ME5Bh12MdBCTzXPY0tiY/+QG1pG+FTA5UCTaEjplh KdvA== X-Gm-Message-State: AAQBX9ehXorIpnGcGXGiUZi7z1f86FKaunuSADETbyRSN2DhcLJOQS5o ypSd4sKhJdVCw2Bj+ppcBuCPO/u//8wGww== X-Google-Smtp-Source: AKy350YY/26ps7XIZAQ4sCjmFbyk86uqwl7vODlUB72Eb8Xds5Ea2wA1nuY+cwdOZdv/xo88+6s0uA== X-Received: by 2002:a05:600c:28f:b0:3dc:4b87:a570 with SMTP id 15-20020a05600c028f00b003dc4b87a570mr564557wmk.35.1680852291403; Fri, 07 Apr 2023 00:24:51 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:51 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 12/14] replay: introduce guess_new_base() Date: Fri, 7 Apr 2023 09:24:13 +0200 Message-Id: <20230407072415.1360068-13-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren In many cases the `--onto` option is not necessary as we can guess the branch we would like to replay onto. So let's introduce guess_new_base() for that purpose and make `--onto` optional. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- Documentation/git-replay.txt | 8 ++++- builtin/replay.c | 61 +++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt index 7a83f70343..ce2cafc42e 100644 --- a/Documentation/git-replay.txt +++ b/Documentation/git-replay.txt @@ -9,7 +9,7 @@ git-replay - Replay commits on a different base, without touching working tree SYNOPSIS -------- [verse] -'git replay' --onto ... +'git replay' [--onto ] ... DESCRIPTION ----------- @@ -20,6 +20,12 @@ references. However, the output of this command is meant to be used as input to `git update-ref --stdin`, which would update the relevant branches. +When the `--onto ` option is not passed, the commits will be +replayed onto a base guessed from the ``. For example +if the `` is `origin/main..mybranch` then `mybranch` +was probably based on an old version of `origin/main`, so we will +replay it on the newest version of that branch. + OPTIONS ------- diff --git a/builtin/replay.c b/builtin/replay.c index 63513ea6f1..af948af73c 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -75,6 +75,54 @@ static struct commit *create_commit(struct tree *tree, return (struct commit *)obj; } +static struct commit *guess_new_base(struct rev_cmdline_info *info) +{ + struct commit *new_base = NULL; + int i, bottom_commits = 0; + + /* + * When the user specifies e.g. + * git replay origin/main..mybranch + * git replay ^origin/next mybranch1 mybranch2 + * we want to be able to determine where to replay the commits. In + * these examples, the branches are probably based on an old version + * of either origin/main or origin/next, so we want to replay on the + * newest version of that branch. In contrast we would want to error + * out if they ran + * git replay ^origin/master ^origin/next mybranch + * git replay mybranch~2..mybranch + * the first of those because there's no unique base to choose, and + * the second because they'd likely just be replaying commits on top + * of the same commit and not making any difference. + */ + for (i = 0; i < info->nr; i++) { + struct rev_cmdline_entry *e = info->rev + i; + struct object_id oid; + char *fullname = NULL; + + if (!(e->flags & BOTTOM)) + continue; + + /* + * We need a unique base commit to know where to replay; error + * out if not unique. + * + * Also, we usually don't want to replay commits on the same + * base they started on, so only accept this as the base if + * it uniquely names some ref. + */ + if (bottom_commits++ || + dwim_ref(e->name, strlen(e->name), &oid, &fullname, 0) != 1) + die(_("cannot determine where to replay commits; please specify --onto")); + + free(fullname); + new_base = lookup_commit_reference_gently(the_repository, + &e->item->oid, 1); + } + + return new_base; +} + static struct commit *pick_regular_commit(struct commit *pickme, struct commit *last_commit, struct merge_options *merge_opt, @@ -117,7 +165,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) int ret = 0; const char * const replay_usage[] = { - N_("git replay --onto ..."), + N_("git replay [--onto ] ..."), NULL }; struct option replay_options[] = { @@ -130,12 +178,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, replay_options, replay_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); - if (!onto_name) { - error(_("option --onto is mandatory")); - usage_with_options(replay_usage, replay_options); - } - - onto = peel_committish(onto_name); repo_init_revisions(the_repository, &revs, prefix); @@ -151,6 +193,11 @@ int cmd_replay(int argc, const char **argv, const char *prefix) revs.topo_order = 1; revs.simplify_history = 0; + if (onto_name) + onto = peel_committish(onto_name); + else + onto = guess_new_base(&revs.cmdline); + if (prepare_revision_walk(&revs) < 0) { ret = error(_("error preparing revisions")); goto cleanup; From patchwork Fri Apr 7 07:24:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204529 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 40CB3C76196 for ; Fri, 7 Apr 2023 07:25:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231918AbjDGHZm (ORCPT ); Fri, 7 Apr 2023 03:25:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239888AbjDGHZU (ORCPT ); Fri, 7 Apr 2023 03:25:20 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 19C2AA5FA for ; Fri, 7 Apr 2023 00:25:00 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id g5so1663641wrb.5 for ; Fri, 07 Apr 2023 00:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852292; 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=F22gc7CMK/IkrjH4+XLPMdpTh5abX8hRPQ02EpYvKw8=; b=DItG7t18iazyRmpe0Frej0mNcWerYfAmM4SkHqm0JhYpabWD8bnVOzl8FiOQLavdT0 dNxi0DQBhjLZJN7C5NDw83Gu1pcWSEPwsbYSszUseV5/jTMgANQkuXKVUjuxalQh/Af1 JkGC+/lcLvpi+XOGshvLNb5Sr+7zLmzjP2+bQGPnLr1pyXJMCXHrkC7q89BB2OflcPjx H6rtt+lb52wlESQ/W5O0UHjayGfVM6kvOfQDczavUciXuWD1eByAxBrp2Osw9wJXq/qY QCAuWe3gqXq/8SNnh85hEA1SrjwkFlCKWmm+f36UvH12+zCwRYOfBUN3nLCm3taUO3db I2rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852292; 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=F22gc7CMK/IkrjH4+XLPMdpTh5abX8hRPQ02EpYvKw8=; b=mZteavdBrF8KV8WB/Q9vAIfvxImuMolfvwnhcIwKYLAjmZkrEb6OKM1/LuDWVtRQ8j Dm4O1G6Nhe3evrKdloOYDlOuxJ3wz51r53SHSpAdDJzfu4ApEYmTBqGagucxFB0U2oK2 mnq589xugYEnM42bFUY17fh2Ky/H88/Nu7qB6Mf0LidZyNKA4DaUsFxigX7LM6TWNpXh FhFZunjPetq7MYcbL6AdrPdb0I2pv7llcMGV+T1aBw+ChwPO7Nmk+rgA2+0EIYbHsRGd MLryH7qrR6zSOhter0OUxZZxh2mUchsupMx61BOsAK7z8+weqR78atAmsQTj/igSnHno yT+A== X-Gm-Message-State: AAQBX9fHJsUguD6KwvdyMxPoZuavx6xoktz1vEdm2PfpC321L3Mj/4DH xe59EfDHHdmimk3aMA1rsyOgJD2tiuefew== X-Google-Smtp-Source: AKy350Y1PDW0UTauQ7DTNQdNFkyOc7YQ5ESlckBFfTGz6EQOUm5GWYSsFlfA8tmT4g6hS4rMIL9nSw== X-Received: by 2002:a5d:4530:0:b0:2ef:45d2:6ac2 with SMTP id j16-20020a5d4530000000b002ef45d26ac2mr617859wra.27.1680852292192; Fri, 07 Apr 2023 00:24:52 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:51 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 13/14] replay: add different modes Date: Fri, 7 Apr 2023 09:24:14 +0200 Message-Id: <20230407072415.1360068-14-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren There is already a 'rebase' mode with `--onto`. Let's add an 'advance' or 'cherry-pick' mode with `--advance`. This new mode will make the target branch advance as we replay commits onto it. While at it, let's also add a `--contained` that can be used along with `--onto` to rebase all the branches contained in the argument. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- Documentation/git-replay.txt | 58 +++++++++-- builtin/replay.c | 185 +++++++++++++++++++++++++++++------ t/t3650-replay-basics.sh | 45 +++++++++ 3 files changed, 247 insertions(+), 41 deletions(-) diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt index ce2cafc42e..d714c72188 100644 --- a/Documentation/git-replay.txt +++ b/Documentation/git-replay.txt @@ -9,7 +9,7 @@ git-replay - Replay commits on a different base, without touching working tree SYNOPSIS -------- [verse] -'git replay' [--onto ] ... +'git replay' [--contained] [--onto | --advance ] ... DESCRIPTION ----------- @@ -20,11 +20,12 @@ references. However, the output of this command is meant to be used as input to `git update-ref --stdin`, which would update the relevant branches. -When the `--onto ` option is not passed, the commits will be -replayed onto a base guessed from the ``. For example -if the `` is `origin/main..mybranch` then `mybranch` -was probably based on an old version of `origin/main`, so we will -replay it on the newest version of that branch. +When neither the `--onto ` option nor the +`--advance ` option are passed, the commits will be replayed +onto a base guessed from the ``. For example if the +`` is `origin/main..mybranch` then `mybranch` was +probably based on an old version of `origin/main`, so we will replay +it on the newest version of that branch. OPTIONS ------- @@ -33,9 +34,17 @@ OPTIONS Starting point at which to create the new commits. May be any valid commit, and not just an existing branch name. + -The update-ref commands in the output will update the branch(es) -in the revision range to point at the new commits (in other -words, this mimics a rebase operation). +When `--onto` is specified, the update-ref command(s) in the output will +update the branch(es) in the revision range to point at the new +commits (in other words, this mimics a rebase operation). + +--advance :: + Starting point at which to create the new commits; must be a + branch name. ++ +When `--advance` is specified, the update-ref command(s) in the output +will update the branch passed as an argument to `--advance` to point at +the new commits (in other words, this mimics a cherry-pick operation). :: Range of commits to replay; see "Specifying Ranges" in @@ -51,7 +60,10 @@ input to `git update-ref --stdin`. It is basically of the form: update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} -where the number of refs updated depend on the arguments passed. +where the number of refs updated depend on the arguments passed. When +using `--advance`, the number of refs updated is always one, but for +`--onto`, it can be one or more (rebasing multiple branches +simultaneously is supported). EXIT STATUS ----------- @@ -71,6 +83,32 @@ $ git replay --onto target origin/main..mybranch update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH} ------------ +To cherry-pick the commits from mybranch onto target: + +------------ +$ git replay --advance target origin/main..mybranch +update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH} +------------ + +Note that the first two examples replay the exact same commits and on +top of the exact same new base, they only differ in that the first +provides instructions to make mybranch point at the new commits and +the second provides instructions to make target point at them. + +What if you have a stack of branches, one depending upon another, and +you'd really like to rebase the whole set? + +------------ +$ git replay --contained --onto origin/main origin/main..tipbranch +update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} +update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} +update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH} +------------ + +In contrast, trying to do this with rebase would require 3 separate +rebases, eacho of which involves a different and and +forces you to first check out each branch in turn. + When calling `git replay`, one does not need to specify a range of commits to replay using the syntax `A..B`; any range expression will do: diff --git a/builtin/replay.c b/builtin/replay.c index af948af73c..63b3ad518e 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -12,6 +12,7 @@ #include "parse-options.h" #include "refs.h" #include "revision.h" +#include "strmap.h" static const char *short_commit_name(struct commit *commit) { @@ -75,10 +76,24 @@ static struct commit *create_commit(struct tree *tree, return (struct commit *)obj; } -static struct commit *guess_new_base(struct rev_cmdline_info *info) +struct ref_info { + struct commit *onto; + struct strset positive_refs; + struct strset negative_refs; + int positive_refexprs; + int negative_refexprs; +}; + +static void get_ref_information(struct rev_cmdline_info *cmd_info, + struct ref_info *ref_info) { - struct commit *new_base = NULL; - int i, bottom_commits = 0; + int i; + + ref_info->onto = NULL; + strset_init(&ref_info->positive_refs); + strset_init(&ref_info->negative_refs); + ref_info->positive_refexprs = 0; + ref_info->negative_refexprs = 0; /* * When the user specifies e.g. @@ -95,32 +110,110 @@ static struct commit *guess_new_base(struct rev_cmdline_info *info) * the second because they'd likely just be replaying commits on top * of the same commit and not making any difference. */ - for (i = 0; i < info->nr; i++) { - struct rev_cmdline_entry *e = info->rev + i; + for (i = 0; i < cmd_info->nr; i++) { + struct rev_cmdline_entry *e = cmd_info->rev + i; struct object_id oid; + const char *refexpr = e->name; char *fullname = NULL; + int can_uniquely_dwim = 1; + + if (*refexpr == '^') + refexpr++; + if (dwim_ref(refexpr, strlen(refexpr), &oid, &fullname, 0) != 1) + can_uniquely_dwim = 0; + + if (e->flags & BOTTOM) { + if (can_uniquely_dwim) + strset_add(&ref_info->negative_refs, fullname); + if (!ref_info->negative_refexprs) + ref_info->onto = lookup_commit_reference_gently(the_repository, + &e->item->oid, 1); + ref_info->negative_refexprs++; + } else { + if (can_uniquely_dwim) + strset_add(&ref_info->positive_refs, fullname); + ref_info->positive_refexprs++; + } - if (!(e->flags & BOTTOM)) - continue; + free(fullname); + } +} +static void determine_replay_mode(struct rev_cmdline_info *cmd_info, + const char *onto_name, + const char **advance_name, + struct commit **onto, + struct strset **update_refs) +{ + struct ref_info rinfo; + + get_ref_information(cmd_info, &rinfo); + if (!rinfo.positive_refexprs) + die(_("need some commits to replay")); + if (onto_name && *advance_name) + die(_("--onto and --advance are incompatible")); + else if (onto_name) { + *onto = peel_committish(onto_name); + if (rinfo.positive_refexprs < + strset_get_size(&rinfo.positive_refs)) + die(_("all positive revisions given must be references")); + } else if (*advance_name) { + struct object_id oid; + char *fullname = NULL; + + *onto = peel_committish(*advance_name); + if (dwim_ref(*advance_name, strlen(*advance_name), + &oid, &fullname, 0) == 1) { + *advance_name = fullname; + } else { + die(_("argument to --advance must be a reference")); + } + if (rinfo.positive_refexprs > 1) + die(_("cannot advance target with multiple source branches because ordering would be ill-defined")); + } else { + int positive_refs_complete = ( + rinfo.positive_refexprs == + strset_get_size(&rinfo.positive_refs)); + int negative_refs_complete = ( + rinfo.negative_refexprs == + strset_get_size(&rinfo.negative_refs)); /* - * We need a unique base commit to know where to replay; error - * out if not unique. - * - * Also, we usually don't want to replay commits on the same - * base they started on, so only accept this as the base if - * it uniquely names some ref. + * We need either positive_refs_complete or + * negative_refs_complete, but not both. */ - if (bottom_commits++ || - dwim_ref(e->name, strlen(e->name), &oid, &fullname, 0) != 1) - die(_("cannot determine where to replay commits; please specify --onto")); - - free(fullname); - new_base = lookup_commit_reference_gently(the_repository, - &e->item->oid, 1); + if (rinfo.negative_refexprs > 0 && + positive_refs_complete == negative_refs_complete) + die(_("cannot implicitly determine whether this is an --advance or --onto operation")); + if (negative_refs_complete) { + struct hashmap_iter iter; + struct strmap_entry *entry; + + if (rinfo.negative_refexprs == 0) + die(_("all positive revisions given must be references")); + else if (rinfo.negative_refexprs > 1) + die(_("cannot implicitly determine whether this is an --advance or --onto operation")); + else if (rinfo.positive_refexprs > 1) + die(_("cannot advance target with multiple source branches because ordering would be ill-defined")); + + /* Only one entry, but we have to loop to get it */ + strset_for_each_entry(&rinfo.negative_refs, + &iter, entry) { + *advance_name = entry->key; + } + } else { /* positive_refs_complete */ + if (rinfo.negative_refexprs > 1) + die(_("cannot implicitly determine correct base for --onto")); + if (rinfo.negative_refexprs == 1) + *onto = rinfo.onto; + } } - - return new_base; + if (!*advance_name) { + *update_refs = xcalloc(1, sizeof(**update_refs)); + **update_refs = rinfo.positive_refs; + memset(&rinfo.positive_refs, 0, sizeof(**update_refs)); + } + strset_clear(&rinfo.negative_refs); + strset_clear(&rinfo.positive_refs); } static struct commit *pick_regular_commit(struct commit *pickme, @@ -155,29 +248,41 @@ static struct commit *pick_regular_commit(struct commit *pickme, int cmd_replay(int argc, const char **argv, const char *prefix) { - struct commit *onto; + const char *advance_name = NULL; + struct commit *onto = NULL; const char *onto_name = NULL; - struct commit *last_commit = NULL; + int contained = 0; + struct rev_info revs; + struct commit *last_commit = NULL; struct commit *commit; struct merge_options merge_opt; struct merge_result result; + struct strset *update_refs = NULL; int ret = 0; const char * const replay_usage[] = { - N_("git replay [--onto ] ..."), + N_("git replay [--contained] [--onto | --advance ] ..."), NULL }; struct option replay_options[] = { + OPT_STRING(0, "advance", &advance_name, + N_("branch"), + N_("make replay advance given branch")), OPT_STRING(0, "onto", &onto_name, N_("revision"), N_("replay onto given commit")), + OPT_BOOL(0, "contained", &contained, + N_("advance all branches contained in revision-range")), OPT_END() }; argc = parse_options(argc, argv, prefix, replay_options, replay_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); + if (advance_name && contained) + die(_("options '%s' and '%s' cannot be used together"), + "--advance", "--contained"); repo_init_revisions(the_repository, &revs, prefix); @@ -193,10 +298,11 @@ int cmd_replay(int argc, const char **argv, const char *prefix) revs.topo_order = 1; revs.simplify_history = 0; - if (onto_name) - onto = peel_committish(onto_name); - else - onto = guess_new_base(&revs.cmdline); + determine_replay_mode(&revs.cmdline, onto_name, &advance_name, + &onto, &update_refs); + + if (!onto) /* FIXME: Should handle replaying down to root commit */ + die("Replaying down to root commit is not supported yet!"); if (prepare_revision_walk(&revs) < 0) { ret = error(_("error preparing revisions")); @@ -206,6 +312,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); merge_opt.show_rename_progress = 0; + result.tree = get_commit_tree(onto); last_commit = onto; while ((commit = get_revision(&revs))) { @@ -243,12 +350,16 @@ int cmd_replay(int argc, const char **argv, const char *prefix) oid_to_hex(&commit->object.oid)); } + /* Update any necessary branches */ + if (advance_name) + continue; decoration = get_name_decoration(&commit->object); if (!decoration) continue; - while (decoration) { - if (decoration->type == DECORATION_REF_LOCAL) { + if (decoration->type == DECORATION_REF_LOCAL && + (contained || strset_contains(update_refs, + decoration->name))) { printf("update %s %s %s\n", decoration->name, oid_to_hex(&last_commit->object.oid), @@ -258,11 +369,23 @@ int cmd_replay(int argc, const char **argv, const char *prefix) } } + /* In --advance mode, advance the target ref */ + if (result.clean == 1 && advance_name) { + printf("update %s %s %s\n", + advance_name, + oid_to_hex(&last_commit->object.oid), + oid_to_hex(&onto->object.oid)); + } + /* Cleanup */ merge_finalize(&merge_opt, &result); ret = result.clean; cleanup: + if (update_refs) { + strset_clear(update_refs); + free(update_refs); + } release_revisions(&revs); /* Return */ diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh index f55b71763a..976032ad18 100755 --- a/t/t3650-replay-basics.sh +++ b/t/t3650-replay-basics.sh @@ -60,4 +60,49 @@ test_expect_success 'using replay to rebase two branches, one on top of other' ' test_cmp expect result ' +test_expect_success 'using replay to perform basic cherry-pick' ' + # The differences between this test and the last one are: + # --advance vs --onto + # 2nd field of result is refs/heads/main vs. refs/heads/topic2 + # 4th field of result is hash for main instead of hash for topic2 + + git replay --advance main topic1..topic2 >result && + + test_line_count = 1 result && + + git log --format=%s $(cut -f 3 -d " " result) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/main " >expect && + printf "%s " $(cut -f 3 -d " " result) >>expect && + git rev-parse main >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay to also rebase a contained branch' ' + git replay --contained --onto main main..topic3 >result && + + test_line_count = 2 result && + cut -f 3 -d " " result >new-branch-tips && + + git log --format=%s $(head -n 1 new-branch-tips) >actual && + test_write_lines F C M L B A >expect && + test_cmp expect actual && + + git log --format=%s $(tail -n 1 new-branch-tips) >actual && + test_write_lines H G F C M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic1 " >expect && + printf "%s " $(head -n 1 new-branch-tips) >>expect && + git rev-parse topic1 >>expect && + printf "update refs/heads/topic3 " >>expect && + printf "%s " $(tail -n 1 new-branch-tips) >>expect && + git rev-parse topic3 >>expect && + + test_cmp expect result +' + test_done From patchwork Fri Apr 7 07:24:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Couder X-Patchwork-Id: 13204527 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 08884C76196 for ; Fri, 7 Apr 2023 07:25:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240009AbjDGHZd (ORCPT ); Fri, 7 Apr 2023 03:25:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239864AbjDGHZU (ORCPT ); Fri, 7 Apr 2023 03:25:20 -0400 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 1A427A5FB for ; Fri, 7 Apr 2023 00:25:00 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id l12so41583623wrm.10 for ; Fri, 07 Apr 2023 00:24:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680852293; 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=b9gQ2z7BlbZD5MQRDAhyZ+Q1fAvPiUX4YUmtuhbuWHQ=; b=HmD6nP2hihx9nDDnLopVZNBeLAPgSuJ+0PXBFout82tAaQ1lhzW4ok0FxCDaK/vi/i R/VZDtPkDDV3ypRVakXUhOfTq3nq4EagQq1o7bDj1EG/CkqpA45I3Ydpan4bENym7VqO deaLLSt4fgW3mOnZLu6Vt+P+uov1yFdf/KPbed50MXcij4Zti9hf7os2ML6EFt4Iya8h 6wMx01E7NVNJ2SEp0FdpszwUPMMzuRGdrJ+a3lPMkru6nPpYXzPqfip9ZetkU6AlnbX3 hflCTvVxOZ0mpx4ZE5yj6tPhgYXD3rkdW5AKu5C1xhBrflbQo2s6ed05Ft346YIeGofZ UJ2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680852293; 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=b9gQ2z7BlbZD5MQRDAhyZ+Q1fAvPiUX4YUmtuhbuWHQ=; b=yvHVSFweC96WufYsF7pmr3EYK2xI3TxM/uMks+xIKVbZtCkR2ue/4+ErKWUjZMKHUB 2kioWgHSEuWjNAItUaa1kqu1a/Odws7g/o1P99ocCrl3z/w9jWqVY32xhYiQOJtSGEJ8 01GraXIgCvbBalJMO8m2rQ7IZtj9VLobWSJpoc8U38vTiAN/ckw4o8J/wGliLWiAZdYY A0ORlUOOFeGNqUsUPZflVKSatVNTFFaOQfIQ0XzRRIKcOqspNHew/A68KRVQtdDE/PZj WEibWt6vLte4QtvkX7ceTCr3kiuQU/yU+XUT2nJOxO9e7dmDgFOpD/q58lHRuAVJnyWN c0Ag== X-Gm-Message-State: AAQBX9d0iMmmKDQXnbtLCQGyl070K5D4SE6X4vdS0QXlON1dcsFt8svC CmlZPpE4+AzU8Hb2jJh/vdLURfENEtVbgA== X-Google-Smtp-Source: AKy350YdV499oHPgwWaxyGJaKlgtC0dSQOKTkxvOtVXwJVjyZT/auqnxidd1B0yQXcxC3loAyRj/Cw== X-Received: by 2002:adf:e846:0:b0:2c7:efb:dded with SMTP id d6-20020adfe846000000b002c70efbddedmr637745wrn.24.1680852292986; Fri, 07 Apr 2023 00:24:52 -0700 (PDT) Received: from christian-Precision-5550.lan ([2001:861:3f04:7ca0:90e:3fb7:fec2:981]) by smtp.gmail.com with ESMTPSA id f7-20020a5d6647000000b002da1261aa44sm3782761wrw.48.2023.04.07.00.24.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 00:24:52 -0700 (PDT) From: Christian Couder To: git@vger.kernel.org Cc: Junio C Hamano , Patrick Steinhardt , Johannes Schindelin , Elijah Newren , John Cai , Christian Couder Subject: [PATCH 14/14] replay: stop assuming replayed branches do not diverge Date: Fri, 7 Apr 2023 09:24:15 +0200 Message-Id: <20230407072415.1360068-15-christian.couder@gmail.com> X-Mailer: git-send-email 2.40.0.228.gb2eb5bb98e In-Reply-To: <20230407072415.1360068-1-christian.couder@gmail.com> References: <20230407072415.1360068-1-christian.couder@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Elijah Newren The replay command is able to replay multiple branches but when some of them are based on other replayed branches, their commit should be replayed onto already replayed commits. For this purpose, let's store the replayed commit and its original commit in a key value store, so that we can easily find and reused a replayed commit instead of the original one. Co-authored-by: Christian Couder Signed-off-by: Elijah Newren Signed-off-by: Christian Couder --- builtin/replay.c | 44 ++++++++++++++++++++++++++-------- t/t3650-replay-basics.sh | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/builtin/replay.c b/builtin/replay.c index 63b3ad518e..71815d5ca3 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -216,20 +216,33 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info, strset_clear(&rinfo.positive_refs); } +static struct commit *mapped_commit(kh_oid_map_t *replayed_commits, + struct commit *commit, + struct commit *fallback) +{ + khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid); + if (pos == kh_end(replayed_commits)) + return fallback; + return kh_value(replayed_commits, pos); +} + static struct commit *pick_regular_commit(struct commit *pickme, - struct commit *last_commit, + kh_oid_map_t *replayed_commits, + struct commit *onto, struct merge_options *merge_opt, struct merge_result *result) { - struct commit *base; + struct commit *base, *replayed_base; struct tree *pickme_tree, *base_tree; base = pickme->parents->item; + replayed_base = mapped_commit(replayed_commits, base, onto); + result->tree = get_commit_tree(replayed_base); pickme_tree = get_commit_tree(pickme); base_tree = get_commit_tree(base); - merge_opt->branch1 = short_commit_name(last_commit); + merge_opt->branch1 = short_commit_name(replayed_base); merge_opt->branch2 = short_commit_name(pickme); merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2); @@ -243,7 +256,7 @@ static struct commit *pick_regular_commit(struct commit *pickme, merge_opt->ancestor = NULL; if (!result->clean) return NULL; - return create_commit(result->tree, pickme, last_commit); + return create_commit(result->tree, pickme, replayed_base); } int cmd_replay(int argc, const char **argv, const char *prefix) @@ -259,6 +272,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix) struct merge_options merge_opt; struct merge_result result; struct strset *update_refs = NULL; + kh_oid_map_t *replayed_commits; int ret = 0; const char * const replay_usage[] = { @@ -312,18 +326,20 @@ int cmd_replay(int argc, const char **argv, const char *prefix) init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); merge_opt.show_rename_progress = 0; - - result.tree = get_commit_tree(onto); last_commit = onto; + replayed_commits = kh_init_oid_map(); while ((commit = get_revision(&revs))) { const struct name_decoration *decoration; + khint_t pos; + int hr; if (!commit->parents) die(_("replaying down to root commit is not supported yet!")); if (commit->parents->next) die(_("replaying merge commits is not supported yet!")); - last_commit = pick_regular_commit(commit, last_commit, &merge_opt, &result); + last_commit = pick_regular_commit(commit, replayed_commits, onto, + &merge_opt, &result); if (!last_commit) { /* TODO: handle conflicts in sparse worktree instead */ @@ -350,6 +366,13 @@ int cmd_replay(int argc, const char **argv, const char *prefix) oid_to_hex(&commit->object.oid)); } + /* Record commit -> last_commit mapping */ + pos = kh_put_oid_map(replayed_commits, commit->object.oid, &hr); + if (hr == 0) + BUG("Duplicate rewritten commit: %s\n", + oid_to_hex(&commit->object.oid)); + kh_value(replayed_commits, pos) = last_commit; + /* Update any necessary branches */ if (advance_name) continue; @@ -379,13 +402,14 @@ int cmd_replay(int argc, const char **argv, const char *prefix) /* Cleanup */ merge_finalize(&merge_opt, &result); - ret = result.clean; - -cleanup: + kh_destroy_oid_map(replayed_commits); if (update_refs) { strset_clear(update_refs); free(update_refs); } + ret = result.clean; + +cleanup: release_revisions(&revs); /* Return */ diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh index 976032ad18..b13bb7502c 100755 --- a/t/t3650-replay-basics.sh +++ b/t/t3650-replay-basics.sh @@ -105,4 +105,56 @@ test_expect_success 'using replay to also rebase a contained branch' ' test_cmp expect result ' +test_expect_success 'using replay to rebase multiple divergent branches' ' + git replay --onto main ^topic1 topic2 topic4 >result && + + test_line_count = 2 result && + cut -f 3 -d " " result >new-branch-tips && + + git log --format=%s $(head -n 1 new-branch-tips) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + git log --format=%s $(tail -n 1 new-branch-tips) >actual && + test_write_lines J I M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic2 " >expect && + printf "%s " $(head -n 1 new-branch-tips) >>expect && + git rev-parse topic2 >>expect && + printf "update refs/heads/topic4 " >>expect && + printf "%s " $(tail -n 1 new-branch-tips) >>expect && + git rev-parse topic4 >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay to rebase multiple divergent branches, including contained ones' ' + git replay --contained --onto main ^main topic2 topic3 topic4 >result && + + test_line_count = 4 result && + cut -f 3 -d " " result >new-branch-tips && + + >expect && + for i in 2 1 3 4 + do + printf "update refs/heads/topic$i " >>expect && + printf "%s " $(grep topic$i result | cut -f 3 -d " ") >>expect && + git rev-parse topic$i >>expect || return 1 + done && + + test_cmp expect result && + + test_write_lines F C M L B A >expect1 && + test_write_lines E D C M L B A >expect2 && + test_write_lines H G F C M L B A >expect3 && + test_write_lines J I M L B A >expect4 && + + for i in 1 2 3 4 + do + git log --format=%s $(grep topic$i result | cut -f 3 -d " ") >actual && + test_cmp expect$i actual || return 1 + done +' + test_done