From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-3.2 required=3.0 tests=AWL,BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by dcvr.yhbt.net (Postfix) with ESMTP id 7A1631F404 for ; Thu, 19 Apr 2018 12:13:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751565AbeDSMNH (ORCPT ); Thu, 19 Apr 2018 08:13:07 -0400 Received: from mout.gmx.net ([212.227.17.21]:52253 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751379AbeDSMNG (ORCPT ); Thu, 19 Apr 2018 08:13:06 -0400 Received: from [192.168.0.129] ([37.201.195.116]) by mail.gmx.com (mrgmx101 [212.227.17.168]) with ESMTPSA (Nemesis) id 0Lip2P-1eYyfN1uJR-00cycO; Thu, 19 Apr 2018 14:12:56 +0200 Date: Thu, 19 Apr 2018 14:12:39 +0200 (DST) From: Johannes Schindelin X-X-Sender: virtualbox@MININT-6BKU6QN.europe.corp.microsoft.com To: git@vger.kernel.org cc: Junio C Hamano , Jacob Keller , Stefan Beller , Philip Oakley , Eric Sunshine , Phillip Wood , Igor Djordjevic , Johannes Sixt , Sergey Organov , =?UTF-8?Q?Martin_=C3=85gren?= Subject: [PATCH v7 00/17] rebase -i: offer to recreate commit topology In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21.1 (DEB 209 2017-03-23) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Provags-ID: V03:K1:5qPJISGTjFrwz0yoDvXGS9Bjt+8X/xhUlzDkEVEA+khQB+wfvW4 hLyN1fpKpcMV02SgCaLnruV0F+xi5vY6Lf4I8FLW5nGWjEFEnSDC3EDMe2FrklBslZ4vX5O oze2v93dCfoUtL9mXPBKrQF62ncMP2cmnAzlQyQyT2xATByE5xiAsty7v/Bs+XXioQWNRRo iWxZzvmwocmK9tEdiwCXA== X-UI-Out-Filterresults: notjunk:1;V01:K0:JLJKZ9U+kMM=:MA0bHCCHbiB+RWC9ss5OIj 2ihxIkHqhlseRcC6F6zmgZ2y+rFMyS86fNSCmwLmsNloo1o3l8PutqmEiH5ZHYykMpiVpRDkm 4aD6cz5jERH1EwTwbKDWMK1KrtZ99dN/Ow3oYlOW4r0B+YQ7lnNPukwVZ/b+IdIwqRU7Z2SvM Wu3KYdRFD4P5Gg3DmK+QIAdjWb5k4dv2QlVrv1YZbMSPsuJ1vUZAzESXrk98Ibaa5FrFAOgBT rZx6RfOBy1ti8ptNX/rgPuL46485i05vuicqTqvaTLdtaw8vH8SLQnYW5KCQ3Opx0yoQIacgm QHknq5RNyWOxbSjh2YbW1yrpVtjZWJ+0UAsMYVaGfTbuxG+n/ZjmJ2BpUsJv7EYfHsXOk4M7q pUbJczggD2607b7z9iqnEm6xV+QmGDyg7NcKosy9/5/WUQvwqbgCAUhKcZ9OtwuI8mHmu/FxG ZR8V9u0p4sMOkCSrE+WGz9TIg5foAOz0EuQ4VdasNLmyPq9+2WHeaMhpjxYLbFcuyTIYb5MUS g6c8h78tzSIWqwF9FYskUlqUB7wF6y1seD+lt1wDGErSuBgUTl3WjZkffuMQjCFUdgqmcw6yf Vw+eHnOH5Xb09EouCE4Sr6ZWnbJqAR++hfWm7wcPG8NLAH4CJ9+Wy6/UkT79TfZdYMje8BQD7 pY3cadEk42Vd+Weom8QsI1BQeYqYyizMF4iPc7uDpO+3zioc6J/kCga8hgX+3wa88I944XUv5 XgxukbhlQOqX9Xs+ovCD1Hslk8XV5POVwH9a7IW9BdiJsyOW7dYnaVSd1zsdVBJYrEpLFs7mm TOp9tPoi12LdEWbk1NnyJMAJm39Fa5QnByDbdC9T/zXvRj304Y= Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Once upon a time, I dreamt of an interactive rebase that would not flatten branch structure, but instead recreate the commit topology faithfully. My original attempt was --preserve-merges, but that design was so limited that I did not even enable it in interactive mode. Subsequently, it *was* enabled in interactive mode, with the predictable consequences: as the --preserve-merges design does not allow for specifying the parents of merge commits explicitly, all the new commits' parents are defined *implicitly* by the previous commit history, and hence it is *not possible to even reorder commits*. This design flaw cannot be fixed. Not without a complete re-design, at least. This patch series offers such a re-design. Think of --rebase-merges as "--preserve-merges done right". It introduces new verbs for the todo list, `label`, `reset` and `merge`. For a commit topology like this: A - B - C \ / D the generated todo list would look like this: # branch D pick 0123 A label branch-point pick 1234 D label D reset branch-point pick 2345 B merge -C 3456 D # C There are more patches in the pipeline, based on this patch series, but left for later in the interest of reviewable patch series: one mini series to use the sequencer even for `git rebase -i --root`, and another one to add support for octopus merges to --rebase-merges. And then one to allow for rebasing merge commits in a smarter way (this one will need a bit more work, though, as it can result in very complicated, nested merge conflicts *very* easily). Changes since v6: - Reworded the REBASING MERGES section of the man page a bit (thanks, Martin & Phillip!). - The `reset` todo command now refuses to overwrite untracked files (thanks Phillip!). - The do_merge() function was prevented from leaking memory left and right. - Added a nice advice for the case when todo commands were rescheduled. - Refactored the way we get to the original line of any given todo command in the todo list, simplifying even existing code to make it a lot more readable. - Failed `label` and `reset` commands, as well as `merge` that failed before even attempting to merge, are now rescheduled automatically (thanks Phillip and Philip!). - The do_merge() function no longer tries to commit when there are merge conflicts (thanks Phillip!). - When do_merge() failed to run the recursive merge, it no longer claims that there were conflicts (thanks Phillip!). - When the merge failed, we now write out the index before giving `rerere` a chance (d'oh!). Johannes Schindelin (15): sequencer: avoid using errno clobbered by rollback_lock_file() sequencer: make rearrange_squash() a bit more obvious sequencer: refactor how original todo list lines are accessed sequencer: offer helpful advice when a command was rescheduled sequencer: introduce new commands to reset the revision # This is a combination of 2 commits. # This is the 1st commit message: sequencer: fast-forward `merge` commands, if possible rebase-helper --make-script: introduce a flag to rebase merges rebase: introduce the --rebase-merges option sequencer: make refs generated by the `label` command worktree-local sequencer: handle post-rewrite for merge commands rebase --rebase-merges: avoid "empty merges" pull: accept --rebase=merges to recreate the branch topology rebase -i: introduce --rebase-merges=[no-]rebase-cousins rebase -i --rebase-merges: add a section to the man page Phillip Wood (1): rebase --rebase-merges: add test for --keep-empty Stefan Beller (1): git-rebase--interactive: clarify arguments Documentation/config.txt | 8 + Documentation/git-pull.txt | 5 +- Documentation/git-rebase.txt | 147 ++++- builtin/pull.c | 14 +- builtin/rebase--helper.c | 13 +- builtin/remote.c | 18 +- contrib/completion/git-completion.bash | 4 +- git-rebase--interactive.sh | 22 +- git-rebase.sh | 16 + refs.c | 3 +- sequencer.c | 869 +++++++++++++++++++++++-- sequencer.h | 7 + t/t3421-rebase-topology-linear.sh | 1 + t/t3430-rebase-merges.sh | 221 +++++++ 14 files changed, 1288 insertions(+), 60 deletions(-) create mode 100755 t/t3430-rebase-merges.sh base-commit: fe0a9eaf31dd0c349ae4308498c33a5c3794b293 Published-As: https://github.com/dscho/git/releases/tag/recreate-merges-v7 Fetch-It-Via: git fetch https://github.com/dscho/git recreate-merges-v7 Interdiff vs v6: diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index be946de2efb..0ff83b62821 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -849,14 +849,18 @@ merge -C 6f5e4d report-a-bug # Merge 'report-a-bug' In contrast to a regular interactive rebase, there are `label`, `reset` and `merge` commands in addition to `pick` ones. -The `label` command puts a label to whatever will be the current -revision when that command is executed. Internally, these labels are -worktree-local refs that will be deleted when the rebase finishes or -when it is aborted. That way, rebase operations in multiple worktrees -linked to the same repository do not interfere with one another. - -The `reset` command is essentially a `git reset --hard` to the specified -revision (typically a previously-labeled one). +The `label` command associates a label with the current HEAD when that +command is executed. These labels are created as worktree-local refs +(`refs/rewritten/