Skip to content

Conversation

@mhagger
Copy link
Owner

@mhagger mhagger commented Oct 30, 2015

The last step of "simplify to rebase" is chaining a bunch of commits from the merge diagram into a linear history, taking the metadata for the new commits from the metadata for the corresponding original commits. Currently that is done using specialized code.

But this procedure can be generalized. Add a new function create_commit_chain() that can string an arbitrary list of commits together using arbitrary commits as the source of the metadata. Also add a method MergeState._simplify_to_path() that can do the same thing using commits taken from a MergeState.

Rewrite MergeState.simplify_to_rebase() to use the new functions.

This will make it easier to add other new functionality (not part of this PR):

  • The new "simplify to rebase reversed" feature suggested in rebase-reversed goal for those struggling with what gets rebased where #89. In this case we need to chain together the commits from the bottom edge of the merge diagram rather than the right edge.
  • Dropping commits that don't do anything. Often the same logical change is made on both of the branches, with the result that one of the commits in the rebased branch doesn't do anything. git rebase allows such commits to be omitted from the rebased result, and we should too.
  • Incremental git revert. Reverting one or more commits from your current branch can result in merge conflicts just like merging or rebasing. But these conflicts can be resolved in an incremental way using the approach discussed here. "Simplify to path" could be used to string the results together while omitting the unwanted commits and their inverses.
  • git rebase --onto is quite a bit like the previous case, followed by appending more commits to the end of the second branch, as described midway through this comment. For that matter, some uses of git cherry-pick are equivalent to git rebase --onto, though I doubt that many scenarios thought of as cherry-picking would be practical to do incrementally.
  • We could make it possible to break off an incremental merge before all of the conflicts are resolved, resulting (for example) in a branch being rebased not to the tip of the target branch, but rather to partway along the target branch. This would be a way to "lock in" part of the work of a rebase/merge.
  • For a completed full incremental merge, the commits from the two branches can be interleaved in arbitrary order by chaining together commits along any zig-zag path that starts at the upper-left and ends at the lower-right of the diagram. I'm not sure that this is useful though, given that it requires the full incremental merge to be completed first, and that is usually quite expensive.

This change is only very lightly tested. (We need better tests!)

Use the new function in the implementation of
MergeState.simplify_to_rebase.
Use the new function in the implementation of
MergeState.simplify_to_rebase(). Also fix and improve an error
message.
Use the new function in the implementation of
MergeState.simplify_to_rebase().
@mhagger mhagger merged commit e8da000 into master Jul 9, 2016
@mhagger mhagger deleted the simplify-to-path branch July 9, 2016 07:54
@waldyrious
Copy link
Contributor

@mhagger I'm very interested in the "break off an incremental merge before all of the conflicts are resolved" use case. Could you give a few hints in how to do that? Just the basis steps to get started, later I'd gladly contribute something more fleshed out to the readme :)

@mhagger
Copy link
Owner Author

mhagger commented Jul 10, 2016

Note that "incremental git revert" is implemented in PR #100. It would be great if people would cautiously test it.

@waldyrious: I just wrote up the idea "break off an incremental merge" in more detail as issue #101.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants