On Wed, Feb 02, 2022 at 04:18:39PM -0800, Elijah Newren wrote: > On Wed, Feb 2, 2022 at 2:01 PM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > > > Elijah Newren <newren@xxxxxxxxx> writes: > > > > > Yes, you are reading right. I think the cherry-pick/rebase > > > replacement actually deserves a separate command from what merges > > > should use; replaying a sequence of commits just has a number of UI > > > differences and abilities that I think pull it in a different > > > direction. > > > > I completely disagree. Each individual step in a sequence of > > replaying commits in order (or in reverse order) should be > > scriptable as a single merge-tree that takes "apply the change to go > > from A^ to A on X". Sequencing and placing UI around it is a job > > for the script that drives merge-tree. > > Adding such an ability to merge-tree would be trivial -- it basically > involves just two things: (1) accepting one extra argument, and (2) > calling merge_incore_nonrecursive() instead of > merge_incore_recursive(). > > However, I think forking a subprocess for every merge of a series of > commits is a completely unreasonable overhead, so even if we provide > such an option to merge-tree, I still want a separate plumbing-ish > tool that does non-worktree/non-index replaying of commits which is > not written as a driver of merge-tree. That other tool should just > call merge_incore_nonrecursive() directly. And such a tool, since it > should handle an arbitrary number of commits, should certainly be able > to handle just one commit. From that angle, it feels like adding > another mode to merge-tree would just be a partial duplication of the > other tool. I wonder how the UI of a tool that does non-worktree/non-index cherry-picks will look like. I'd expect it to produce the same output as merge-tree, except cherry-pick should probably output a commit OID, not a tree. Maybe we want a unified command that produces commits from any sequence of merge/cherry-pick/revert/reword steps. The obvious UI would use something like the rebase-todo list as input. For example: $ echo ' pick commit1 reword commit2 # edit commit message in $GIT_EDITOR merge commit3 -m "log message" ' | git create-commit commit0 <OID of final commit> we start from commit0 and apply steps one-by-one. Obviously, one unsolved problem is how to pass parameters like commit messages if no editor should be invoked (my sketch uses -m). If any of the steps fails when merging merge, then we get the tree with conflicts $ echo ' pick commit1 pick commit2 pick commit-that-does-not-apply ' | git create-commit commit0 <OID of commit after step 2> <OID of toplevel tree after failed merge> <Conflicted file info> <Informational messages> Replaying a series of commits might look like this: $ echo 'pick commit1 ^commit0' | git create-commit new-base I'm concluding that this is a difficult UI problem, and having a merge-tree command that accepts a "common ancestor" parameter could make it easier to experiment. Of course that depends on who is experimenting. > > However, if the other tool doesn't obviate the need for this > additional mode (perhaps it ends up being forced to be too > porcelain-ish insteading of plumbing-ish?), or folks really just want > another merge-tree mode, I'm happy to add one along with the tool I > submit later. Does that sound reasonable to you, or is there > something you're still objecting to that I've missed?