6 ms·
As the article notes, this is hard to do cleanly, depending on the exact semantics of what you want. And even with a full spec in hand, I don't think git's data
by zwegner 6y ago
As the article notes, this is hard to do cleanly, depending on the exact semantics of what you want. And even with a full spec in hand, I don't think git's data model makes it particularly easy to compute this information.
One method for doing this manually is to do an interactive rebase and re-order all the relevant commits to the end. You basically create a new branch that has all the other commits first, and then you can diff between that point and the branch head. With the example commits from the post, you'd order them A B D F G C E H; then git diff G H would show just the changes from C E H.
This is a bit annoying in that it needs to use the working tree to apply all the commits in sequence, and you have to manually resolve any conflicts that arise, which gets more difficult the larger and more-intertwined the commits get. But maybe it's better than nothing...
- tln 6y agoYou could use `git worktree add` to avoid messing up the main working tree.
- zwegner 6y agoRight, or there's always git stash. Either way, it's a pretty expensive and cumbersome operation.
- chrismorgan 6y agogit-revise is what you want here. It’s rebase, but without touching the working tree. This makes it vastly faster, avoids changing file mtimes (which is very useful property if you have a build system that operates on mtimes, such as make, or something that is watching for file system changes), and if you do need to resolve conflicts it’s easier to confirm that you haven’t changed anything in the final result, because that’ll produce warnings and a dirty index. https://github.com/mystor/git-revise https://github.com/mystor/git-revise Since learning about this, 90% of my rebase usage has switched to revise, and I’m much happier with it all. I also probably revise commits twice as often as I used to because it’s so much faster and has no file system modification side-effects. When there are conflicts, it only gets you a two-way merge, so that occasionally I reach for rebase to help with handling non-trivial conflicts from reorderings.
- ninkendo 6y agoI’ve been wanting something like this for a long time, thanks! I like to do a lot of rebasing and splicing together/apart various commits, and I hate that rebase touches the working tree, it means I can’t have my IDE open during the process or it starts throwing error messages about invalid project files (due to the conflict markers showing up.) I’ll definitely have give this a look.
- chrismorgan 6y agoYes, this is exactly what you want. Even if it’s bothersome setting it up (which Python things can be, depending on how you are willing to install it; especially on Windows), you will find it worthwhile.
- cpach 6y agoIt hadn’t occurred to me that Git allows you to reorder commits. Cool!