|
|
Subscribe / Log in / New account

Git replay

Git replay

Posted Feb 27, 2024 3:44 UTC (Tue) by newren (subscriber, #5160)
In reply to: Git replay by Tobu
Parent article: Git 2.44.0 released

> Git replay looks good, I can use it to rebase stacked histories like so:
>
> git replay --onto linus/master linus/master..remote/feature linus/master..feature |git update-ref --stdin

Glad folks are finding it useful. Note, though, that this only works for linear histories; if any of the commits in the range is a merge, you'll hit "replaying merge commits is not yet supported". There are plans to support merge commits (fairly detailed ones), but it doesn't exist yet.

> It's better than git rebase in that it works fast and won't update worktree timestamps unnecessarily (you do need to start with a clean work tree and
> finalize with a git checkout feature, or git reset --hard if already on that branch),

Why do you need to start with a clean work tree? Have you found a bug, or are you being careful about starting with a clean worktree because you are using a hard reset afterward and that would have problems with the changes? (Part of the point of git replay is that you don't necessarily want or need to check out the result afterwards, so having a clean worktree should be irrelevant for such cases.)

> but it's also lacking useful functionality: instead of skipping previously applied commits (eg those that moved from remote/feature to
> linus/master), it generates empty commits. Which makes it hard to run git range-diff ...remote/feature to see what's changed.

Boy, oh boy is it lacking functionality. I was super surprised that folks at GitLab and GitHub thought it useful in its current state. But they did, and apparently you and others do too, so it's probably a good thing they decided to push to have it made available. Anyway, adding an --empty={stop,drop,roll} flag (similar to those found in am & rebase) to either stop and ask the user how to handle the now-empty commit, or to automatically drop such commits, or to roll them up into the end result would indeed be a useful addition. There are many other capabilities I'd love to work on: giving users the ability to handle conflicts and continue instead of simply dying, replaying merges much smarter than rebase does, allowing a few more general revision flags like --ancestry-path, completely new and simplified interactivity handling, etc., etc. If only $employer hadn't decided it was time to invest in stuff other than git, and/or if I only had more free time. :-( I'm sure I'll get to it eventually, it just may be a while.


to post comments

Git replay

Posted Feb 28, 2024 10:52 UTC (Wed) by Tobu (subscriber, #24111) [Link]

Glad folks are finding it useful. Note, though, that this only works for linear histories; if any of the commits in the range is a merge, you'll hit "replaying merge commits is not yet supported". There are plans to support merge commits (fairly detailed ones), but it doesn't exist yet.
Yes, for me at least this is enough: stacking non-merge commits as I would with git rebase.
Why do you need to start with a clean work tree? Have you found a bug, or are you being careful about starting with a clean worktree because you are using a hard reset afterward and that would have problems with the changes? (Part of the point of git replay is that you don't necessarily want or need to check out the result afterwards, so having a clean worktree should be irrelevant for such cases.)

The second: because I pipe into update-refs updating the current branch, followed by a hard reset. If there was a way to advance the current branch with autostash, that would be safer.

I'm used to working with low-level and high-level git commands depending on what works, and currently I can work with replay as a low-level command, git filter-branch to prune the empty commits (git filter-branch --prune-empty linus/master.. in this example — I looked at filter-repo and it doesn't take ranges), and finally git update-ref with manual stashing.

I'm not sure yet what would be a reasonable high-level interface: presumably just updating the refs from git replay would work (git replay --update-refs --autostash). Mimicking the rebase interface is an option but I don't know if I'd use it, because the point for me is not to reflect intermediate states inside the worktree, and that seems to preclude the interactive bits like --continue / --skip / --abort. Another totally different approach would be to stash worktree timestamps with their blob hashes somewhere and apply them back for unchanged files; then updating the worktree with in-between states wouldn't be a problem.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds