From patchwork Tue Aug 4 22:01:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aaron Lipman X-Patchwork-Id: 11701059 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 87B8D14E3 for ; Tue, 4 Aug 2020 22:01:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8828922B45 for ; Tue, 4 Aug 2020 22:01:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kqiWZdOc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728328AbgHDWB1 (ORCPT ); Tue, 4 Aug 2020 18:01:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728052AbgHDWBX (ORCPT ); Tue, 4 Aug 2020 18:01:23 -0400 Received: from mail-qk1-x741.google.com (mail-qk1-x741.google.com [IPv6:2607:f8b0:4864:20::741]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6C14C06174A for ; Tue, 4 Aug 2020 15:01:22 -0700 (PDT) Received: by mail-qk1-x741.google.com with SMTP id l23so39982471qkk.0 for ; Tue, 04 Aug 2020 15:01:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cESbn+0qRyw1H9cXdRoCr2DVijcyjakrqE0qFSjWkWY=; b=kqiWZdOcOjW3apjJkfhpwSWpT58RVlMPqH3G33eCNxGqKQok6mBtct4xakqX3YDLmi w1+3fvUL6ENDQ0TUWHTyO2U8IGzu9qvKVUWU9aVcRdOH6Q+SKoLGWymQ1AQpDxIOpvg2 szF/csZYteQPmqueuebJxCtlfvvKnT9Bx/D7gI/GVbKnKVt9XB+qu+vU5MMcBOoQzQai DM0hWZpZe89SN40Q794KCBQulkmSzw5Orj0Bpv/VEWqp2eWfHDAeavBVHQNqU6tlpevr blomG1ix96R90yAPKxBjHNEgJZ1mXbJtA82ePAPLH54T4AMJj3uCdAUFYKgVvQ89liQT AX6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cESbn+0qRyw1H9cXdRoCr2DVijcyjakrqE0qFSjWkWY=; b=FZUs+X4RiqyvhQ3wjFunU2wfelDMASBaLKcfQeTOUHP1qcaA1spGucuEqi1dZrDJCe Qv9nkAAuyGRwvqoGIBoU/iFwf0WP3rPpv9ZRiCHhDxAz/c83X8qlo1AA8LJ+WAa0HPdV DWDUZb0IKXFIHJgGbf1Zu6upJduyZm1w5pg8znsKWbf2Cm1hgQTCjNqjtsFkkOqeYQpb u8gcQqmJqTrIvwu2e6m7BsOly78iGySdl8G3aidbxnxVlJf+UJQ7RbtxmCAy/+yMG67g sJlPe6RWdRWBK2Dyq+4leSXt+uUodFUB05DlwJ8oKg6tyAAErwY1Vy9o6jcimU0ST3Z1 LVRw== X-Gm-Message-State: AOAM530BXz7mr45JS2q77Kub2VJh1ImjEbW0RlrvdjCqZD5wDItXSog6 IblLDOpclNJ3R1c/Nv9V1TVQPnmPTVoWHg== X-Google-Smtp-Source: ABdhPJzrJ0fBDOmvJxi8nl+AELbSV3cIPD2MNqtZXLftXLv3lXtF1U1q+2cwXVOOd2LKnaJGIsqNUg== X-Received: by 2002:a37:4f07:: with SMTP id d7mr409062qkb.144.1596578481546; Tue, 04 Aug 2020 15:01:21 -0700 (PDT) Received: from localhost.localdomain (c-98-229-3-81.hsd1.vt.comcast.net. [98.229.3.81]) by smtp.gmail.com with ESMTPSA id n33sm231724qtd.43.2020.08.04.15.01.20 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Aug 2020 15:01:21 -0700 (PDT) From: Aaron Lipman To: git@vger.kernel.org Cc: Aaron Lipman Subject: [PATCH v4 1/5] t6030: modernize "git bisect run" tests Date: Tue, 4 Aug 2020 18:01:09 -0400 Message-Id: <20200804220113.5909-2-alipman88@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20200804220113.5909-1-alipman88@gmail.com> References: <20200801175840.1877-1-alipman88@gmail.com> <20200804220113.5909-1-alipman88@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Enforce consistent styling for tests on "git bisect run": - Use "write_script" to abstract away platform-specific details. - Favor current whitespace conventions. - While at it, change "introduced" to "added" in the comments to make them read better. Thanks-to: Martin Ågren Signed-off-by: Aaron Lipman --- t/t6030-bisect-porcelain.sh | 86 ++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 48 deletions(-) diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 36d9b2b2e4..a66c4b89bc 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -243,32 +243,30 @@ test_expect_success 'bisect skip: with commit both bad and skipped' ' ' # We want to automatically find the commit that -# introduced "Another" into hello. -test_expect_success \ - '"git bisect run" simple case' \ - 'echo "#"\!"/bin/sh" > test_script.sh && - echo "grep Another hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && - git bisect start && - git bisect good $HASH1 && - git bisect bad $HASH4 && - git bisect run ./test_script.sh > my_bisect_log.txt && - grep "$HASH3 is the first bad commit" my_bisect_log.txt && - git bisect reset' +# added "Another" into hello. +test_expect_success '"git bisect run" simple case' ' + write_script test_script.sh <<-\EOF && + ! grep Another hello >/dev/null + EOF + git bisect start && + git bisect good $HASH1 && + git bisect bad $HASH4 && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$HASH3 is the first bad commit" my_bisect_log.txt && + git bisect reset +' # We want to automatically find the commit that -# introduced "Ciao" into hello. -test_expect_success \ - '"git bisect run" with more complex "git bisect start"' \ - 'echo "#"\!"/bin/sh" > test_script.sh && - echo "grep Ciao hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && - git bisect start $HASH4 $HASH1 && - git bisect run ./test_script.sh > my_bisect_log.txt && - grep "$HASH4 is the first bad commit" my_bisect_log.txt && - git bisect reset' +# added "Ciao" into hello. +test_expect_success '"git bisect run" with more complex "git bisect start"' ' + write_script test_script.sh <<-\EOF && + ! grep Ciao hello >/dev/null + EOF + git bisect start $HASH4 $HASH1 && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$HASH4 is the first bad commit" my_bisect_log.txt && + git bisect reset +' # $HASH1 is good, $HASH5 is bad, we skip $HASH3 # but $HASH4 is good, @@ -295,24 +293,17 @@ HASH6= test_expect_success 'bisect run & skip: cannot tell between 2' ' add_line_into_file "6: Yet a line." hello && HASH6=$(git rev-parse --verify HEAD) && - echo "#"\!"/bin/sh" > test_script.sh && - echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && - echo "grep line hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && + write_script test_script.sh <<-\EOF && + sed -ne \$p hello | grep Ciao >/dev/null && exit 125 + ! grep line hello >/dev/null + EOF git bisect start $HASH6 $HASH1 && - if git bisect run ./test_script.sh > my_bisect_log.txt - then - echo Oops, should have failed. - false - else - test $? -eq 2 && - grep "first bad commit could be any of" my_bisect_log.txt && - ! grep $HASH3 my_bisect_log.txt && - ! grep $HASH6 my_bisect_log.txt && - grep $HASH4 my_bisect_log.txt && - grep $HASH5 my_bisect_log.txt - fi + test_expect_code 2 git bisect run ./test_script.sh >my_bisect_log.txt && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH3 my_bisect_log.txt && + ! grep $HASH6 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + grep $HASH5 my_bisect_log.txt ' HASH7= @@ -320,14 +311,13 @@ test_expect_success 'bisect run & skip: find first bad' ' git bisect reset && add_line_into_file "7: Should be the last line." hello && HASH7=$(git rev-parse --verify HEAD) && - echo "#"\!"/bin/sh" > test_script.sh && - echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh && - echo "sed -ne \\\$p hello | grep day > /dev/null && exit 125" >> test_script.sh && - echo "grep Yet hello > /dev/null" >> test_script.sh && - echo "test \$? -ne 0" >> test_script.sh && - chmod +x test_script.sh && + write_script test_script.sh <<-\EOF && + sed -ne \$p hello | grep Ciao >/dev/null && exit 125 + sed -ne \$p hello | grep day >/dev/null && exit 125 + ! grep Yet hello >/dev/null + EOF git bisect start $HASH7 $HASH1 && - git bisect run ./test_script.sh > my_bisect_log.txt && + git bisect run ./test_script.sh >my_bisect_log.txt && grep "$HASH6 is the first bad commit" my_bisect_log.txt ' From patchwork Tue Aug 4 22:01:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lipman X-Patchwork-Id: 11701063 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D092C6C1 for ; Tue, 4 Aug 2020 22:01:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C1DBB22B45 for ; Tue, 4 Aug 2020 22:01:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qLcjTKgU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728346AbgHDWBf (ORCPT ); Tue, 4 Aug 2020 18:01:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728212AbgHDWBY (ORCPT ); Tue, 4 Aug 2020 18:01:24 -0400 Received: from mail-qt1-x842.google.com (mail-qt1-x842.google.com [IPv6:2607:f8b0:4864:20::842]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C73A1C061756 for ; Tue, 4 Aug 2020 15:01:23 -0700 (PDT) Received: by mail-qt1-x842.google.com with SMTP id 6so32254840qtt.0 for ; Tue, 04 Aug 2020 15:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KTFJ6Uxl8NKaXlxeUtEcrLbZOtyO1xu4vBqmewPgGDI=; b=qLcjTKgUa+Zq7147zT+1dZbHpszJ+rQoBGz+Uu8GKVvHvfheOHzkEo5DNx6EXG4PhM 86+2VMfMJyGROpalVVbPDgRyGKz+q7bKHREF7+9nXPLfKy3ve8Zpw55PUeqW/pHXSdiQ f8aWFktxX2PWM1+ULqo35ZQ3Tt8CR533gMaYb2SdpB9gtCK+ntbQdlzS54AMsXcW/563 B+Di7w8dXN6+BfKhaHmWHrisyf+eUA0fgrSA8EaQ18HoB4EZYiZBqikhnnR2G1oialaW Wzj6XWnrI9cT07FviaiFQ7neX+Z8CKQw0Gryg8cBKbj8q4i60cEdJnbEXen6LHv8b93C AfUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KTFJ6Uxl8NKaXlxeUtEcrLbZOtyO1xu4vBqmewPgGDI=; b=fxxfYzMfWIAljsodFcZK+k2RbmsfF++/WxhZS98QV1YTaFktY7N+VODksa/6xvPsll 4Fz6B4drhX59qrxpmP5JBUThpmTBYInRVFwUvGoenkmyQj6Col/3lOcQUOm7EG4OkaOe Wzl5uR6YoAY5GCF32FmbHNbMBkGBz3FjrASvJ0icG0ZEwe35xZHiXgM2iFa21uSUOBo2 PX2UcLuVwT/bInaH1ODxKFW5G96xkn9sa5GLRvbJ4hrxPMQ7GMd1M221rUrsuu59E4X8 okPK7AdvGuN5HPrqWoH5H5+7LrXozsrCwwZ1gxnTwCgGdXGmFS3LkiW6bksAka8pW0h4 ZYFA== X-Gm-Message-State: AOAM533N/axBg7E1RAae/pEUY2ZgGqlDhWomeMeR5nOx+WjE1jNme3ee aeOVJtUv52na+LmsYFluwS9yK2U1zujHLw== X-Google-Smtp-Source: ABdhPJyvgjppSPQWzRnDcwUbkZsEadqPMcx1Ibpe7FOc8obl/PT4EObPEmOmEh6WqWWKo4HoAXzR2A== X-Received: by 2002:ac8:320b:: with SMTP id x11mr198302qta.320.1596578482510; Tue, 04 Aug 2020 15:01:22 -0700 (PDT) Received: from localhost.localdomain (c-98-229-3-81.hsd1.vt.comcast.net. [98.229.3.81]) by smtp.gmail.com with ESMTPSA id n33sm231724qtd.43.2020.08.04.15.01.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Aug 2020 15:01:22 -0700 (PDT) From: Aaron Lipman To: git@vger.kernel.org Cc: Aaron Lipman Subject: [PATCH v4 2/5] rev-list: allow bisect and first-parent flags Date: Tue, 4 Aug 2020 18:01:10 -0400 Message-Id: <20200804220113.5909-3-alipman88@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20200804220113.5909-1-alipman88@gmail.com> References: <20200801175840.1877-1-alipman88@gmail.com> <20200804220113.5909-1-alipman88@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Add first_parent_only parameter to find_bisection(), removing the barrier that prevented combining the --bisect and --first-parent flags when using git rev-list Based-on-patch-by: Tiago Botelho Signed-off-by: Aaron Lipman --- Documentation/rev-list-options.txt | 7 ++--- bisect.c | 28 ++++++++++++------- bisect.h | 2 +- builtin/rev-list.c | 2 +- revision.c | 3 -- t/t6000-rev-list-misc.sh | 4 +-- t/t6002-rev-list-bisect.sh | 45 ++++++++++++++++++++++++++++++ 7 files changed, 70 insertions(+), 21 deletions(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index b01b2b6773..d3117ce51b 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -128,8 +128,7 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit). because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits - brought in to your history by such a merge. Cannot be - combined with --bisect. + brought in to your history by such a merge. --not:: Reverses the meaning of the '{caret}' prefix (or lack thereof) @@ -207,7 +206,7 @@ ifndef::git-rev-list[] Pretend as if the bad bisection ref `refs/bisect/bad` was listed and as if it was followed by `--not` and the good bisection refs `refs/bisect/good-*` on the command - line. Cannot be combined with --first-parent. + line. endif::git-rev-list[] --stdin:: @@ -743,7 +742,7 @@ outputs 'midpoint', the output of the two commands would be of roughly the same length. Finding the change which introduces a regression is thus reduced to a binary search: repeatedly generate and test new 'midpoint's until the commit chain is of length -one. Cannot be combined with --first-parent. +one. --bisect-vars:: This calculates the same as `--bisect`, except that refs in diff --git a/bisect.c b/bisect.c index d5e830410f..a11fdb1473 100644 --- a/bisect.c +++ b/bisect.c @@ -88,15 +88,16 @@ static inline void weight_set(struct commit_list *elem, int weight) **commit_weight_at(&commit_weight, elem->item) = weight; } -static int count_interesting_parents(struct commit *commit) +static int count_interesting_parents(struct commit *commit, int first_parent_only) { struct commit_list *p; int count; for (count = 0, p = commit->parents; p; p = p->next) { - if (p->item->object.flags & UNINTERESTING) - continue; - count++; + if (!(p->item->object.flags & UNINTERESTING)) + count++; + if (first_parent_only) + break; } return count; } @@ -259,7 +260,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n */ static struct commit_list *do_find_bisection(struct commit_list *list, int nr, int *weights, - int find_all) + int find_all, int first_parent_only) { int n, counted; struct commit_list *p; @@ -271,7 +272,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list, unsigned flags = commit->object.flags; *commit_weight_at(&commit_weight, p->item) = &weights[n++]; - switch (count_interesting_parents(commit)) { + switch (count_interesting_parents(commit, first_parent_only)) { case 0: if (!(flags & TREESAME)) { weight_set(p, 1); @@ -314,6 +315,8 @@ static struct commit_list *do_find_bisection(struct commit_list *list, continue; if (weight(p) != -2) continue; + if (first_parent_only) + BUG("shouldn't be calling count-distance in fp mode"); weight_set(p, count_distance(p)); clear_distance(list); @@ -332,7 +335,10 @@ static struct commit_list *do_find_bisection(struct commit_list *list, if (0 <= weight(p)) continue; - for (q = p->item->parents; q; q = q->next) { + + for (q = p->item->parents; + q; + q = first_parent_only ? NULL : q->next) { if (q->item->object.flags & UNINTERESTING) continue; if (0 <= weight(q)) @@ -370,7 +376,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list, } void find_bisection(struct commit_list **commit_list, int *reaches, - int *all, int find_all) + int *all, int find_all, int first_parent_only) { int nr, on_list; struct commit_list *list, *p, *best, *next, *last; @@ -406,7 +412,7 @@ void find_bisection(struct commit_list **commit_list, int *reaches, weights = xcalloc(on_list, sizeof(*weights)); /* Do the real work of finding bisection commit. */ - best = do_find_bisection(list, nr, weights, find_all); + best = do_find_bisection(list, nr, weights, find_all, first_parent_only); if (best) { if (!find_all) { list->item = best->item; @@ -991,6 +997,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int enum bisect_error res = BISECT_OK; struct object_id *bisect_rev; char *steps_msg; + int first_parent_only = 0; /* TODO: pass --first-parent flag from git bisect start */ read_bisect_terms(&term_bad, &term_good); if (read_bisect_refs()) @@ -1001,11 +1008,12 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int return res; bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1); + revs.first_parent_only = first_parent_only; revs.limited = 1; bisect_common(&revs); - find_bisection(&revs.commits, &reaches, &all, !!skipped_revs.nr); + find_bisection(&revs.commits, &reaches, &all, !!skipped_revs.nr, first_parent_only); revs.commits = managed_skipped(revs.commits, &tried); if (!revs.commits) { diff --git a/bisect.h b/bisect.h index 8bad8d8391..a63af0505f 100644 --- a/bisect.h +++ b/bisect.h @@ -12,7 +12,7 @@ struct repository; * best commit, as chosen by `find_all`. */ void find_bisection(struct commit_list **list, int *reaches, int *all, - int find_all); + int find_all, int first_parent_only); struct commit_list *filter_skipped(struct commit_list *list, struct commit_list **tried, diff --git a/builtin/rev-list.c b/builtin/rev-list.c index f520111eda..d1a14596b2 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -638,7 +638,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (bisect_list) { int reaches, all; - find_bisection(&revs.commits, &reaches, &all, bisect_find_all); + find_bisection(&revs.commits, &reaches, &all, bisect_find_all, revs.first_parent_only); if (bisect_show_vars) return show_bisect_vars(&info, reaches, all); diff --git a/revision.c b/revision.c index 6de29cdf7a..e628d5ea56 100644 --- a/revision.c +++ b/revision.c @@ -2891,9 +2891,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s if (!revs->reflog_info && revs->grep_filter.use_reflog_filter) die("cannot use --grep-reflog without --walk-reflogs"); - if (revs->first_parent_only && revs->bisect) - die(_("--first-parent is incompatible with --bisect")); - if (revs->line_level_traverse && (revs->diffopt.output_format & ~(DIFF_FORMAT_PATCH | DIFF_FORMAT_NO_OUTPUT))) die(_("-L does not yet support diff formats besides -p and -s")); diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index 3bb0e4ff8f..fc4d55dcb2 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -128,8 +128,8 @@ test_expect_success 'rev-list can negate index objects' ' test_cmp expect actual ' -test_expect_success '--bisect and --first-parent can not be combined' ' - test_must_fail git rev-list --bisect --first-parent HEAD +test_expect_success '--bisect and --first-parent can be combined' ' + git rev-list --bisect --first-parent HEAD ' test_expect_success '--header shows a NUL after each commit' ' diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index a661408038..7fc0f75ca5 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -263,4 +263,49 @@ test_expect_success 'rev-parse --bisect can default to good/bad refs' ' test_cmp expect.sorted actual.sorted ' +test_output_expect_success "--bisect --first-parent" 'git rev-list --bisect --first-parent E ^F' < expect.unsorted < expect && +git rev-list --bisect-all --first-parent E ^F > actual && +test_cmp actual expect +' + test_done From patchwork Tue Aug 4 22:01:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lipman X-Patchwork-Id: 11701065 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 18C8D14E3 for ; Tue, 4 Aug 2020 22:01:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 17DF722B42 for ; Tue, 4 Aug 2020 22:01:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SUvMVwr4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728367AbgHDWBg (ORCPT ); Tue, 4 Aug 2020 18:01:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728233AbgHDWBZ (ORCPT ); Tue, 4 Aug 2020 18:01:25 -0400 Received: from mail-qt1-x843.google.com (mail-qt1-x843.google.com [IPv6:2607:f8b0:4864:20::843]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A8367C06174A for ; Tue, 4 Aug 2020 15:01:24 -0700 (PDT) Received: by mail-qt1-x843.google.com with SMTP id 6so32254875qtt.0 for ; Tue, 04 Aug 2020 15:01:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6qD/KMzXnMPYcPFAhYELz+gUWQUtCdooaXdQIHfYjOs=; b=SUvMVwr4p2ZvrnlX1Gv61KkRv4AQ0rfSKHddaLiUVLVZIqBzl0pSCUgmhDYuB+/Ns9 9ubLTZFEX7bUM9ez7bEAxkDQsHgA5/KkRxx59+bQv4HTS73PuF7D+wBApKhsUbpDpYUf UUAtWbmbwbb8wtLnBI6oyuk4YIy3n2B/nQcHMGVrerPKWdNNOsMm7WZSf7JfRnanU3sp uueq8REPfk188fOyv9FBGVsez0MqJGmJHRBm68BBmp5Urd6B0O0Wf5YkYXhZYscuF7bU p4zqIXOHD6f6JYHFBp2QE68xJQswufwo7YiiMUJ0GQtX0Z7fJC5i9BTA6w21qSHqBKH0 MFWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6qD/KMzXnMPYcPFAhYELz+gUWQUtCdooaXdQIHfYjOs=; b=GcebWSjmdG0Q1UFVkfSTAGrAjzeV1KDt/cYDSAnqcNj6S+2IRMPvJWvjc5IEeGaNIu UGW80LH2tFiG3lM81T/qLtfW6bvwYm1OvKMtLEtjMTB6qzMnM6dqD7bFDHlG6ABw1jIK xSg19xiYtEI95uTnIW+6keAR+gLORGYs7MgvE55EJKmHDMcNZQ0VlQ4RPnLTCAaWEN9w cX4qU9XSwVZze3e/TteDuI8a4bguamITiqIl6dml1BFiUL4VIl4j5VTAp06IzMcZDWns dQum63kjRIXOnZ4KpD5u9PsKrKrbzk/tc/vEcCk5Et27PKBFvsuXvYkb55Y87/WckW+M 0OKQ== X-Gm-Message-State: AOAM530Qjnqq4INPf36gy9HDaMKTp5XqffJ+fHgDu0ae4lBxFU3Zkqh+ BirF97TtePs8My7dqMjd8gZcudmd6AttJw== X-Google-Smtp-Source: ABdhPJw/HkibknuoKOmM1cAyWDcnPzLptNDLCWlX3ns7njZM1DNEvAeoUrhcpUkJiHKenIUmTR7gcg== X-Received: by 2002:ac8:1948:: with SMTP id g8mr211920qtk.354.1596578483249; Tue, 04 Aug 2020 15:01:23 -0700 (PDT) Received: from localhost.localdomain (c-98-229-3-81.hsd1.vt.comcast.net. [98.229.3.81]) by smtp.gmail.com with ESMTPSA id n33sm231724qtd.43.2020.08.04.15.01.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Aug 2020 15:01:22 -0700 (PDT) From: Aaron Lipman To: git@vger.kernel.org Cc: Aaron Lipman Subject: [PATCH v4 3/5] cmd_bisect__helper: defer parsing no-checkout flag Date: Tue, 4 Aug 2020 18:01:11 -0400 Message-Id: <20200804220113.5909-4-alipman88@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20200804220113.5909-1-alipman88@gmail.com> References: <20200801175840.1877-1-alipman88@gmail.com> <20200804220113.5909-1-alipman88@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org cmd_bisect__helper() is intended as a temporary shim layer serving as an interface for git-bisect.sh. This function and git-bisect.sh should eventually be replaced by a C implementation, cmd_bisect(), serving as an entrypoint for all "git bisect ..." shell commands: cmd_bisect() will only parse the first token following "git bisect", and dispatch the remaining args to the appropriate function ["bisect_start()", "bisect_next()", etc.]. Thus, cmd_bisect__helper() should not be responsible for parsing flags like --no-checkout. Instead, let the --no-checkout flag remain in the argv array, so it may be evaluated alongside the other options already parsed by bisect_start(). Signed-off-by: Aaron Lipman --- bisect.c | 3 ++- bisect.h | 4 +--- builtin/bisect--helper.c | 14 ++++++-------- git-bisect.sh | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/bisect.c b/bisect.c index a11fdb1473..950ff6f533 100644 --- a/bisect.c +++ b/bisect.c @@ -989,7 +989,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good) * If no_checkout is non-zero, the bisection process does not * checkout the trial commit but instead simply updates BISECT_HEAD. */ -enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int no_checkout) +enum bisect_error bisect_next_all(struct repository *r, const char *prefix) { struct rev_info revs; struct commit_list *tried; @@ -997,6 +997,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int enum bisect_error res = BISECT_OK; struct object_id *bisect_rev; char *steps_msg; + int no_checkout = ref_exists("BISECT_HEAD"); int first_parent_only = 0; /* TODO: pass --first-parent flag from git bisect start */ read_bisect_terms(&term_bad, &term_good); diff --git a/bisect.h b/bisect.h index a63af0505f..7f30b94db3 100644 --- a/bisect.h +++ b/bisect.h @@ -58,9 +58,7 @@ enum bisect_error { BISECT_INTERNAL_SUCCESS_MERGE_BASE = -11 }; -enum bisect_error bisect_next_all(struct repository *r, - const char *prefix, - int no_checkout); +enum bisect_error bisect_next_all(struct repository *r, const char *prefix); int estimate_bisect_steps(int all); diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index 73f9324ad7..95a15b918f 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -18,7 +18,7 @@ static GIT_PATH_FUNC(git_path_head_name, "head-name") static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES") static const char * const git_bisect_helper_usage[] = { - N_("git bisect--helper --next-all [--no-checkout]"), + N_("git bisect--helper --next-all"), N_("git bisect--helper --write-terms "), N_("git bisect--helper --bisect-clean-state"), N_("git bisect--helper --bisect-reset []"), @@ -420,9 +420,9 @@ static int bisect_append_log_quoted(const char **argv) return res; } -static int bisect_start(struct bisect_terms *terms, int no_checkout, - const char **argv, int argc) +static int bisect_start(struct bisect_terms *terms, const char **argv, int argc) { + int no_checkout = 0; int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0; int flags, pathspec_pos, res = 0; struct string_list revs = STRING_LIST_INIT_DUP; @@ -631,7 +631,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) BISECT_TERMS, BISECT_START } cmdmode = 0; - int no_checkout = 0, res = 0, nolog = 0; + int res = 0, nolog = 0; struct option options[] = { OPT_CMDMODE(0, "next-all", &cmdmode, N_("perform 'git bisect next'"), NEXT_ALL), @@ -653,8 +653,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) N_("print out the bisect terms"), BISECT_TERMS), OPT_CMDMODE(0, "bisect-start", &cmdmode, N_("start the bisect session"), BISECT_START), - OPT_BOOL(0, "no-checkout", &no_checkout, - N_("update BISECT_HEAD instead of checking out the current commit")), OPT_BOOL(0, "no-log", &nolog, N_("no log for BISECT_WRITE")), OPT_END() @@ -670,7 +668,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) switch (cmdmode) { case NEXT_ALL: - res = bisect_next_all(the_repository, prefix, no_checkout); + res = bisect_next_all(the_repository, prefix); break; case WRITE_TERMS: if (argc != 2) @@ -712,7 +710,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) break; case BISECT_START: set_terms(&terms, "bad", "good"); - res = bisect_start(&terms, no_checkout, argv, argc); + res = bisect_start(&terms, argv, argc); break; default: return error("BUG: unknown subcommand '%d'", cmdmode); diff --git a/git-bisect.sh b/git-bisect.sh index f03fbb18f0..c7580e51a0 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -153,7 +153,7 @@ bisect_next() { git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD $TERM_GOOD|| exit # Perform all bisection computation, display and checkout - git bisect--helper --next-all $(git rev-parse --verify -q BISECT_HEAD > /dev/null && echo --no-checkout) + git bisect--helper --next-all res=$? # Check if we should exit because bisection is finished From patchwork Tue Aug 4 22:01:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lipman X-Patchwork-Id: 11701067 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA12914DD for ; Tue, 4 Aug 2020 22:01:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D372222B42 for ; Tue, 4 Aug 2020 22:01:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BKkKXSLy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728374AbgHDWBh (ORCPT ); Tue, 4 Aug 2020 18:01:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728235AbgHDWB0 (ORCPT ); Tue, 4 Aug 2020 18:01:26 -0400 Received: from mail-qt1-x843.google.com (mail-qt1-x843.google.com [IPv6:2607:f8b0:4864:20::843]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4FD8C061757 for ; Tue, 4 Aug 2020 15:01:25 -0700 (PDT) Received: by mail-qt1-x843.google.com with SMTP id v22so26300938qtq.8 for ; Tue, 04 Aug 2020 15:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I5Es3QrVp5S44OB7wFFcCjvWFqu4E1AXZNuENo39h8Y=; b=BKkKXSLyX/0vd8BisqUn0Nwm8WhvpEBoJ6N6EcAlVhjSBpmXWBy/UzBtiw7qtsyhx7 hnrmrTCN8Zll03wc+WGSKkKTRvycj7/5SlCvJzdnfZNJDfSBXU/JbrchZvYtLNAwOnu9 jy0cACgaH+PB1Hx1Dcm44aK9m1AIcXMad2Opqvvck7zHkqYCKsKpug5mlUyWi2NBOpZC 85a8kxHLKGcrE8LobYEx6siutopWc8dKv7bQEijw6Cfy1FU0jtvKpzLhN8IyaVRCPLzX AF5e+dDquu0Kze6Ip8cxcF3WzLly52j0wKoVP0p10LynsaWSR6GeMokcuOITN8HaFc5e 1GZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=I5Es3QrVp5S44OB7wFFcCjvWFqu4E1AXZNuENo39h8Y=; b=cWa+3PqlGAeCvBUjH97Fqp0OoH7Dc+vxEyqmVVeP1eOzGD7GtDjxIxYQDLS/1mCB/7 yhsVPYLrmxQ1PxnsDecLYdve0idYj7noFnDsUFT7z5lu/UrhTUyhcsAGHaNkWnBpuTmX vIpfCK3qgiCTGPTlGhFUyqWOYQbEUY2eZP4fXCMF7/nhicybmLMrpPro7MURdPooXSoE HrfEGatEM7ml1+bbbhOQfwE0z7EDRlLHwKY80pYe+gswDT8rRD1lqgo4r0ZrBvVtQwVZ jDQpAGtQI/tfaA9v/9XG6Dyo3sL1IOk+W5/IhrE5XqIQ3LZCVivUEKKtQL7TDnU4YlsB 8AXg== X-Gm-Message-State: AOAM53305Wg4QT09oq9nd8+ltVqWrKM5X3Ob7HI7GJGINncjT94U48oy vWycN+ZhVzSdUjUFZ9e6xwPTGvV7p9VukA== X-Google-Smtp-Source: ABdhPJwkjo9oMuRiH7Xy9FRKRQynbc/cg/RpJIpHpuEMWc/Vlv+uuvSI9P0++9eWLXk8XoJGce3X/A== X-Received: by 2002:ac8:6d2f:: with SMTP id r15mr170583qtu.281.1596578484534; Tue, 04 Aug 2020 15:01:24 -0700 (PDT) Received: from localhost.localdomain (c-98-229-3-81.hsd1.vt.comcast.net. [98.229.3.81]) by smtp.gmail.com with ESMTPSA id n33sm231724qtd.43.2020.08.04.15.01.23 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Aug 2020 15:01:23 -0700 (PDT) From: Aaron Lipman To: git@vger.kernel.org Cc: Aaron Lipman Subject: [PATCH v4 4/5] bisect: introduce first-parent flag Date: Tue, 4 Aug 2020 18:01:12 -0400 Message-Id: <20200804220113.5909-5-alipman88@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20200804220113.5909-1-alipman88@gmail.com> References: <20200801175840.1877-1-alipman88@gmail.com> <20200804220113.5909-1-alipman88@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Upon seeing a merge commit when bisecting, this option may be used to follow only the first parent. In detecting regressions introduced through the merging of a branch, the merge commit will be identified as introduction of the bug and its ancestors will be ignored. This option is particularly useful in avoiding false positives when a merged branch contained broken or non-buildable commits, but the merge itself was OK. Signed-off-by: Aaron Lipman --- Documentation/git-bisect.txt | 13 ++++++++++++- bisect.c | 5 ++++- builtin/bisect--helper.c | 9 ++++++++- t/t6030-bisect-porcelain.sh | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 7586c5a843..0e993e4587 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -17,7 +17,7 @@ The command takes various subcommands, and different options depending on the subcommand: git bisect start [--term-{old,good}= --term-{new,bad}=] - [--no-checkout] [ [...]] [--] [...] + [--no-checkout] [--first-parent] [ [...]] [--] [...] git bisect (bad|new|) [] git bisect (good|old|) [...] git bisect terms [--term-good | --term-bad] @@ -365,6 +365,17 @@ does not require a checked out tree. + If the repository is bare, `--no-checkout` is assumed. +--first-parent:: ++ +Follow only the first parent commit upon seeing a merge commit. ++ +In detecting regressions introduced through the merging of a branch, the merge +commit will be identified as introduction of the bug and its ancestors will be +ignored. ++ +This option is particularly useful in avoiding false positives when a merged +branch contained broken or non-buildable commits, but the merge itself was OK. + EXAMPLES -------- diff --git a/bisect.c b/bisect.c index 950ff6f533..bc4241b51f 100644 --- a/bisect.c +++ b/bisect.c @@ -15,6 +15,7 @@ #include "commit-slab.h" #include "commit-reach.h" #include "object-store.h" +#include "dir.h" static struct oid_array good_revs; static struct oid_array skipped_revs; @@ -460,6 +461,7 @@ static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN") static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START") static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG") static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS") +static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT") static GIT_PATH_FUNC(git_path_head_name, "head-name") static void read_bisect_paths(struct argv_array *array) @@ -998,7 +1000,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) struct object_id *bisect_rev; char *steps_msg; int no_checkout = ref_exists("BISECT_HEAD"); - int first_parent_only = 0; /* TODO: pass --first-parent flag from git bisect start */ + int first_parent_only = file_exists(git_path_bisect_first_parent()); read_bisect_terms(&term_bad, &term_good); if (read_bisect_refs()) @@ -1142,6 +1144,7 @@ int bisect_clean_state(void) unlink_or_warn(git_path_bisect_names()); unlink_or_warn(git_path_bisect_run()); unlink_or_warn(git_path_bisect_terms()); + unlink_or_warn(git_path_bisect_first_parent()); /* Cleanup head-name if it got left by an old version of git-bisect */ unlink_or_warn(git_path_head_name()); /* diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index 95a15b918f..a055147f19 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -16,6 +16,7 @@ static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START") static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG") static GIT_PATH_FUNC(git_path_head_name, "head-name") static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES") +static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT") static const char * const git_bisect_helper_usage[] = { N_("git bisect--helper --next-all"), @@ -27,7 +28,7 @@ static const char * const git_bisect_helper_usage[] = { N_("git bisect--helper --bisect-next-check []"), N_("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]"), N_("git bisect--helper --bisect-start [--term-{old,good}= --term-{new,bad}=]" - "[--no-checkout] [ [...]] [--] [...]"), + " [--no-checkout] [--first-parent] [ [...]] [--] [...]"), NULL }; @@ -423,6 +424,7 @@ static int bisect_append_log_quoted(const char **argv) static int bisect_start(struct bisect_terms *terms, const char **argv, int argc) { int no_checkout = 0; + int first_parent_only = 0; int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0; int flags, pathspec_pos, res = 0; struct string_list revs = STRING_LIST_INIT_DUP; @@ -452,6 +454,8 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc) break; } else if (!strcmp(arg, "--no-checkout")) { no_checkout = 1; + } else if (!strcmp(arg, "--first-parent")) { + first_parent_only = 1; } else if (!strcmp(arg, "--term-good") || !strcmp(arg, "--term-old")) { i++; @@ -576,6 +580,9 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc) */ write_file(git_path_bisect_start(), "%s\n", start_head.buf); + if (first_parent_only) + write_file(git_path_bisect_first_parent(), "\n"); + if (no_checkout) { if (get_oid(start_head.buf, &oid) < 0) { res = error(_("invalid ref: '%s'"), start_head.buf); diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index a66c4b89bc..b886529e59 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -448,6 +448,24 @@ test_expect_success 'many merge bases creation' ' grep "$SIDE_HASH5" merge_bases.txt ' +# We want to automatically find the merge that +# added "line" into hello. +test_expect_success '"git bisect run --first-parent" simple case' ' + git rev-list --first-parent $B_HASH ^$HASH4 >first_parent_chain.txt && + write_script test_script.sh <<-\EOF && + grep $(git rev-parse HEAD) first_parent_chain.txt || exit -1 + ! grep line hello >/dev/null + EOF + git bisect start --first-parent && + test_path_is_file ".git/BISECT_FIRST_PARENT" && + git bisect good $HASH4 && + git bisect bad $B_HASH && + git bisect run ./test_script.sh >my_bisect_log.txt && + grep "$B_HASH is the first bad commit" my_bisect_log.txt && + git bisect reset && + test_path_is_missing .git/BISECT_FIRST_PARENT +' + test_expect_success 'good merge bases when good and bad are siblings' ' git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt && test_i18ngrep "merge base must be tested" my_bisect_log.txt && From patchwork Tue Aug 4 22:01:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lipman X-Patchwork-Id: 11701069 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DFA8F14DD for ; Tue, 4 Aug 2020 22:01:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D707F22B45 for ; Tue, 4 Aug 2020 22:01:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="d6tr+YhF" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728378AbgHDWBj (ORCPT ); Tue, 4 Aug 2020 18:01:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728300AbgHDWB1 (ORCPT ); Tue, 4 Aug 2020 18:01:27 -0400 Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDE0BC06179E for ; Tue, 4 Aug 2020 15:01:26 -0700 (PDT) Received: by mail-qt1-x841.google.com with SMTP id v22so26300970qtq.8 for ; Tue, 04 Aug 2020 15:01:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Kk7/ry4u1aOxybhFBfiBIK1sa7OKpM/m/efGeRLKYqo=; b=d6tr+YhFArzNHRJTlCpM2dK7DLuGbphRoY6vv1zQzxKwZueGSWAs+B4yPOh9v0dViN f4ROyO3zqa0EtALOR2blGTNpaK/L5L/+XttoG8j0Phr3JrOZ2J2edKwN86r/KX5Sb8dT O4suSdoFCRIB0K+ErGC2DrfX8WjmdJrHGwTxvk/2y7MgQ0ZeYiTkIm3o1SQjGDBhkb4i swFNMFwVneIaateRjVXb/R1ue+uCXqWK7D0tQuPAhUoJuDOANmm8ntQQHlBcyWDruFGM 0mO9U8UJ5Ft0U8J860kWeDS9zk3VzmOIBnP3VHV9W83yQ2hqp73dsgWQ4pAUAJftIKgM jJAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Kk7/ry4u1aOxybhFBfiBIK1sa7OKpM/m/efGeRLKYqo=; b=U081GjV8nRBwayZqYEPtn98yuFcxk0itPNN6TJsssQxSf/OZUJQT4EmErz6nWIuQOl xiZwHNeZv+9dMBhw7c1cACDoQkG1XBG2/xpvslWPx3YjQotmt6HS5T+WVnBo6KTce7Nk GxzKIji/YUMoHuN74EW6FYK0zYdnQnbULN1xolpmtk+EryosSvxqODGHCia639ILGNOv SKuLdog3S8ZFn51CXL/dMN8axX9jlJ21kcbqsDUn1VVPuYc/Ei6HYAt+QlUnDMx/+XPI /V3/zyP18c/Ie2MraVrn7ocTuNDoS1T90H4voSXbjftTZeG+Ifift3XaybTEtEb9+oYB Rplg== X-Gm-Message-State: AOAM530Tk4pKxgLAWvQIEVwxMA3stTBZW6fM+AxJxKJgPkiacdIXGi/V tvNENXmZ/jMyBnzZcbfziIBHw8B3f/obuQ== X-Google-Smtp-Source: ABdhPJyDHOELY20FmC+ZVLc64SCtAqpDKvD3lXP+2tdL7IkAD3k5E+y/gmm8GVtYzEp18nzD8TfqSQ== X-Received: by 2002:ac8:118d:: with SMTP id d13mr186208qtj.87.1596578485650; Tue, 04 Aug 2020 15:01:25 -0700 (PDT) Received: from localhost.localdomain (c-98-229-3-81.hsd1.vt.comcast.net. [98.229.3.81]) by smtp.gmail.com with ESMTPSA id n33sm231724qtd.43.2020.08.04.15.01.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Aug 2020 15:01:24 -0700 (PDT) From: Aaron Lipman To: git@vger.kernel.org Cc: Aaron Lipman Subject: [PATCH v4 5/5] bisect: combine args passed to find_bisection() Date: Tue, 4 Aug 2020 18:01:13 -0400 Message-Id: <20200804220113.5909-6-alipman88@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20200804220113.5909-1-alipman88@gmail.com> References: <20200801175840.1877-1-alipman88@gmail.com> <20200804220113.5909-1-alipman88@gmail.com> MIME-Version: 1.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Now that find_bisection() accepts multiple boolean arguments, these may be combined into a single unsigned integer in order to declutter some of the code in bisect.c Also, rename the existing "flags" bitfield to "commit_flags", to explicitly differentiate it from the new "bisect_flags" bitfield. Based-on-patch-by: Harald Nordgren Signed-off-by: Aaron Lipman --- bisect.c | 67 +++++++++++++++++++++++++--------------------- bisect.h | 5 +++- builtin/rev-list.c | 9 ++++++- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/bisect.c b/bisect.c index bc4241b51f..1585fcc6ad 100644 --- a/bisect.c +++ b/bisect.c @@ -89,7 +89,7 @@ static inline void weight_set(struct commit_list *elem, int weight) **commit_weight_at(&commit_weight, elem->item) = weight; } -static int count_interesting_parents(struct commit *commit, int first_parent_only) +static int count_interesting_parents(struct commit *commit, unsigned bisect_flags) { struct commit_list *p; int count; @@ -97,7 +97,7 @@ static int count_interesting_parents(struct commit *commit, int first_parent_onl for (count = 0, p = commit->parents; p; p = p->next) { if (!(p->item->object.flags & UNINTERESTING)) count++; - if (first_parent_only) + if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY) break; } return count; @@ -137,7 +137,7 @@ static void show_list(const char *debug, int counted, int nr, for (p = list; p; p = p->next) { struct commit_list *pp; struct commit *commit = p->item; - unsigned flags = commit->object.flags; + unsigned commit_flags = commit->object.flags; enum object_type type; unsigned long size; char *buf = read_object_file(&commit->object.oid, &type, @@ -146,9 +146,9 @@ static void show_list(const char *debug, int counted, int nr, int subject_len; fprintf(stderr, "%c%c%c ", - (flags & TREESAME) ? ' ' : 'T', - (flags & UNINTERESTING) ? 'U' : ' ', - (flags & COUNTED) ? 'C' : ' '); + (commit_flags & TREESAME) ? ' ' : 'T', + (commit_flags & UNINTERESTING) ? 'U' : ' ', + (commit_flags & COUNTED) ? 'C' : ' '); if (*commit_weight_at(&commit_weight, p->item)) fprintf(stderr, "%3d", weight(p)); else @@ -173,9 +173,9 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr) best = list; for (p = list; p; p = p->next) { int distance; - unsigned flags = p->item->object.flags; + unsigned commit_flags = p->item->object.flags; - if (flags & TREESAME) + if (commit_flags & TREESAME) continue; distance = weight(p); if (nr - distance < distance) @@ -214,9 +214,9 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n for (p = list, cnt = 0; p; p = p->next) { int distance; - unsigned flags = p->item->object.flags; + unsigned commit_flags = p->item->object.flags; - if (flags & TREESAME) + if (commit_flags & TREESAME) continue; distance = weight(p); if (nr - distance < distance) @@ -261,7 +261,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n */ static struct commit_list *do_find_bisection(struct commit_list *list, int nr, int *weights, - int find_all, int first_parent_only) + unsigned bisect_flags) { int n, counted; struct commit_list *p; @@ -270,12 +270,12 @@ static struct commit_list *do_find_bisection(struct commit_list *list, for (n = 0, p = list; p; p = p->next) { struct commit *commit = p->item; - unsigned flags = commit->object.flags; + unsigned commit_flags = commit->object.flags; *commit_weight_at(&commit_weight, p->item) = &weights[n++]; - switch (count_interesting_parents(commit, first_parent_only)) { + switch (count_interesting_parents(commit, bisect_flags)) { case 0: - if (!(flags & TREESAME)) { + if (!(commit_flags & TREESAME)) { weight_set(p, 1); counted++; show_list("bisection 2 count one", @@ -316,13 +316,13 @@ static struct commit_list *do_find_bisection(struct commit_list *list, continue; if (weight(p) != -2) continue; - if (first_parent_only) + if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY) BUG("shouldn't be calling count-distance in fp mode"); weight_set(p, count_distance(p)); clear_distance(list); /* Does it happen to be at exactly half-way? */ - if (!find_all && halfway(p, nr)) + if (!(bisect_flags & FIND_BISECTION_ALL) && halfway(p, nr)) return p; counted++; } @@ -332,14 +332,14 @@ static struct commit_list *do_find_bisection(struct commit_list *list, while (counted < nr) { for (p = list; p; p = p->next) { struct commit_list *q; - unsigned flags = p->item->object.flags; + unsigned commit_flags = p->item->object.flags; if (0 <= weight(p)) continue; for (q = p->item->parents; q; - q = first_parent_only ? NULL : q->next) { + q = bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY ? NULL : q->next) { if (q->item->object.flags & UNINTERESTING) continue; if (0 <= weight(q)) @@ -353,7 +353,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list, * add one for p itself if p is to be counted, * otherwise inherit it from q directly. */ - if (!(flags & TREESAME)) { + if (!(commit_flags & TREESAME)) { weight_set(p, weight(q)+1); counted++; show_list("bisection 2 count one", @@ -363,21 +363,21 @@ static struct commit_list *do_find_bisection(struct commit_list *list, weight_set(p, weight(q)); /* Does it happen to be at exactly half-way? */ - if (!find_all && halfway(p, nr)) + if (!(bisect_flags & FIND_BISECTION_ALL) && halfway(p, nr)) return p; } } show_list("bisection 2 counted all", counted, nr, list); - if (!find_all) + if (!(bisect_flags & FIND_BISECTION_ALL)) return best_bisection(list, nr); else return best_bisection_sorted(list, nr); } void find_bisection(struct commit_list **commit_list, int *reaches, - int *all, int find_all, int first_parent_only) + int *all, unsigned bisect_flags) { int nr, on_list; struct commit_list *list, *p, *best, *next, *last; @@ -393,16 +393,16 @@ void find_bisection(struct commit_list **commit_list, int *reaches, for (nr = on_list = 0, last = NULL, p = *commit_list; p; p = next) { - unsigned flags = p->item->object.flags; + unsigned commit_flags = p->item->object.flags; next = p->next; - if (flags & UNINTERESTING) { + if (commit_flags & UNINTERESTING) { free(p); continue; } p->next = last; last = p; - if (!(flags & TREESAME)) + if (!(commit_flags & TREESAME)) nr++; on_list++; } @@ -413,9 +413,9 @@ void find_bisection(struct commit_list **commit_list, int *reaches, weights = xcalloc(on_list, sizeof(*weights)); /* Do the real work of finding bisection commit. */ - best = do_find_bisection(list, nr, weights, find_all, first_parent_only); + best = do_find_bisection(list, nr, weights, bisect_flags); if (best) { - if (!find_all) { + if (!(bisect_flags & FIND_BISECTION_ALL)) { list->item = best->item; free_commit_list(list->next); best = list; @@ -1000,23 +1000,30 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) struct object_id *bisect_rev; char *steps_msg; int no_checkout = ref_exists("BISECT_HEAD"); - int first_parent_only = file_exists(git_path_bisect_first_parent()); + unsigned bisect_flags = 0; read_bisect_terms(&term_bad, &term_good); if (read_bisect_refs()) die(_("reading bisect refs failed")); + if (file_exists(git_path_bisect_first_parent())) + bisect_flags |= FIND_BISECTION_FIRST_PARENT_ONLY; + + if (skipped_revs.nr) + bisect_flags |= FIND_BISECTION_ALL; + res = check_good_are_ancestors_of_bad(r, prefix, no_checkout); if (res) return res; bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1); - revs.first_parent_only = first_parent_only; + + revs.first_parent_only = !!(bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY); revs.limited = 1; bisect_common(&revs); - find_bisection(&revs.commits, &reaches, &all, !!skipped_revs.nr, first_parent_only); + find_bisection(&revs.commits, &reaches, &all, bisect_flags); revs.commits = managed_skipped(revs.commits, &tried); if (!revs.commits) { diff --git a/bisect.h b/bisect.h index 7f30b94db3..ec24ac2d7e 100644 --- a/bisect.h +++ b/bisect.h @@ -12,7 +12,7 @@ struct repository; * best commit, as chosen by `find_all`. */ void find_bisection(struct commit_list **list, int *reaches, int *all, - int find_all, int first_parent_only); + unsigned bisect_flags); struct commit_list *filter_skipped(struct commit_list *list, struct commit_list **tried, @@ -23,6 +23,9 @@ struct commit_list *filter_skipped(struct commit_list *list, #define BISECT_SHOW_ALL (1<<0) #define REV_LIST_QUIET (1<<1) +#define FIND_BISECTION_ALL (1u<<0) +#define FIND_BISECTION_FIRST_PARENT_ONLY (1u<<1) + struct rev_list_info { struct rev_info *revs; int flags; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index d1a14596b2..25c6c3b38d 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -637,8 +637,15 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (bisect_list) { int reaches, all; + unsigned bisect_flags = 0; - find_bisection(&revs.commits, &reaches, &all, bisect_find_all, revs.first_parent_only); + if (bisect_find_all) + bisect_flags |= FIND_BISECTION_ALL; + + if (revs.first_parent_only) + bisect_flags |= FIND_BISECTION_FIRST_PARENT_ONLY; + + find_bisection(&revs.commits, &reaches, &all, bisect_flags); if (bisect_show_vars) return show_bisect_vars(&info, reaches, all);