6 ms·
Defeating Git Rigour Fatigue with Jujutsu
- mcookly 4mo agoI'm not an expert in Magit by any means, but I bet there's a way to accomplish this in only a few keystrokes.
- y1n0 4mo agoI don't get why people like jujutsu. I tried it for a while but I work with a quite a few people in the same repo and I need easy named branches that keep up with commits. For all the many problems in git, branches are dead easy. That was the big innovation over svn at the time. Last time I tried jj, branches were an extremely laborious process to keep up to date. I don't see how people that aren't working alone can work with that. I have numerous branches in flight at any given time, and my colleagues do as well. The idea of manually keeping them pointed at the right commit is just nuts. Maybe they've fixed that astonishing choice since then, and I'd give things another go if they did. But branches and worktrees are how I operate. Regarding the article, I have no idea what is going on as I'm red-green color deficient.
- jolux 4mo agoI assume you mean named branches (bookmarks in jj)? Because anonymous branches in jj are trivial: you just `jj new <parent_change_id>` and you have a new branch. Bookmarks aren’t that bad either IMO, especially with the recent addition of `jj bookmark advance`. Curious if you can say more about the particular difficulties you found keeping them up to date?
- nine_k 4mo agoImagine that you use jj, while everyone else who works on the repo along with you uses regular git. Is it easy?
- LoganDark 4mo agoI use jj all the time for pull requests, in fact I don't use regular git at all anymore, and it's perfectly easy. Not only can I easily keep all my pull requests properly synced to their base branches, but I can easily and very quickly address review comments, keeping the commit stack clean without having to manually squash or amend or anything of that sort. Honestly it's a lot easier and more efficient than git for me because of how much naturally follows rather than requiring explicit imperative fixups.
- jolux 4mo agoYes, that describes me at both jobs I’ve had since learning jj. Hence why I asked for specifics: I’m genuinely curious what other people struggle with, partially because I’d like to help them if I can, and partially because it gives me a better understanding of common pitfalls which helps when teaching other people.
- jgtrosh 4mo agoI believe this is the most common scenario, yes. If you're used to actively pushing and pulling from the same branche as your colleagues, you need to learn how to manipulate diverging changes and conflicting bookmarks, but other than that all the jj magic is limited to your local activity.
- stouset 4mo agoYes, that is the case for almost every repo I’ve ever used jj for. It is a complete non-issue. There is virtually zero friction.
- rtpg 4mo agoyeah nobody "has to know", especially if everyone else is also rebasing etc constantly.
- tiltowait 4mo agoI do this all the time at my job, without issue. I think it's honestly easier than using plain git.
- Macha 4mo ago
- y1n0 4mo agoI think I said named branches, but that is definitely what I mean. I find it strange that people want to work on anonymous branches, but to each their own. I don't so that has no appeal to me. I often work on something and then switch away to something else. it might be a week before i get back to it, and the name of the branch is a clue as to what the heck I was doing. Other people often need to check out a branch I'm working on to help. How does anonymous branching help anyone except a solo developer?
- justinpombrio 4mo ago> it might be a week before i get back to it, and the name of the branch is a clue as to what the heck I was doing. Ah, this is what the description (what git would call the commit message) is for. You can set the description even before you've made any changes.
- em-bee 4mo agothat doesn't make sense because when i am working on a feature, i create a branch, name the branch after the feature and then each commit has a description of what is in that commit. the feature has multiple commits, and while i carefully work out what goes in each commit i don't squash them. so with jj i could use a bookmark, ok, but having to manually update that bookmark feels wrong.
- igor47 4mo agoWhen I'm working in git, I always start work by creating a new branch with a name. Sometimes the branch becomes something different as I work and then I might rename it or more often just keep a stale name around. But in git commit descriptions come later. In jj, it's the opposite. I start with a change, and I often describe it right away. Branches (bookmarks) come at the end. You could, in jj, tag a new empty change with a bookmark as soon as you create it. You don't have to advance the bookmark -- that the first change in a sequence of changes is tagged with a bookmark is probably as much information as you need?
- LoganDark 4mo agoI don't try to reimplement the git workflow on top of Jujutsu. I like it because I can let go of a bunch of annoying noise that I needed in Git. I like it because rebases don't have to be synchronous and modal. I like it because I can easily edit history, rearrange the commit graph, change commit descriptions, duplicate, and so much more, and even remotely (without having to checkout first). There's so much to love that I never could've even dreamed of under Git. I like Jujutsu so much that I've been working on massive refactors to my tooling in order to support it (example: https://github.com/LoganDark/get-shit-done https://github.com/LoganDark/get-shit-done)
- y1n0 4mo agoThat's great that it has things you like. I don't do rebasing, except on MRs where I've come to prefer squashing the branch being committed. But I don't rewrite history. It's history. While I can understand people have reasons to do it, the reasons have never resonated with me. I'd rather spend my time getting new work done and not polishing work I've already done.
- RobotCaleb 4mo agoI'm excited for your delayed comment. I'm sure going to take note that you delayed it and come back later to read it because I'm super interested in what it is that you've delayed. You know, you can just write the comment instead of holding your place in line
- jwiz 4mo agoThe delay is on HN side, when people reply too quickly.
- RobotCaleb 4mo agoOooh, my apologies, then! I misunderstood
- LoganDark 4mo ago
- stouset 4mo agoI’ll be honest, as a long-time jj user, I actually haven’t the foggiest what you’re talking about with branches being laborious to keep up to date. Can you elaborate?
- y1n0 4mo agoI make a commit and the branch doesn't follow it. Bookmark, whatever. That is never a behavior I would want. What purpose does it serve?
- paradox460 4mo agoThey added auto advance bookmarks a while ago. You configure which revset bookmarks you want to advance or not, and then it just keeps them at the "head" of a branch
- stouset 4mo agoOf all the things I was imagining it might be, this was down at the bottom. Personally I’m a huge fan of this approach. If you aren’t, it’s literally just a one-liner (that is trivially made into an alias) to advance a branch name to the most recent revision. And now there’s a feature to do auto-advancing if you want it. Why is it this way? Because jj is designed around revisions being constantly mutated. In git, when I make a commit, I am typically signaling that that a chunk of work is complete. Not always, but usually. In most jj workflows, revisions are mutated constantly during development. A revision being made on the tip of a branch is rarely a signal that that unit of work is finished. It’s even incredibly common to have multiple revisions in a row that are works in progress. Hell, the article we’re all commenting on discusses just such a workflow. If I make five revisions on top of some branch, there is no reason to assume that any of them are ready to be shared, much less all of them. Because of that difference, it makes sense to have an explicit act to move a branch name forward.
- throawayonthe 4mo agotbh i never actually learned git, but peope working on the same repos with git seem to be ahme ones struggling with named branches... i just do jj rebase and it just works idk
- rmwaite 4mo agoI remember being the big innovation over svn being merging. There were others things, obviously, but the distributed model + easy merges is what I remember.
- y1n0 4mo agoYes, that's true, merging. Which is what made branching a reasonable thing to do.
- kccqzy 4mo agoIf the big innovation over svn is merging for git, then the big innovation here is conflicts. I hate the fact that git requires you to stop everything and fix the merge conflict when you merge. I especially hate the fact that when rebasing in git sometimes it requires you to solve conflicts one by one. The big innovation here is jj does not require you to resolve merge conflicts in a timely manner; it simply records the fact that there are conflicts in the file and you go about your ways. You don't ever have to abort like `git rebase --abort` or `git merge --abort`.
- kccqzy 4mo agoYou don’t need easy named branches. Naming branches is a chore: since you already spend time writing commit messages, branch names are just a summarization of your commit messages but with more character restrictions. That’s why I always use jj’s automatic commit identifiers. They are short and I don’t waste brain cycles naming things that are ephemeral. When I push, I let jj automatically creates, updates, and deletes remote git branches (`jj git push -c` for creation, plain `jj git push` for updates, `jj git push --deleted` for deletions). I do not ever have to think about branch names and it is great!
- y1n0 4mo agoYeah, I don't get it. I'm sure it's because we work differently and that's fine. But when I'm picking up something someone on the team has left behind because they got pulled on to something else, or are sick, or 5 million other reasons, having a branch, with a ticket in the name, explaining what the purpose of the branch is, why it exists, what it's current state is, that all matters. I can't help but think that everyone that likes JJ isn't really doing collaboration.
- kccqzy 4mo agoI collaborate a whole lot. In fact for solo development I use git because jj is overkill for it. Also by default jj prevents you from overwriting commits that exists on the main branch on the remote, but this is what I often do on solo projects. > having a branch, with a ticket in the name, explaining what the purpose of the branch is, why it exists, what it's current state is, that all matters In my view, all the above information exists not in the branch name, but either in the ticket, or in the commit message. The branch name is purely a superfluous thing that does not convey any information. Many of my colleagues already use a tool to automatically name their branches from the first line of their commit messages, and jj just makes this awkward process straightforward.
- Macha 4mo agoWhen its MR time I use jj push -c and I’ve set my config to auto generate a branch name from the commit message by extracting the ticket ID from the commit message since we have a standard format into something like PROJ-1234-nzytopmn . Since the company I work at enforces squash merge since many coworkers would otherwise have 20 merge, fixup, lint or ci fix commits per MR, auto advancing isn’t relevant. Addressing comments is just squash into that change and repush. We don’t really do long lived branches so the ticket number is enough to find the branch and the commit message explains the change if I need to hand over work.
- NamlchakKhandro 4mo agoFeel the same way about JJ. It feels like Apple vs Linux. Apple being different ... just because (it gives them an artificial moat)
- kaladin-jasnah 4mo agoI like jujutsu simply because (despite my annoyances, which might be because I started using it 2 weeks ago) it's still faster than git. I dislike this as well. I find it easier to keep track of branches with bookmarks, but my workflow still makes things cumbersome. I am usually working with the "megamerge" branches, and I usually want to add commits to my current branch instead of squashing my edits. However, adding commits means I have to add my commit, move my bookmark up to the branch tip (jj tug?), and then rebase the megamerge branch, versus doing nothing for squashing. I also find that when I mess up, I don't really love using `jj op log` to fix it. I want to not be in an environment where it's this easy to destroy history (I feel like git was on the other end of it).
- oscillonoscope 4mo agoIf I need to move a 'branch bookmark' around a lot, I usually just tie it to an empty commit and then rebase changes before the bookmark.
- sakompella 4mo agoi had this exact friction trying to use jj this weekend. can't fathom for the life of me why i have to run another command that updates the branch to the next commit.
- wocram 4mo agohttps://github.com/jj-vcs/jj/discussions/3549 https://github.com/jj-vcs/jj/discussions/3549 let's you change this behavior. I think the idea is that branches/bookmarks aren't as necessary as they are with git.
- BeetleB 4mo agoI think much of the problem with this thread is people trying to convince one way is superior/inferior. There are just multiple different ways of working. Some ways fit some people's mental models better. You're not going to get a definitive "jujutsu is better than git" or vice versa. You should accept that some people have no problems with what you've described using jujutsu, and likewise jujutsu users should understand that not everyone can handle jj as well as they can. Imagine a different thread where jj users take your exact scenario, and complain about solving the problem with git. You wouldn't understand their pain, because it's not painful for you. This thread is the same, just with jj and git reversed. Personally, I don't see the pain you have. Back when I used git a lot, if I left a branch for a few weeks, I'd forget the name of the branch and would have to list all the branches (and set an alias to sort by and list the last commit dates of each) to discover the appropriate branch name. It's really not all that different from looking at all (recent) heads. Once you get used to this, you stop naming branches - other than to share with others. And when you do share with them, you cannot push (newer) changes because only bookmarked nodes and their parents can be pushed - so just prior to pushing, you advance the bookmark. With the shells I use, it's a few keystrokes before autocomplete/fzf produces the command for me - no mental effort at all. You definitely wouldn't advance the bookmark with each commit. Only when you need to push. And oh man, it's so nice not to have to manage all the branches. With git, I'd routinely go and delete old branches to declutter. With jj, there's simply no need to. The same with stashes. It's really nice not having to do that labor, and simultaneously not dealing with long lists. If this doesn't appeal to you - that's fine. You're not deficient. But understand, nor are those for whom your workflow sucks.
- jaredklewis 4mo agoIt’s only natural to want to defend one’s preferences with these things. Because unlike with some other preferences, such as what IDE, operating system, or terminal emulator you use, version control systems must be shared. If it is like you say and different people are just inherently more or less suited to different paradigms, then not everyone can be happy.
- deleted 4mo ago[deleted]
- arccy 4mo agoi too work with worktrees (jj workspaces) and prs (requires branches). it's easier if you give up choosing the name of your branch, and instead rely on finding things by description or your workspace name. for prs, I usually start with a single commit, so `jj git push -c` will auto create a named branch based on the change id. And i have template like the following to push to the same branch if i decided to stack commits rather than rewrite: branch-push = ["util", "exec", "--", "sh", "-c", """ name="$(jj log --no-graph --no-pager --color=never -r 'fork_point(@ | trunk())+ & fork_point(@ | trunk())..@' -T '"push-" ++ change_id.short()')" jj bookmark set -r @- "${name}" jj git push -b "${name}" """] you could probably write a similar alias that used your workspace name as the branch name to push to. and descriptions are slightly nicer than branch names, since they can be longer.
- LtWorf 4mo agoI've worked in places where they didn't know about git branches. They only had master. Review was done by having someone sit next to you and scrolling through the code telling what you had changed.
- wocram 4mo agojujutsu presents the same amount of power with fewer ideas, eg. There is no staging area. It adds new features, like jj undo. The un-learning curve is steep if you already know git very well. https://github.com/jj-vcs/jj/discussions/3549 https://github.com/jj-vcs/jj/discussions/3549 lets you enable automatically advancing bookmarks.
- diath 4mo agoSo... git rebase -i?
- nomel 4mo agoDefinitely not. Switch to a previous commit, make edits, changes propagate into the future commits (including into a git repo if you wish [1]) Jj is not git and is not a git tool, it just (thankfully) uses git as a backend, so you can still carry on with the rest of the world. [1] https://news.ycombinator.com/item?id=47765759 https://news.ycombinator.com/item?id=47765759
- deleted 4mo ago[deleted]
- ahepp 4mo ago> Switch to a previous commit, make edits, changes propagate into the future commits In what way is that different from using `git rebase -i` to edit a commit?
- stouset 4mo agoYou can literally jump into a commit and edit its contents directly, and everything is auto-rebased on top. There are no modal “sorry rebase failed, best of luck” gotchas. There are no “oops I put the wrong thing in the wrong part of the rebase and now I have to abort and start all over” gotchas. It’s rebase, but without all the extra work, mental overhead, failure cases, and effort.
- matheusmoreira 4mo agoHow does it just auto-rebase everything without failing though? If you edit something later commits depend on, then you get merge conflicts. Are you implying that jj just automatically handles all this?
- steveklabnik 4mo ago
- jonathanyc 4mo agoI have been walking some newer programmers through Git recently, so this topic is fresh on my mind. The commands in the blog post do not look friendlier or even different.
- mi_lk 4mo agoSo: Squash everything together then pick each component out by squash -i to an empty commit. Seems straightforward, wouldn’t call it special
- nomel 4mo agoI think jj will never gain momentum because people only have a git mental model at this point, so won't be able to effectively reason about jj.
- deleted 4mo ago[deleted]
- incognito124 4mo agoI spoke about this before, but jj has the Blub Paradox problem, from the pg's essay Beating the Averages (https://paulgraham.com/avg.html https://paulgraham.com/avg.html). Yes, you can do most commit manipulations with git just like with jj. But, users of jj know they're "looking down the power continuum" (to reuse pg's terminology) when they look at git, whereas git users cannot fathom what's exactly the deal with jj. Unfortunately, the only way to get it is to spend a week with it, with an open mind. It's close to impossible to describe it except "it's really neat" and "wow it removes all git's friction I didn't know existed". And, apparently, there's a pattern of having to try at least two times before it becomes intuitive!
- skydhash 4mo ago> Unfortunately, the only way to get it is to spend a week with it, with an open mind We do get it. But have you ever thought that git inflexible nature and full control is what some people people like? Having three different state for your work (working tree, staging, and committed) is nice for reviewing code. Picking lines and chunk give me an additional mental state to think about the design of the code. And once upon a time, I preferred history log like the one in the article. But this days (mostly inspired by mailing list development style) I wants the commit in my main log to be either features or bug fixes. Everything else is “wip”, which I will squash. It makes it easier when rewriting history, cherry picking, or just browsing the log.
- winterqt 4mo ago> `absorb` assigns the changes based on whichever previous commit most recently touched those files, which sometimes doesn't actually correspond to which commit should own these particular changes. I’m pretty sure `jj absorb` (and its predecessors, `git-absorb` [0] and `hg absorb`) are smarter than this, instead looking at the actual diffs. [0]: https://github.com/tummychow/git-absorb https://github.com/tummychow/git-absorb
- jolux 4mo agoAlso `sl absorb`.
- ikesau 4mo agoAh yeah, you're right, that's a misrepresentation on my part - it's based on lines, not the file: > [absorb] splits changes in the source revision and moves each change to the closest mutable ancestor where the corresponding lines were modified last. If the destination revision cannot be determined unambiguously, the change will be left in the source revision. I use absorb fairly often, fwiw. It's great for when I want to make a patch to a commit that will easily absorb into its right place. And I also, sometimes, prefer the more intentional approach where I decide exactly where each hunk will go.
- oefrha 4mo agoYeah it’s smarter than that, but as a daily user of git absorb it still gets things wrong fairly often though—like a couple times a week often for me. Plus the changes it can’t absorb automatically (e.g. a lone doc change it can’t find peers for).
- codemog 4mo ago[flagged]
- pkulak 4mo agoJJ is a whole different way to think about source control. The fact that you don’t need to run an agent just to use it is a nice bonus.
- deleted 4mo ago[deleted]
- nvader 4mo agoYou can also have you agent use jj with this skill https://github.com/danverbraganza/jujutsu-skill https://github.com/danverbraganza/jujutsu-skill
- aggregator-ios 4mo agoThis is my take on it too. And I built BetterGit (https://www.satishmaha.com/BetterGit/ https://www.satishmaha.com/BetterGit/) before agent capabilities became widespread. A lot of things in Git and existing GUIs are just cumbersome, and my app makes it better to handle the most common tasks and makes them easier. It's really meant for newcomers to Git. BUT! You can simply ask an agent to commit every meaningful block of work. Or just ask any agent to create a JIRA ticket and start work on that named branch. Or ask it to create work trees and create a PR. Life has gotten much easier without having to fight the command line or confusing GUI UX.
- deleted 4mo ago[deleted]
- einpoklum 4mo ago> For large features, I find this workflow far easier than having to maintain strict git rigour for the lifecycle of the feature's development. I don't know about all that. All sorts of ex-post-facto automated cut-up-and-splice commits sounds to me like a recipe for an every larger mess. I say maintain git rigor, always. Now, you could say "You only say that because you know git rather than jujutsu" or "if you use git absorb more you'll get it", and theoretically you might be right, but... meh, I kind of doubt it.
- einpoklum 4mo agos/every larger mess/even larger mess/ sorry about that.
- fragmede 4mo agoThe elephant in the room is that I haven't had to do something complicated and manual in git by hand in a long while. I'm using AI to generate code, and further, having it commit to git and pushing and pulling and managing branches and merging for me. So for people new to software development, they can also just ask AI to deal with git, which papers over the harder parts of its UX.
- hu3 4mo agoThis. I feel jj is some years too late. It tries to solve a human problem in an LLM era. LLMs are destined to overcome humans in code merging and change versioning (already did for me). There's little point to introducing yet another layer of indirection when LLMs just cut to the chase.
- surajrmal 4mo agoA lot of humans don't currently trust agents to touch VCS today. I also find that my agent tends to be much better about dealing with jj than it is with git.
- hu3 4mo agoCulture change is hard. A lot of humans still don't use git too. Many do only when they are forced. And it's much easier for a professional to be forced to use LLMs than jj when it comes to versioning assist (not even comparable in mindshare but the obvious needs to be said sometimes). So unfortunately I'm afraid jj is not going to achieve critical mass before 99.99% of merges are done by AI which don't need jj.
- surajrmal 4mo agoThat's the beauty of jj. It doesn't need critical mass. If the community remains small it's fine. If it blows up in adoption that's also fine. Also there are many ways to use llms. Some people control it at code review, but others control it as the VCS.
- xyzsparetimexyz 4mo agoWith jj I mostly just `jj split -B @`. Nice interactive ui for picking the changes I want into a commit. So many times better than 'git add -p'
- nozzlegear 4mo agoAs a git rebase enjoyer, I've completely switched over to jujutsu. The whole experience is more ergonomic in my opinion, and the default workflow which I use (using `jj new` to create a new change that clearly delineates work on a different "thing" before I start working on it) fits my mental model much better than the traditional write-then-commit workflow we all grew up with.
- singiamtel 4mo agoThe only thing that stops me from switching to jujutsu is that lazygit already paves through all these paper cuts pretty well, and I'd miss their custom patches feature. I see there's a similar project for JJ, but it doesn't seem nearly as polished https://github.com/Cretezy/lazyjj https://github.com/Cretezy/lazyjj
- stouset 4mo agoThis seems like a lot more effort than the (to me) more natural jj workflow of maintaining the idealized series of commits plus a working commit on top. As you make tweaks and fixes you just squash the relevant parts into the already-clean history. Basically, if you don’t get into that sort of situation with commits containing parts they shouldn’t in the first place, you don’t need to do any extra work to clean them up. The tip of your branch should be the only “messy” part.
- 3eb7988a1663 4mo agoThat is a lot of discipline up front. I am sure there are problems which are nicely bucketed, but I usually have to go with the flow and make changes as I see them. I want to keep working with the code, not babysitting version control as I focus on getting the initial version to work.
- surajrmal 4mo agoI think it comes down to your ability to plan and understand how the work can be broken down before you try solving it. I often know what every commit will look like before I ever touch the code. I do sometimes learn things and change my mind as I make changes but it doesn't often change my commit structure. I tend to work on a codebase I have 8+ years experience in though. I'm sure it doesn't work in a variety of situations though.
- stouset 4mo agoIt’s really not. I start a new branch and begin work. When I’m ready to start organizing that work into a consistent narrative (or when bits are “finished”), I split it out into independent commits. As I keep making fixes and tweaks, I continue squashing bits from my working commit into the parent commits they belong on. I don’t bother making any independent commits until pieces of what I’m working on are becoming fully-formed. Until then, my working commit just has everything.
- EFLKumo 4mo agoThis remind me of [jj megamerge](https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-and-profit https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-an...). jj allows concentrating on developing while leaving things for vcs alone, as well as solving vcs things (conflicts) at very beginning (megamerge). Really good.
- drdrey 4mo agoI have finally embraced squashing PRs and realized I wasted my youth trying to write Good Commits.
- vermilingua 4mo agoThese Good Commits are for the review’s benefit, not necessarily trunk history.
- wocram 4mo agoPRs very frequently contain more than 1 logical change.
- nextaccountic 4mo ago> Latter commits overwrite work that was done in earlier commits and the story breaks. > Some people prefer this, as it helps git bisect work better. Debuggability versus reviewer convenience is the tradeoff, I guess. Ideally we would have a VCS that made ergonomic to store both history-as-it-happened for some purposes, and the cleaned up, squashed and rebased history for other purposes, ensuring they match
- bschwindHN 4mo agoJust squash all the PR commits into one when it gets merged to main or whatever your main branch is. You can revisit the original PR to see the individual commits if you really want.
- paradox460 4mo agoJj could do that; it stores an evolog of each change, but currently that's kept local
- gmueckl 4mo agoI think that version control has reached a point where the next major evolutionary steps will be based on making history totally shared and immutable with history edits themselves being non-destructive versioned operations that can be browsed as higher order history.
- riwsky 4mo agoThat’s, uh, exactly how jj works!
- gmueckl 4mo agoI never absorbed that fact until now. Now, if it supported huge repositories with large files and binary files well, it could actually become a superstar.
- steveklabnik 4mo ago
- BobbyTables2 4mo agoI don’t understand. Are there people that try to use git without ever invoking “git rebase -i” ?
- christophilus 4mo agoI don't rebase. I just merge and resolve the conflicts. Nowadays, I just have an agent do that for me, and move on with my life.
- NamlchakKhandro 4mo agoYes. almost the majority of git users do this. i would say that as an expert commenter, 99.9% of people outside of California do this.
- Yokohiii 4mo agoTIL I am a minority.
- BeetleB 4mo agoI've done both the rebase and the merge flows in different jobs. I just don't see the fuss about rebase. Merging just works fine. Edit: OK, I realized later that I'm not really responding to the usual git rebase -i use case. Have you heard people say that because of magit they started using more "advanced" git workflows, and how they emphasize having a better UI makes a difference? It's the same idea with jujutsu. I'm much more likely to use git's power via jujutsu than directly with git. It's because jujutsu lets you do it all with a much simpler interface - fewer commands, and fewer concepts. And knowing that "jj undo" has your back. As a sibling commenter said: Likely 99% of git users don't do "git rebase -i". But the percentage who do similar with jujutsu is high - perhaps over half[1] of jujutsu users do the equivalent of "git rebase -i" all the time. Many of them didn't when they used git. The interface matters. [1] If you told me 80%, it wouldn't surprise me in the least.
- jadar 4mo agoI tend to just commit whenever I see fit, then at the end I do a `git reset —soft` and write the history that makes sense before pushing.
- ninkendo 4mo agoI always tell people I use a “git reset” based workflow. I rarely “checkout” branches, I just stay on main, reset hard when switching topics, reset soft when squashing, and I only name my branches on the remote end via “git push origin HEAD:some-branch”. `git branch` is basically my bookmark tool. I commit for a while, then when I want to remember where I am for later, `git branch wip/topic-a-finally-compiles` or whatever. I can reset hard to it when I want to revert back, or any other topic I need. If I forget to name a branch for a commit, the reflog is right there. Nothing’s lost. And yeah, a soft reset is basically the ideal way to just say “pretend all my changes weren’t committed yet, starting from $ref” and then I make my single commit for my PR. Easy peasy.
- 789-ha 4mo agoI can’t tell if this is satire. The fact that we have to memorize soft and hard resets was a thing I and everyone else just have to do. But that goes away if you only have commits, so no staging area vs staged changes vs changes on disk, it’s just all a commit and we have a myriad of tools that already know how to deal with commits. Honestly, your workflow as described sounds incredibly compatible with jujutsu, I’d really recommend giving it a shot / another go
- skydhash 4mo agoI follow something similar, especially with the PR process and squash-merge on remote. I do the first ticket push using explicit ref, then just continue on the next one, while I wait for the review process. When the first PR is merged, I rebase on top of the remote branch and do the same for the second PR. I do switch branch for long experiments and touch up on existing PR. It would be great if a PR was about distributing patches and not having those automatically generated from a branch.
- everybodyknows 4mo ago> A downside to this technique is that there's no guarantee that every commit will compile, which might be a dealbreaker. To some of us, that's an essential structural criterion. Passing unit-level self-tests may be as well.
- deleted 4mo ago[deleted]
- dundunUp 4mo ago[flagged]
- nvgrw 4mo agoI like how jj allows me to essentially use the same workflow in my personal projects (jj on git) as with my work stuff (jj on piper). That alone is really neat!
- gertburger 4mo agoI'd like to give jj another go but I found the "all files must be tracked/committed" approach to really break my workflow. I have a lot of temporary uncommitted files, which are not ignored or excluded. Some may eventually be committed but most won't. Being then forced to commit these (but only some due to file size) just gets in the way and impedes things like cross branch debugging A checkout is a working space after all, why can't it be (temporarily) dirty whilst you work?
- a10c 4mo ago[flagged]
- maleldil 4mo agoWhy not add them to gitignore? If you don't want to change the project's ignore, there's also a repository local ignore file, .git/info/exclude, which jj will respect. > why can't it be (temporarily) dirty whilst you work? Because that would go completely against how jj changes work.
- silon42 4mo agoSame here, auto-adding is a non-starter for me. Thankfully there's an option to not do it, not sure how well it works, but I'll have it enabled for the future when I try jj again.
- arccy 4mo agoauto add is nice for universal undo for changes made outside your editor... instead of adding changes to a new commit, i split/squash them into the previous one so the current commit remains dirty
- JimDabell 4mo agoWhen you are ready to record a change, split your current working changeset and pick the things you want to commit. It’s equivalent to staging then committing with Git.
- jezzamon 4mo agoIf you do want to solve this, here's two thoughts on how you can deal with it. First: don't try to edit jj changes. Always work on a new change and then squash that in to the parent. You think of that top level change as your working space. From there, the simplest way is to just always use 'jj commit -i' and 'jj squash -i' to create change ids with your work. Then if you want to have your changes move around with you, just rebase your working copy which contains your "uncommitted files" to the new branch. A different idea is to put those changes in a separate change, and then when you do work, always create your working space change as a merge change like 'jj new <uncommitted file change id> <main change id>. Then you should be able to do 'jj absorb' instead of 'jj squash' to put changes into the right change. Switching to a different branch is 'jj new <uncommitted file change id> <other change id>. As in typing this, I'm thinking for myself and what I actually do in practice... I find moving / rebasing jj commits very easy (I have a UI tool that literally lets you drag and drop them) so I usually just commit these changes and then drag the commits around so it's not in the chain of when I want to send it out for review
- a10c 4mo agoThis is roughly how I’ve found myself using jj naturally. I find it hard to “tell the story” of a change ahead of time, because the design often only becomes clear after some exploration. It’s much easier to land at an implementation I’m happy with, then work backwards and shape the commits into the story I wish I’d taken.
- oncallthrow 4mo ago`git rebase -i` and `fixup`
- regularfry 4mo agoSo I'd have an immediate problem with the target sequence of commits here. The thing about just getting a "define types" commit is that it shows me nothing about why those types were chosen. I need to flit backwards and forwards in history to see how they hook into the later code. I lose the history of "this type was enough to get us to point A, we needed this other thing to get to point B". But flitting back and forth is exactly what we're trying to avoid here. It feels like we're trying to optimise to One True Clean History, when that can't possibly exist because no two people's idea of "clean" actually matches. Just give me the PR, don't sweat the individual patches. But maybe also work on not committing your first idea as finished work.
- Zizizizz 4mo agoI would imagine why the types were chosen could easily be explained in the commit message. The goal presumably (at least how I do it) is so that if I'm touching quite a lot of the code base, the reviewer has the _option_ of being taken through the narrative of the change like they might explain if they were talking to you. If you don't want to be told what the changes are and how they tie together, then just click on review changes and review it all at once. It's not about the clean history, it's about making the reviewer's life easier with larger features. The commits might get squashed anyways so the history on main won't necessarily match what's on the feature branch. You can commit before you raise a pull request, I don't quite understand that point but I might just be missing something about your workflow that's different to mine.
- skydhash 4mo agoI work via tickets so I don’t take care of the commits in my branch (if I would there would only be one commit). So what I expect the reviewer to do is review the whole diff. I help by commenting the changes to explain the design and the implementation. Commits on a PR branch are usually my thinking outline, not for someone else to step through.
- Zizizizz 4mo agoThat's fair enough! I think the flow will be more universally beneficial if things like this become more mainstream. https://github.github.com/gh-stack/ https://github.github.com/gh-stack/ because then big prs aren't necessary if they can be reviewed incrementally so long as they can stand on their own.
- vaylian 4mo ago> This allows reviewers to step through your pull request in small bites, with each set of changes scoped to a single aspect of the feature. Is that a frequent way of reviewing? On GitHub you get shown all changes together in the review tab. You can select individual commits for closer inspection, but where is the benefit?
- Balinares 4mo agoA series of piecemeal self-contained changes is much easier to wrap your brain around comprehensively enough to detect logic issues. I started doing exactly this and it's been invaluable.
- jeltz 4mo agoYes, it us common among people who use git and it makes reviews of complex features much easier.
- steveklabnik 4mo agoSee this gist (and the discussion) https://news.ycombinator.com/item?id=41505266 https://news.ycombinator.com/item?id=41505266
- Yokohiii 4mo agoI suspect there is some weird habit that some people even like to overengineer their git history. Maybe it improves the pixel fame ratio or something. For me it's satire. There are reasons for varying effort in creating PRs or patches, but attempts like this never seem to reason about reality. If I have to review, I want to see the code, not a clever story hidden in the commit history.
- luodaint 4mo agoAgentic development transforms the scope of work. Once a session is committed to having one topic from the get-go — one move, one service, one abstraction — the diff generated from such a session is atomic by construction. Committing happens at the session level, and the commitment discipline problem solved by Jujutsu does not come into play. It is also true in reverse. Scopes set too broadly ("dark mode implementation," "auth flow fixes") lead to un-readable diffs no matter what tool you use for version control. Un-readable diff does not stem from commitment discipline; it is a scope problem. That said, this fact does not diminish the usefulness of Jujutsu. There are valid use cases for the rebase and stacking operations. However, the discussion about commit granularity takes on a whole new context once the constraint of having readable commits is established at the scope setting stage.
- deleted 4mo ago[deleted]
- danborn26 4mo agoJujutsu's approach to treating the working copy as a commit solves so many common friction points with Git rebase workflows. Great to see it gaining more adoption.
- actinium226 4mo agoI don't get how this is meaningfully different from doing something like: 1. Squash all your commits in this branch to one 2. Move that commit to the working directory with the appropriate git reset command 3. Commit hunks as appropriate.
- jauco 4mo agoIt’s mostly the same. But if you realize you forgot to add something to the dirst commit while you’re putting stuff in the second commit then this avoids having to create a fixup commit and then rebasing that afterwards.
- binarin 4mo agohttps://git-scm.com/docs/git-history https://git-scm.com/docs/git-history - git got the remaining piece of the puzzle to make massaging history relatively easy. "git history split", interactive rebase and fixup/auto squash allow you to do anything in a more systematic way than resetting/selectively staging/committing again and again.
- riwsky 4mo agogit let me make changes to local files without fear, since version control let me undo those changes easily. jj let me make changes to my git commits without fear, since version control of the git state itself let me undo those changes easily, too.
- nextlevelwizard 4mo agoNew tools are cool, but from what I have seen jj is literally just git with aliases
- sharts 4mo agoMaybe just not use git? It doesn’t even make sense for like 95% of projects.
- sevenseacat 4mo agoEvery time I've tried to use jujutsu, or even read about jujutsu, it's totally broken my brain. I'm not a git expert by any means I don't think, but there's 15 years of muscle memory there, and a few years of subversion before that...
- geraldsterling 4mo ago[flagged]