On Fri, Jun 3, 2022 at 1:52 AM Elijah Newren <newren@xxxxxxxxx> wrote: > > On Thu, Jun 2, 2022 at 10:08 AM Tao Klerks <tao@xxxxxxxxxx> wrote: > > <snip> > > > > It *seems* as though I could enact something functionally equivalent > > to a cherry-pick by first creating a (temporary) "--ours" merge commit > > on the target branch, pretending to have merged the parent commit of > > the cherry-pickable one, and then merging the cherry-pick commit > > itself on top of that. The resulting tree could be used as the basis > > for a final commit on top of the original tip of the target branch, if > > that merge were clean, and otherwise fail saying "there are conflicts, > > go do things properly in a working tree pls". > > > > I'm not sure whether this is the right way to conceive of > > cherry-picking, however, or whether it makes more sense to conceive of > > it as a single-commit rebase. > > The merge --ours stuff is going down a weird path that I don't > recommend, but thinking of it as a single-commit rebase is good. In > fact, the default rebase backend was originally written by calling > cherry-pick for each commit in question. > Thanks so much for your fast feedback! When you say "The merge --ours stuff is going down a weird path that I don't recommend", I would love to understand better what you mean. My testing so far is basic at best, and I had a typo (I meant "git merge -s ours" rather than "git merge --ours"), but in principle what I described does seem to *work* in most cases? For example, imagine I want to cherry-pick Johannes Schindelin's commit b44855743b1674caf3bd4f42814473771b129c48 onto current master in Junio's repo - I can do it the simple way: git checkout origin/master git cherry-pick b44855743b1674caf3bd4f42814473771b129c48 Or I can do it the "the only tool I have available is merge, so I need to play with the merge base" way: git checkout origin/master TARGET_COMMIT=b44855743b1674caf3bd4f42814473771b129c48 git merge $TARGET_COMMIT~1 -s ours -m whatever git merge $TARGET_COMMIT -m whateverelse git log --format=%B -1 $TARGET_COMMIT | \ GIT_AUTHOR_NAME="$(git log --format=%an -1 $TARGET_COMMIT)" \ GIT_AUTHOR_EMAIL="$(git log --format=%ae -1 $TARGET_COMMIT)" \ GIT_AUTHOR_DATE="$(git log --format=%at -1 $TARGET_COMMIT)" \ git commit-tree -p origin/master `git rev-parse HEAD^{tree}` #and do something with the resulting commit, eg branch -f One limitation here is that it doesn't work to "cherry-pick" commits that are already in the history of the target branch (which could be solved with a temporary shallow graft? :D ). Maybe more important is that it's a crazy-convoluted way of doing things... Is there something "theoretically" wrong with this way of thinking about it, or is your concern more that this is like using a stick of dynamite to kill a fly? (likely effective, but not recommended?) Please note, having read the thread below, I understand you have some hard-won experience around the use of scripting approaches for the implementation of actual git commands - I never stated this explicitly above, but I'm asking partially as an intellectual exercise, partially wrt something I might implement in custom tooling for specific workflows in a specific context. At no point am I suggesting the above would be the right way for an official (new?) git command to do its work. > > Is there a relationship between > > git-merge-tree and rebases? > > The patches I submitted do not have the ability for rebases to be > built from git-merge-tree. There's a debate over whether my series > should be tweaked to enable it. Peruse the thread over at > https://lore.kernel.org/git/xmqqh78nj0q0.fsf@gitster.g/ if you want to > read some of the discussion, as well as see discussion of how merging > and cherry-picks/rebases are related. > Thanks very much! I guess it's a little late to chime in on that thread, but for what it's worth, I agree with Junio that it would be ideal if "merge-tree" were able to do that "gimme (arbitrary) trees and I'll merge'em" operation - not that I would expect any official git commands to invoke this recursively (I understand the concerns over poor design / unnecessary complexity driven by a scripting approach), but that would be a powerful tool for people who want to script their own crazy use cases - eg a less-bad version of what I outlined above, without the need for the "git merge -s ours" commit establishing the desired merge base. That said, I get lost in the discussion of what the right set of commands / distribution of responsibility should be; given the *name*, I would expect "gimme three trees and I'll give you a fourth with conflict data" to be an operation that fits in that existing command, and I would expect "do a server-side merge or a server-side rebase through to a new (set of) merge or rebased commit(s)" to be separate (new?) commands. > > Is there an aspiration to develop "server > > side rebase" also at some stage? > > Yes, already in progress and possibly usable for simple cases. > Haven't had some time to work on it for a while (~4 months, sigh), but > will definitely get some time in late June/early July to carry it on. > You can check out the "replay" branch of github.com/newren/git if > you're curious. Thank you, will look!