8 ms·
Say you start on Main, then make a new branch that you intend to be a PR someday. You make commit 1. Then another. Maybe 6 more. Now you realize that something
by pkulak 1y ago
Say you start on Main, then make a new branch that you intend to be a PR someday. You make commit 1. Then another. Maybe 6 more. Now you realize that something in commit 1 should have been done differently. So, you "edit" commit 1. All the other commits automatically rebase on top and when you go back to your last commit, it's there. Same with _after_ you PR and someone notices something in commit 3. Edit it, push, and it's fixed.
You can do all that in Git, but I sure as hell never did; and my co-workers really appreciate PRs that are broken into lots of little commits that can be easily looked over, one by one.
- lrobinovitch 1y agoYou have to force push each time you do this, right? How do your coworkers find the incremental change you made to commit 1 after you force push it, and how do you deal with collaborative branches effectively this way? And if I don't want to work this way and force push, are there other benefits of jj?
- baq 1y agothe heuristic is 'if you know about rerere and especially if you use it, you should try jj'. if you never force push, you might not see value in jj. (I basically always force push.)
- lrobinovitch 1y agoThat makes sense, good to know, thanks. > I basically always force push How do your colleagues deal with this, or is this mostly on experimental branches or individual projects?
- whateveracct 1y agoPeople barely ever work off my branches.
- smw 1y agoIt's generally fine if you force push a branch that you're the only one working on. In many projects, there's an expectation that the 'PR Branch' you create in order to make a github pull request is owned by you, and can be rebased/edited/force-pushed at will. It's very common to do things like `git commit --amend --no-edit` to fix a typo or lint issue and then force push to update the last commit. This has it's problems, and there's a reason things like Geritt are popular in some more sophisticated shops, as they make it much easier to review changes to PRs in response to reviews, as an example.
- baq 1y agoThe PRs are either small enough that it isn’t a problem or large enough that it isn’t a problem… the odd in-between PR experience sucks and it’s one of the cases when I sometimes add more commits instead of force pushing. +1 to sibling gerrit recommendation; I used to use it a decade ago and it was better then than GitHub PRs today.
- andrewaylett 1y agoJJ has the concept of "immutable changesets" -- if it sees a commit is referenced from a branch that it's not tracking, it assumes it ought not rebase that commit. Changesets on branches that look like the main branch are immutable too. And you can edit the revset that JJ considers immutable if you need it to be different from the default. The net effect is that I can change "my" branches as I wish, but I can't change stuff that's been merged or other folks' branches unless I disable the safety features (either using `--ignore-immutable` or tracking the branch). JJ also makes it really easy to push a single changeset as a branch, which means as you evolve that single commit you can keep the remote updated with your current work really easily. And it's got a specific `jj evolog` command to see how a specific changeset has evolved over time.
- Disposal8433 1y agoIIRC it's push force with lease, ie non destructive push force. No one will be bothered or notice what you did. And if you have conflicts, it's really easy to rebase and fix any issue.
- adastra22 1y agoI do this every day in git. “git rebase -i [hash]” fyi.
- baq 1y agoyou think you do, but you don't; jj edit is much, much better than an edit step in a rebase - it essentially keeps rebasing while you're editing, so you can always see which changes get conflicts, then you are free to resolve them, or not, at your convenience.
- adastra22 1y agoSo you get all merge conflicts at once? How is that better?
- baq 1y agoit's exponentially better because you don't need to resolve them until you're ready. conflicts are committed to the local repo like everything else, commits with conflicts are noisily warned about and you can fix them whenever instead of having no other option than immediately.
- adastra22 1y agoHow does your repo work with conflicts? How does it compile?
- baq 1y agoThe edited commit, assuming it doesn’t have conflicts with predecessors, builds just fine. Successor commits with conflicts that you just introduced predictably don’t - but you aren’t editing them, so it isn’t a problem. In fact, that’s exactly why this feature is so compelling.
- adastra22 1y ago
- philwelch 1y agoI do that in Git all the time. JJ might be easier in some sense but “more powerful” implies that it can do things that are impossible in Git.
- Vinnl 1y agoI think generally when people say that for jj, they mean it can do the same things with fewer concepts.
- sswatson 1y agoThe author lists that as a separate benefit, though. My interpretation is that jj makes certain useful operations convenient to use that would be so complex in git as to be completely impractical. Something like jj undo would be a simple example: jj users can do it, and git users can’t, even though it’s logically possible in both systems.
- sunshowers 1y agoIf you're in the middle of a git rebase -i of a stack of 20 commits, and realize while editing commit 15 that you made a mistake at commit 8, how do you go back and edit commit 8 without having to complete the rebase -i? This is not contrived — this is an entirely realistic scenario that I use jj to handle all the time.
- 1718627440 1y agoTrue nested rebase doesn't exist (yet) in Git. What I do is create another commit with the parent commit 8 with commit --fixup and then complete the rebase. The I can just autosquash it, without reediting anything. You could also keep the rebased commits, abort the rebase, rebase the already rebased commits and then continue the first rebase.
- sunshowers 1y agoWith jj, because it doesn't have modal states of any kind, you can just go back to commit 8, edit it, and everything dependent on it gets auto-rebased. You can also do jj squash --into for a workflow similar to fixup commits. I would consider the first workflow to be impossible to do by most mere mortals in Git [1]. Meanwhile in jj it's downright trivial. [1] There technically is a way to do this by setting a temporary branch, aborting the rebase, starting another rebase -i, carefully editing the interactive instructions, going to commit 8, editing that commit, then cherry-picking 9-15 from the temporary branch. But it's too hard to do in practice, and far too easy to get wrong.
- ileonichwiesz 1y agoOkay, sure, but if I realize I should’ve done something differently in commit 1, why wouldn’t I just make a new commit with the fix?
- tomstuart 1y agoDo you want another person (or yourself in the future) to be able to read your commits, in order, to get a clear account of what changed & why? If so, you should fix up those commits to address mistakes. If not, it doesn’t matter.
- KallDrexx 1y agoNot the OP but for me, no I don't actually. In a PR branch, my branches usually have a bunch of WIP commits, especially if I've worked on a PR across day boundaries. It's common for more complex PRs that I started down one path and then changed to another path, in which case a lot of work that went into earlier commits is no longer relevant to the picture as a whole. Once a PR has been submitted for review, I NEVER want to change previous commits and force push, because that breaks common tooling that other team mates rely on to see what changes since their last review. When you do a force push, they now have to review the full PR because they can't be guaranteed exactly which lines changed, and your commit message for the old pr is now muddled. Once the PR has been merged, I prefer it merged as a single squashed commit so it's reflective of the single atomic PR (because most of the intermediary commits have never actually mattered to debugging a bug caused by a PR). And if I've already merged a commit to main, then I 100% don't want to rewrite the history of that other commit. So personally I have never found the commit history of a PR branch useful enough that rewriting past commits was beneficial. The commit history of main is immensely useful, enough that you never want to rewrite that either.
- tux3 1y agoWhen you force push a PR, Gitlab shows the changes from the last push. So it also depends which forge you use. I could see that working less well on Github or simpler Git forges