Skip to content

Add 'reorder' command

Eric Sunshine requested to merge sunshineco/reposurgeon:es/reorder into master

Some tools which convert project history from a file-based revision control system, such as SCCS, RCS, CVS, to a changeset-based system attempt to infer changesets by comparing a file's commit comment and time-stamp against other nearby commits, however, this is only a heuristic, and inference can easily fail. In cases of poor commit hygiene, the resulting history may have many changes from several topics interleaved in an apparently chaotic fashion, which can be difficult to unravel. Fixing such histories typically involves re-ordering commits into topics and optionally squashing those commits into one or more changesets per topic.

The reparent command can re-order commits, however, using it is onerous since each commit must be re-parented individually, while taking care not to introduce cycles. This is bothersome even when merely swapping two commits, but becomes outright painful when many commits are involved since the cognitive load is quite high. A small example from a real lift is instructive as being both difficult to construct and effectively impenetrable, revealing nothing about the final desired commit order.

:166,:171 reparent rebase
:171,:177 reparent rebase
:168,:173 reparent rebase
:154,:168 reparent rebase
:175|:160 reparent --use-order rebase
:158,:179 reparent rebase
:177|:156 reparent --use-order rebase
:156 squash
:164 squash --pushback
:166..:171 squash

To ease this burden, add a reorder command which re-orders a contiguous range of commits. The above complex sequence of re-parenting operations collapses to a single, easy to understand, reorder invocation:

:168,:173,:175,:160,:164,:166,:171,:177,:156,:158 reorder
:156 squash
:164 squash --pushback
:166..:171 squash

Documentation and tests are included.

Merge request reports