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 [off-list ref] wrote:
quoted
Elijah Newren [off-list ref] writes:
quoted
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?