32 comments

  • klibertp14 minutes ago
    IME, the only real pain point with JJ is Git integration. I love it, it&#x27;s great in almost everything it does. Formalizing all the DSLs and using them consistently throughout the config and CLI is exactly how filesets, revsets, and templating should be implemented. The focus on exposing concepts as interfaces (without &quot;directly reflecting internals&quot;[1] in the UI) is only as good as the concepts themselves, and in JJ&#x27;s case, they <i>are</i> powerful. The problem is that they are too flexible, so Git interop relies heavily on convention and discipline... which is fatal. The fact that (almost?) all states of JJ are representable in Git makes it easy to mess up your remote, and then you need a very solid understanding of Git to fix it.<p>If you can give `jj` a try on a greenfield, single-developer project, you probably should. It feels exactly like Git felt compared to Subversion (when you focus on JJ&#x27;s strengths and use it in favorable conditions - it is young, after all). Get acquainted with `jj` on its terms, and if things click for you, you&#x27;ll be a bit better prepared for the bumpy road that is Git interop later on.<p>[1] <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=48903054">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=48903054</a>
  • bad_username6 hours ago
    I was uncomfortable with git until I read (the first 3 chapters of) the pro git book ( free here : <a href="https:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;v2" rel="nofollow">https:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;v2</a> ). It provides a great mental model of how git works under the hood. The UI of git - for better or worse - directly reflects its internals. And when I understood them, everything clicked into place.
    • Hendrikto3 hours ago
      Git is not nearly as confusing as people make it out to be. They just never take the few hours it takes to understand it. Which is a sad state of affairs for such an essential tool in the belt of any software engineer.<p><pre><code> git commit -am “Changes” </code></pre> just does not cut it, if you call yourself a professional.
      • jchook53 minutes ago
        Obligatory git joke.<p>Git gets easier once you understand branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space<p><a href="https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;256450&#x2F;are-git-branches-in-fact-homeomorphic-endofunctors-mapping-submanifolds-of-a" rel="nofollow">https:&#x2F;&#x2F;softwareengineering.stackexchange.com&#x2F;questions&#x2F;2564...</a>
      • hackrmn3 hours ago
        My observation has been that those who have never learned Git properly -- disregarding for a moment the issue with what &quot;properly&quot; means here -- just don&#x27;t think they need to, sticking to very simple workflows that produce linear graphs featuring squash-rebased work throughout. Because they don&#x27;t know Git&#x27;s fundamental model (including what you&#x27;d think was the obligatory piece of information that commits are essentially immutable), they don&#x27;t venture farther than their confidence suggests, keeping it within the circle so to speak.<p>The tragedy, if you ask me at least, is rather that they then start imposing the &quot;keep it simple&quot; culture onto everyone else, which frankly turns Git into what SVN and CVS were accomplishing before it, with all the drawbacks of those. This keeps 90% of the team satisfied 90% of the time because there&#x27;s nothing wrong with strictly linear graphs and the pro&#x27;s that are asked to produce these, can always squash-merge their intricate local development history before they push to Github (which some Git users also think is part of Git proper).<p>Something about using Git in the aforementioned way just bugs me strongly. I admit it&#x27;s a me problem, very likely, but lately I&#x27;ve also had to admit that it&#x27;s not just that either.<p>For instance, if I need to fix a bug I use `git blame` to find the commit where I have learned the bug originated. I do a `git checkout -b ... &lt;commit&gt;` to start working on a fix, creating a branch starting at the problematic commit. Already that is head and shoulders above what many people I work with do or know _what_ does (or why would one want to do that).<p>I do it because it creates a _trail_, certainly more so than just committing on top of `master`, even with a good commit message.<p>But my practice doesn&#x27;t produce linear graphs, even as pushed to Github (which we have to use, for better and for worse) and shared with everyone. I then get people coming to me and complaining they can&#x27;t merge and it becomes obvious they don&#x27;t understand Git sufficiently to do anything else but `git reset --hard` or worse, `rm -rf * &amp;&amp; git pull` and hope for the best.<p>Not sure where I was going with this, something about why use Git when it&#x27;s the new SVN with everything SVN had and none of what SVN didn&#x27;t have...
        • nixon_why692 hours ago
          Ok but the final outcome, most of the time, is a linear graph unless you&#x27;re maintaining extremely long-lived branches for some reason.<p>Setting practices so that linear graph will be easy to understand in history is still a good idea, no? I&#x27;m not religious about squash-merge on master but when I look at master&#x27;s history, I&#x27;d expect each individual commit to have a good message and be releasable.
          • hackrmn1 hour ago
            A linear graph doesn&#x27;t do any developer in the team except Github (which isn&#x27;t a developer in this context) any good because they have to pull down the graph at some point and when they have to fix something, although they will be able to track the blame to some commit in the middle of the graph, when they fix it and merge it it has to be squashed again (by hard or soft enforcement), which like I said negates much of the point with Git -- there&#x27;s no usable history left.<p>Point being that branches aren&#x27;t something to avoid, implying that complicated graphs are not to be avoided either, but embraced and knowing how Git works it&#x27;s not a problem at all (unless your &quot;bush&quot; is accidentally complex in a bad way) -- except that if noone bothers to learn Git, it _becomes_ a problem, solved at the cost of the value that Git provides -- branching (not just ephemeral branching for your local convenience). Exacerbated by Github since everyone pulls from there -- meaning that production-grade code is not a true graph but a linked list, on average.
            • nixon_why691 hour ago
              &gt; the value that Git provides -- branching (not just ephemeral branching for your local convenience).<p>I think this is the disconnect. I could see big libraries maintaining branches for each major release and I understand why linux does it. But if I&#x27;m maintaining FooService at work then I actually do just want a linear graph of all the commits that have been in production, in commit order.
              • hackrmn1 hour ago
                If you want that, mandate developers use prefixes like `!fixup` and do `git rebase` _on your end_ -- why force upon everyone your ideas especially if it also squashes all development history? This also removes development friction because people can work with Git on their end the way they like without regard to some convention that can be avoided -- save for the &quot;!fixup&quot; thing which can be considered useful metadata.
                • nixon_why6948 minutes ago
                  I do enforce rebased, releasable merges to master on my end, I&#x27;m not campaigning to remove branching from git.<p>Just saying, in the common case, the simple approach actually is pretty good.
      • kreco3 hours ago
        &gt; Git is not nearly as confusing as people make it out to be.<p>The people are confused, it&#x27;s a fact. So it is confusing. Stop gaslighting people.
        • ninkendo2 hours ago
          There’s this important word in the sentence you seem to be ignoring: “as”<p>GP isn’t saying “git isn’t confusing”, they’re saying “git isn’t as confusing as people make it out to be”<p>The point being, people exaggerate git’s confusingness when discussing it. There’s an element of irrationality here that’s worth bringing up, especially when it comes to comparing it to competing software. Once it has a <i>reputation</i> for being confusing, you’re more likely to be scared of certain workflows, you avoid them, and the problem compounds. Similarly if a VCS has a reputation for being “simple”, people might gravitate to it, learn it first, then parrot conclusions that git is too complicated because they never really gave git a chance in the first place (often they <i>do</i> take the time to read the other VCS’s documentation, and if they would have done the same for git they would have had no problems.)<p>It doesn’t help that there are <i>so many bad tutorials</i> out there that simply give you what commands to run, and tell you dumb stuff like “just make another clone if you get stuck”, and that makes the problem so much worse, and isn’t git’s fault.<p>Git <i>is</i> a bit confusing sometimes, but it’s mostly for reasons like “the reset and checkout commands do too much”, and “some low level commands are easy to confuse with high level commands” not because it’s a fundamentally confusing tool.
          • kreco2 hours ago
            &gt; Similarly if a VCS has a reputation for being “simple”, people might gravitate to it, learn it first, then parrot conclusions that git is too complicated because they never really gave git a chance in the first place (often they do take the time to read the other VCS’s documentation, and if they would have done the same for git they would have had no problems.)<p>I don&#x27;t think I need to reply to a comment that illustrate the main point of this sub thread.
            • ninkendo1 hour ago
              You just did though…<p>Maybe try and explain in more than one-sentence quips why you think git deserves its reputation? Otherwise you’re just coming off as a bit of a troll. Have a nice day.
        • xelxebar1 hour ago
          Interesting. &quot;A is X&quot; is different than &quot;I experience X from A&quot;. The former employs an objectivist lens while the latter a subjectivist one. I have had the pleasure of witnessing debates about whether a room really, truly is cold or not, which all resulted from a simple &quot;it is cold in here&quot; comment. In my experience modern English speakers tend to bias toward the objectivist register while Japan tends the other way. One of the joys in my life is how absorbing languages and cultures elucidates previously-unperceived distinctions. This discussion makes me want to try picking up Ithkuil again.<p>&#x2F;r
        • xeyownt3 hours ago
          If you ignore gravitation, a sphere earth can be very confusing.
        • dspillett2 hours ago
          But not as many people are as confused as is sometimes made out. And those who are confused are not as confused as people make out¹. Implying that a great many people are very confused because <i>some</i> are is far more gaslighty than suggesting it isn&#x27;t <i>that</i> hard in the majority of circumstances, IMO.<p>--------<p>[1] many (and I&#x27;d include myself here) are fine using the basics, perhaps with some less as-simple-as-possible workflows, but might need to scan the docs if they hit a conflict merging two branches that have developed independently for a fair few commits and have overlaps
        • Thanemate3 hours ago
          &gt;The people are confused, it&#x27;s a fact. So it is confusing. Stop gaslighting people.<p>I don&#x27;t think this sort of aggression is warranted, as the fact that I find something confusing doesn&#x27;t directly imply an intrinsic feature of the object that I&#x27;m confused with. One can reach that conclusion by observing that, not everyone who learns about the object finds it equally confusing.<p>All that to say: &quot;The people are confused&quot; doesn&#x27;t mean that &quot;All people are confused&quot;.
          • kreco2 hours ago
            There is no aggression.<p>If your product has a reputation to confuse users compared to other products, your product confuses users.<p>Let&#x27;s not start to bend reality just to back up some narrative because after reading a N hours documentation everything is OK.
            • dspillett2 hours ago
              <i>&gt; Let&#x27;s not start to bend reality just to back up some narrative because after reading a N hours documentation everything is OK.</i><p>If you expect everything to be as easy as pie without needing to make a little effort to read a bit of documentation, then perhaps the problem is not the product but the fact that you are in the wrong industry, or the wrong role within that industry, for you. Have you considered a management track?<p>Git is intended to make certain patterns possible, and practical. “Easy for people won&#x27;t read some documentation” was never one of its design goals.
              • kreco2 hours ago
                You conveniently cherry picked the least relevant part of my message.<p>No one said everything should be easy as pie.<p>There are other software similar to git that have not such reputation. Version control is not new.
                • account421 hour ago
                  &gt; There are other software similar to git that have not such reputation. Version control is not new.<p>Yes, there are alternatives that aren&#x27;t used by anyone except dedicated fans. If they had the wide user base that git enjoyed you&#x27;d hear just as many complaints about them.
                • jamesnorden2 hours ago
                  Because people actually use Git instead of whatever you mean.
                  • kreco1 hour ago
                    This is irrelevant to the topic.<p>I didn&#x27;t ask why git was widely used. I didn&#x27;t say git was useless.<p>Again, there were version controls before git came out.
                    • echoangle1 hour ago
                      I think the point was that a lot of people are confused by git because a lot of people use it. Meaning that the other software where people don’t complain would get the same amount of complaints if it had as many users as git has.
            • ninkendo1 hour ago
              &gt; If your product has a reputation to confuse users compared to other products, your product confuses users.<p>Is your contention that all reputations are deserved, <i>by definition?</i> That’s certainly an interesting take. It leaves zero room for the concept of an “unfair reputation” for example. Maybe you should rethink your argument here.
    • hnfong5 hours ago
      Same here. The git commands were confusing to me until I actually saw a Linus video on youtube explaining how the git data structures worked under the hood. It was dead simple, and one could easily mentally map the tools&#x27; functions onto how they operated on the data structures.<p>Once I understood that, as you said, everything clicked into place.<p>Somehow the &quot;higher level abstractions&quot; that git tries to do makes the things ever so more confusing.
    • vasco5 hours ago
      Mercurial had by far the best UX, never had to read anything to learn it. I just pretend that I&#x27;m using mercurial when using git and nuke local repo if I mess up. Been doing it for my whole career.
      • black_knight4 hours ago
        I love darcs! Somehow its interface just vibes with me. It is interactive by default, and the commands like “record”, “rollback”, etc, are somehow intuitive. Darcs also tried to put more semantic content in the patches, like file operations or search replace parches.<p>It is always satisfying to rename something, then merge in some work where someone used the old variable name in the meanwhile, and the merge would go through automatically applying the rename!
      • yurishimo4 hours ago
        I&#x27;ve often found that many problems when working in teams can be traced back to `rebase`. I understand the benefits, but if you&#x27;re already working on a team where history is not used in any serious way, then you cut out a lot of foot-guns by only using `merge`.
        • Hendrikto3 hours ago
          &gt; if you&#x27;re already working on a team where history is not used in any serious way<p>Then you are doing it wrong. Sadly this is very common.
        • zwischenzug3 hours ago
          Except the &quot;merge mess&quot; footgun.<p>I got into training people in Git (I now do it for O&#x27;Reilly) because I worked with 12 teams that merged _everything_ into sub-branches. The result was that the `git log --oneline` command resulted in screensful of just pipes.<p>My initial training goal in training was getting my students to understand a rebase to avoid that mess.
    • xyzsparetimexyz5 hours ago
      No it doesn&#x27;t. Half the git commands are low level, half are high level. It&#x27;s not 1:1 at all.
      • palata5 hours ago
        So when someone tells you &quot;understanding X helped me a lot&quot;, your answer is &quot;no, it did not&quot;?<p>&gt; It&#x27;s not 1:1 at all.<p>I don&#x27;t see any mention of &quot;1:1&quot; in the parent.
        • debugnik5 hours ago
          They&#x27;re replying to<p>&gt; The UI of git - for better or worse - directly reflects its internals.
          • palata2 hours ago
            &gt; Half the git commands are low level, half are high level.<p>Can&#x27;t we say that the low level level commands reflect its internal? ...
        • jesse_ash5 hours ago
          &gt; The UI of git directly reflects its internals<p>Maybe?
  • jolmg11 hours ago
    &gt; scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze<p>`git rebase --abort` exists. One can also set a tag or something before doing the rebase, do whatever, then `git reset --hard $set_tag` to go back. Nothing to be scared of. Not like the prior state is lost.
    • rmunn10 hours ago
      I have so many branches named `temp` or `before-rebase` for exactly that reason; I&#x27;m using them effectively as tags, but branches can be moved around with less ceremony than tags (since tags are designed to be for things like v1.2.3, placed once and then almost never moved again), so I usually just do `git branch before-rebase&#x2F;some-feature` before running a big `rebase -i`.<p>I&#x27;ve almost never needed to run `get reset before-rebase`. But I <i>have</i> often done `git log -p before-rebase` and compared that to the post-rebase state of the branch, to ensure that the merge-conflict resolution(s) that came up during the rebase haven&#x27;t accidentally introduced an unintended change.
      • chrismorgan8 hours ago
        Diffing diffs is <i>so</i> valuable for that reason, seriously underrated. Once I even found a use case for diffing diff diffs.<p>I also often wish to edit commits or resolve rebase conflicts or whatever by editing the patch rather than the files.
        • amarant5 hours ago
          Hey yo,I heard you like diffs, so I put some diffs in your diff so you can diff your diff while you diff!<p>Sorry, couldn&#x27;t resist. The xzibit was too strong in your comment.
      • bjackman4 hours ago
        After a rebase, mybranch@{1} refers to the previous location of mybranch, so you don&#x27;t need to manually track these before-rebase branches etc.<p>(In practice I find this syntax super annoying and usually end up typing `git reflog mybranch` and then copy-pasting the commit hash from the output).
      • jolmg10 hours ago
        &gt; but branches can be moved around with less ceremony than tags<p>`git tag -f` to move a tag.<p>Personally, I just do `git show` when I&#x27;m feeling cautious, but I can generally just scroll up to find the last `git commit` I did with the hash in the output. `git reflog` should also have record of it, so everything else is kind of extra.
        • rmunn10 hours ago
          Good point, that&#x27;s no more ceremony than moving a branch. I guess I&#x27;ve just gotten &quot;branches are movable tags&quot; so deep into my hindbrain that I absorbed &quot;tags are hard to move&quot;. But that&#x27;s not actually true, and for what I&#x27;m doing (save this point in history for a while) a tag makes slightly more sense, semantically, than a branch.
      • hack13127 hours ago
        This is the exact same thing I do, though with the prefix &quot;pre-rebase&#x2F;&quot;
    • account421 hour ago
      You don&#x27;t even need to set a safety tag like that anywhere in git, the reflog does that for you automatically.
    • catlifeonmars11 hours ago
      Do you use git reflog?
      • jolmg11 hours ago
        One can also use that, or just `git log -n1` and taking note of the commit hash. So many options.
        • jmholla7 hours ago
          Fun fact: you don&#x27;t even need the `-n`. `git log -1` does the same thing, for any number.<p><pre><code> -&lt;number&gt;, -n &lt;number&gt;, --max-count=&lt;number&gt; Limit the output to &lt;number&gt; commits.</code></pre>
      • ibizaman6 hours ago
        I do when I forget to run the git branch comment before. But I find it still hard to understand exactly which commit to reset to in the reflog.
        • _ikke_6 hours ago
          The branch reflog (git reflog &lt;branchname&gt; or git log -g &lt;branchname&gt;) is a lot easier to follow in the case of rebase than the HEAD reflog (which gets an entry for each commit that gets checked out &#x2F; applied).
    • dalmo35 hours ago
      &gt; `git rebase --abort` exists<p>Exactly. 50% of the times I type git rebase it is followed by --abort.
    • andrepd7 hours ago
      No need for that even. Just git reflog and rewind back to any spot your want!
  • nativeit10 hours ago
    I don’t consider myself a coder or programmer, but learning git was like an organizational superpower for my particular brain wiring. I use it for websites, design projects, electronics engineering, music composition, personal knowledge bases, remote administration scripts, config management, snippets, so many applications and so many features for one system. It’s not always perfect, but I tell everyone I work with they should learn it.
    • m4637 hours ago
      I also took a leap in organization. But I don&#x27;t think you&#x27;re responding to git in particular, just a source control system.<p>git (and other version control systems) take what you made, organize and preserve it, and you can get any number of copies at a moment&#x27;s notice.<p>It is good for people to be able to do work and not worry about it.<p>I remember reading David Allen&#x27;s book Getting Things Done years ago. It takes effort to read through his writing, but he had good ideas.<p>One thing he mentioned is that you need a &#x27;trusted system&#x27; where you can collect and organize your thoughts. It lets you offload what you&#x27;re worrying about until the time you need to do something with it.<p>I actually use omnifocus to do this for my tasks&#x2F;projects&#x2F;lists, but for what I actually do on a computer, I trust git to organize and preserve the software (and some data) I have written.
    • quacked8 hours ago
      How do you use it for music composition?
      • tunesmith7 hours ago
        I use it for lilypond for notation. I always considered it superior to Finale and Sibelius anyway. Not sure how it stacks up against the more modern commercial notation apps. But I love having a real trackable version history of my pieces.<p>What&#x27;s also cool is the more advanced llms know lilypond and music theory too, so they can do things like... I don&#x27;t know, check for counterpoint errors. I&#x27;ve used it with limited success to expand my jazz lead sheets into two-hand piano arrangements just for practice exercises.
        • quacked1 hour ago
          I&#x27;ve considered using Lilypond, but I really like the autoplay feature in Musescore, as well as the lack of delay between placing notes and seeing the result.
      • knodi1237 hours ago
        there are plenty of text-based digital music notation systems. Then, you commit periodically as your composition evolves, and you can have all the history&#x2F;fork&#x2F;undo whatever that you might want.
        • seba_dos17 hours ago
          Also, files don&#x27;t have to be text-based at all to version them with Git. When you&#x27;re versioning things for your own sake, there&#x27;s often not much difference between keeping text and binary files there, as it&#x27;s not like you&#x27;ll have to resolve an unexpected conflict.
          • rmunn7 hours ago
            I find it really useful to be able to diff two commits, which if you&#x27;re using a binary format is only possible if you have a meaningful-diff tool for that format. Some formats have one already created, more formats don&#x27;t. (Though these days, an LLM might be able to produce something suitable).
  • chandlerswift9 hours ago
    I&#x27;ve been theoretically a big fan of these commands; I use the `jj` equivalents all the time. The roadblock I&#x27;ve run into is that I as far as I can tell (from the man pages and the git source code) there&#x27;s no way to get `git history` commands to sign commits they modify:<p><pre><code> $ git log --oneline --show-signature # look ma, I signed my commits! 3a1dd8f gpg: Signature made Mon 13 Jul 2026 10:45:50 PM CDT gpg: using RSA key FBF32CDBCC134B44FD29B66FA851D929D52FB93F gpg: issuer &quot;chandler@chandlerswift.com&quot; gpg: Good signature from &quot;Chandler Swift &lt;chandler@chandlerswift.com&gt;&quot; [ultimate] Second commit 03c3f6e gpg: Signature made Mon 13 Jul 2026 10:45:16 PM CDT gpg: using RSA key FBF32CDBCC134B44FD29B66FA851D929D52FB93F gpg: issuer &quot;chandler@chandlerswift.com&quot; gpg: Good signature from &quot;Chandler Swift &lt;chandler@chandlerswift.com&gt;&quot; [ultimate] Initial commit $ git history reword HEAD~ $ git log --oneline --show-signature # oops! where&#x27;d they go? 5662b2c (HEAD -&gt; main) Second commit 6bf6830 Initial commit amended </code></pre> This has pushed me back to the time-honored `git rebase -i` since I do want to keep my commits signed.
    • jmholla7 hours ago
      Woah! That feels like a huge oversight and like it bypasses standard commit logic. The man pages do say `git history` is experimental. Sounds worth a bug report.
  • jonathanlydall5 hours ago
    I&#x27;ve been doing regular significant re-writes to my local Git commit history with relative ease for over a decade even without this new Git command.<p>I&#x27;m convinced that a big part of people often finding Git and rebase difficult is a user interface issue, having to know all the correct command line options and having to make your own mental model of what&#x27;s happening and what you want to do, all makes it difficult to get a firm grasp on things.<p>I can&#x27;t comment on what equivalent alternatives (especially on macOS&#x2F;Linux as I&#x27;m a Windows user), but in terms of a UI for Git which exposes enormous power in an easy-to-use way I&#x27;ve found TortoiseGit to be spectacular and I <i>especially</i> like its rebase dialog:<p><a href="https:&#x2F;&#x2F;tortoisegit.org&#x2F;docs&#x2F;tortoisegit&#x2F;tgit-dug-rebase.html" rel="nofollow">https:&#x2F;&#x2F;tortoisegit.org&#x2F;docs&#x2F;tortoisegit&#x2F;tgit-dug-rebase.htm...</a><p>Which you kick off from a context menu option from the commit line on the commit log you want to rebase onto with a simply named &quot;Rebase &lt;current reference&gt; onto this&quot; option:<p><a href="https:&#x2F;&#x2F;tortoisegit.org&#x2F;docs&#x2F;tortoisegit&#x2F;tgit-dug-showlog.html" rel="nofollow">https:&#x2F;&#x2F;tortoisegit.org&#x2F;docs&#x2F;tortoisegit&#x2F;tgit-dug-showlog.ht...</a><p>It&#x27;s super easy to re-order, split, combine, edit commits from here and it&#x27;s <i>obvious</i> that will happen. If for whatever reason you decide you want to back out midway, you just abort and you&#x27;re back to where you were.<p>I will concede there are aspects of a TortoiseGit I find a bit annoying, particularly that I feel I have to click around too much, instead of a shell extension I would prefer an app you launch with tabs or something, but I think this is a fundamental design principle of TortoiseGit, which followed the same principle as TortoiseSVN.<p>There is Git Extensions for Windows which seems nice at a glance, I tried it briefly, but I think I didn&#x27;t stick with it either due to being unable to find an option I regularly used or I was just so used to TortoiseGit already.
    • Cthulhu_5 hours ago
      Same, but at the same time the existing workflow is a bit more clumsy &#x2F; these commands are a bit more ergonomic.<p>Fixup was already possible through `git commit --fixup`, and before that through `git rebase -i`; reword also through `git rebase -i`. I suppose the developers got enough feedback that editing a file to decide what to do with each commit was a bit frustrating for some users.<p>It&#x27;s a higher level command on existing functionality I suppose.
    • crabbone4 hours ago
      In terms of UI for Git, I&#x27;ve never seen anything getting remotely close to Magit. It&#x27;s both in-depth and a simplified stateful interface.<p>Here&#x27;s what I mean by &quot;stateful&quot;: one of the huge problems with command-line tools is that their output becomes mostly inaccessible upon subsequent invocations. Suppose you ran git-log, and now you want to apply the knowledge gained from reading its output to your next action (say, you want to cherry-pick a commit). But you are lucky if the hash of the commit in question is still somewhere in the terminal. Otherwise... you aren&#x27;t writing that from memory...<p>Stateful UI to command-line tools allows multiple interactions in parallel and preservation of information obtained in previous interactions.<p>Git <i>needs</i> a lot of state. You need to remember facts s.a. what branch you are on, what branch did you switch from, what files have been modified, what commits haven&#x27;t been pushed etc. The requirement to remember all of this is overwhelming and makes the effective use of the tool difficult. This is where various tools come to help (eg. Shell plug-ins that provide auto-completion or modify the prompt to incorporate some of that state info).<p>I believe that people complaining about difficulties of using Git are often handicapped in their use of surrounding tools that would otherwise mitigate the problems above: they don&#x27;t know how to add Shell plug-ins that display the current branch, they don&#x27;t know how to have multiple tabs&#x2F;panes open in a single terminal session, how to copy text between those tabs&#x2F;panes, they don&#x27;t know how to invoke &#x2F; search auto-complete options.<p>Genuinely, if you don&#x27;t have tools to help you use Git, something that people who are used to navigating the world of terminal UI, using Git becomes very unpleasant.
  • rom1v4 hours ago
    &gt; `git history fixup` fixes an old commit that has something wrong in it, then <i>autorebases all your branches</i> to match.<p>Simplifying `git rebase -i` is a great idea, but unfortunately, that does not match my workflow.<p>I always keep an history of my branches. For example, when I develop a feature, the first version of the branch is `myfeature.1`, then `myfeature.2`, and so on. This is useful because I can retrieve an old version when something behaves differently in a newer one. (And no, `git reflog` will not help)<p>This has saved me multiple times. For example, I can determine that a problem was introduced between `myfeature.58` and `myfeature.59`. If the &quot;feature&quot; contains 15 commits, I do:<p><pre><code> git range-diff myfeature.58~15..myfeature.58 myfeature.59~15..myfeature.59 </code></pre> This lets me see the changes between the 2 versions, commit by commit (even if they don&#x27;t have the same base).<p>I don&#x27;t want all the branches containing a commit to be rebased automatically (I already try using tags for old versions instead, but this does not quite fit).
  • nine_k11 hours ago
    In short, newer versions of git implemented three really frequent use cases of `git rebase --interactive` as separate lower-friction commands. Apparently they only work when there are no conflicts.
    • BobbyTables211 hours ago
      Wonder if the history command is all that useful.<p>I prefer the interactive rebase and use it frequently.<p>Would much rather “visually” move commits around than accidentally aim “git history” at an orphaned commit hash no longer in my local branch.
  • paxys10 hours ago
    I don&#x27;t get all the effort people spend in perfectly curating git history. No one is ever going back and reading individual commits. Just squash everything before merging and call it a day.
    • jxf9 hours ago
      &gt; No one is ever going back and reading individual commits.<p>I violently disagree with this.<p>At a minimum, when I review PRs I look at the commit history to understand what&#x27;s up. If the path that was taken to commit this is full of &quot;oops&quot; and &quot;fix&quot; messages, it&#x27;s an immediate reject for me. The commits tell the story and it&#x27;s a kindness to your human reviewers to not make them work harder to understand the point you&#x27;re trying to get across.
      • nl9 hours ago
        &gt; If the path that was taken to commit this is full of &quot;oops&quot; and &quot;fix&quot; messages<p>great way to encourage people to rebase then!
      • GrandfatherTECH9 hours ago
        What&#x27;s up with the fix commits? Maybe I misunderstood you, but there ain&#x27;t nothing wrong in fixing stuff you offer in your PR. And there can also be multiple commits even before the PR while you&#x27;re developing your PR.
        • locknitpicker8 hours ago
          &gt; What&#x27;s up with the fix commits?<p>They shouldn&#x27;t show up in the commit history. In a PR, you merge them in the commit that they actually fix. Otherwise when you use git blame to get the context of why a line of code was changed, all you see is a useless &quot;fixup&quot; message that is worse than having nothing.<p>Anyone can do better than a fixup commit. And doing metter means merging them into the actual commits that are fixed.
          • dooglius2 minutes ago
            Hence GP&#x27;s advice,<p>&gt; Just squash everything before merging and call it a day.
          • gbalduzzi7 hours ago
            &gt; Otherwise when you use git blame to get the context of why a line of code was changed, all you see is a useless &quot;fixup&quot; message<p>Isn&#x27;t this solved if you squash the commits when merging the PR? I personally don&#x27;t care that much about the commits inside a PR, the are just temporary because when a PR is merged they are squashed and you only get one commit for the whole feature on the main branches
            • NateEag6 hours ago
              I once root-caused a revenue-losing bug that had the entire rest of my team stumped with ten minutes of git-bisect.<p>It only worked that well because the team had all internalized my advice to write small, coherent commits, so the bisect landed on a ten-line change.<p>I strongly dislike the recent trend towards squashing every branch into a single monster commit.
              • LtWorf6 hours ago
                Most people who squash things have never used git bisect, cannot solve a merge conflict and when there is one will just delete the directory and clone everything again. I&#x27;ve worked with such people. They can go on like this for an entire lifetime.
                • user439285 hours ago
                  I used git bisect once in 10 years, and it was when I learned about its existence.<p>I am convinced that very few know about git bisect, much less use it regularly.
                  • locknitpicker5 hours ago
                    &gt; I am convinced that very few know about git bisect, much less use it regularly.<p>Yes, unfortunately not all companies have a high hiring bar. Some
                • skydhash1 hour ago
                  For me (I know you used most, not all). A PR is an atomic thing. Either one bug or one feature. Commits inside it are mostly time snapshots, and fixing formatting and linting errors. If I where to properly present the PR, it will also have been a single commit.
            • xorcist3 hours ago
              &gt; if you squash the commits when merging the PR?<p>You tidy up and rebase <i>before</i> making a PR. Anything else is really disrespectful of your reviewer&#x27;s time. That is also how all the larger open source projects operate.<p>&gt; you only get one commit for the whole feature<p>If you are doing one logical commit per PR, you are doing <i>way</i> too many PRs.<p>Alternatively you don&#x27;t have a working review process.
              • account421 hour ago
                Yes, often you have separate logical changes that should still be reviewed together.
              • skydhash1 hour ago
                Not really, because that one commit represent a logical changes to the codebase. It’s either in or not. Splitting it would be only cosmetic. That’s what a good PR in my opinion.<p>Presenting a series of patches is good in an email format because when I’m adding them, I can evaluate each and decide whether I want it or not. But GitHub (and forges that copies it) is lacking in that regards without me taking over the branch.<p>So the word is to make the PR the unit of changes, and only review the whole diff, not the individual commit.
            • Cthulhu_4 hours ago
              That&#x27;s one approach, sure, probably works best if your units of work (e.g. everything inside of a PR) are small and atomic though.<p>Other use cases exist where each individual commit adds value &#x2F; changes something important &#x2F; is atomic. Which one is best depends on the use case.<p>What should definitely be avoided (or, what should not end up in main) is &quot;work log&quot; commits. Many people use git commit like a save &#x2F; checkpoint operation, that&#x27;s the kind of thing nobody needs to read. That&#x27;s the &quot;fix&quot; commits.<p>Succinct guideline:<p>Good commits: &quot;When applied, this commit will &lt;commit message&gt;&quot;<p>Bad commits: &quot;I did &lt;commit message&gt;&quot;<p>Then whether it&#x27;s one commit or the result of a squash merge it doesn&#x27;t really matter much anymore.
            • locknitpicker5 hours ago
              &gt; Isn&#x27;t this solved if you squash the commits when merging the PR?<p>In theory, yes. Squashing is an extreme approach to merging fixup commits.<p>It also throws the baby out with the bathwater by removing individual commits that explain and clarify how and why some changes were introduced as part or a PR.<p>If your PRs are tiny and don&#x27;t introduce major changes then squashing is ok. Instead, you should do the right thing and curate the set of commits featuring in your PR.
              • CuriouslyC2 hours ago
                Making small atomic commits as you go in the age of AI tends not to go great because it forces too much human in the loop in a lot of cases, and the percentage of AI code rework is significantly higher than manual code, so the history tends to be harder to keep clean.<p>It&#x27;s ironically easier to create a messy agent work branch then have the agent cherry pick independent PRs from it into atomic commits post-work.
      • fcarraldo9 hours ago
        Mine aren’t full of “oops” and “fix” messages, because I squashed them.
        • bonzini7 hours ago
          So you&#x27;re &quot;spending effort in perfectly curating git history&quot; and agreeing with your parent comment.
          • ozim6 hours ago
            <i>Just squash everything before merging and call it a day</i><p>That is also a line from top comment. Everyone read „perfectly curating git history” and went rage commenting instead of reading and understanding what OP wrote.
            • bonzini6 hours ago
              Nope. Perfectly curating history is indeed the opposite of squashing—you squash <i>because</i> you couldn&#x27;t be bothered to curate your commits. Squashing is a workaround not an alternative solution.
              • ozim19 minutes ago
                You just contradicted your previous comment that was pointing out that fcraaldo is „spending effort in perfectly curating history” … or your comment was a joke with no indication it is a joke.
      • ozim6 hours ago
        But parent wrote:<p><i>Just squash everything before merging and call it a day</i>.<p>He didn’t write „leave a mess”. So it feels you wrote knee jerk comment or just writing whatever you wanted to write disregarding whatever was written.
      • InvertedRhodium9 hours ago
        Depends what the git history is supposed to show. Personally, I prefer people to leave their mistakes and reversions - though I&#x27;d require more description messages than &quot;oops&quot; or &quot;fix&quot;, something that explained why it was being reverted or swapped out would be the minimum.<p>Sometimes you try things one way and they don&#x27;t work out, so you go in a different direction. Capturing why this happened and when can go a long way towards explaining downstream decisions that might seem confusing to someone with a fresh perspective.
        • bonzini6 hours ago
          The why for a commit belongs in the message or code comments not in the history.
      • JohnMakin8 hours ago
        yea I look at commits several times a week at least, especially when commits are tied to a ticketing system&#x2F;project it helps a lot going back months later on a large codebase going “how&#x2F;why did this change happen”<p>I do tend to squash or make my entire change in one commit though so maybe I misunderstood your comment. If I have a fix commit often I’ll just tag a separate PR&#x2F;ticket to keep the change history&#x2F;change control clean
      • crabbone1 hour ago
        Parent doesn&#x27;t have experience of working with codebases with slightly high than average code quality requirements.<p>In products s.a. storage, avionics, medical appliances etc. it&#x27;s very typical to have a requirement for each commit to compile and to apply tests retroactively. I.e. once a test is added against an existing feature, it is run against <i>every</i> commit since the feature creation (this is also why git-bisect exists).<p>However, it&#x27;s true that a lot of companies would probably do better with just rsync instead of Git. Their Git history is in such a bad state that it&#x27;s basically useless. It just doesn&#x27;t make sense to use such a complicated tool as Git to deal with the average workflow.
      • ansgar774 hours ago
        I think that the path that was taken should include mistakes. It&#x27;s natural that code at some point would contain bugs and mistakes. If anything, your approach would encourage to squash those commits into one just to make it being review-worthy, but that misses the point then.
        • account421 hour ago
          It shouldn&#x27;t be that path that <i>was</i> taken but the path that will be taken when the PR is merged, split up into as many self-contained steps as possible to ease review now as well as triage if problems are found later.
      • CuriouslyC2 hours ago
        You sound pleasant to work with. I bet your coworkers route around you when they can, and when they can&#x27;t they cherry pick from their working branch to deliver monolithic commits while rolling their eyes.
        • account421 hour ago
          No, he sounds like a professional with standards.
          • CuriouslyC1 hour ago
            A professional with standards who wasn&#x27;t also unpleasant would put the time in to review the content of the commits with a request to clean up the history. Someone who looks at the history, thinks to themselves &quot;not how I like it&quot; and just auto-rejects the entire PR without any further thought is just a bad coworker.
            • account421 hour ago
              No the bad co worker is the one who is trying to offload his job on the reviewer.
              • CuriouslyC1 hour ago
                A programmer&#x27;s job is to deliver business value to their employer. If you&#x27;re slowing down PR turnaround by mindlessly auto-rejecting on stuff that the suits don&#x27;t care about, you better have a rock solid case for why that is going to deliver business value down the line, otherwise you&#x27;re actively sabotaging your employer to bikeshed your personal preferences, which is the hallmark of a bad employee.<p>Rejecting an obviously bad PR after scanning the code quickly is one thing, burning business cycles on PR turnaround&#x2F;latency to bikeshed bookkeeping without spending any time on the actual value producing portion of the PR is just bad. At the minimum you wasted an opportunity to give feedback on the proposed solution, thus probably necessitating another round of reviews, with the associated org latency.
                • account4220 minutes ago
                  You are assuming that the only thing the business in question cares about is moving fast without any consideration for long-term health. I&#x27;d consider that a bad place to work at.
                • skydhash45 minutes ago
                  In most business settings, the ticket is the unit of value to the business. If a ticket is to big, the best way is to split it into several ticket. Then you create a PR for each. There can be some automation that update the status of the ticket alongside the PR. Splitting a PR futher into commits doesn’t make any sense, because the whole business operates with tickets.<p>When I do it, it’s for my convenience. I expect the reviewer to review the diff at the PR level, not at the commit level. And when it’s approved, I’ll squash and merge, because only the whole PR matters.<p>When the commit is the unit of work (email workflow) I curate locally.
      • danieltanfh959 hours ago
        NGL AI usage is driven by friction in presentation and communication over petty details.
      • bobbylarrybobby9 hours ago
        Do you really care if someone forgot to format before committing? They can always squash and push locally if they need to.
        • LtWorf6 hours ago
          I really really really do not want the autoformatter stuff happening in the same commit as where the real thing happens. I don&#x27;t care to review if the autoformatter is working properly.
        • locknitpicker8 hours ago
          &gt; Do you really care if someone forgot to format before committing?<p>Not OP but yes I definitely do. If you expect others to spend time reviewing your code, you are obligated to start off by reviewing it yourself. Posting a mess helps no one and makes code harder to audit.
      • gofreddygo8 hours ago
        Oh that is such a bad heuristic ! The commits and history of how a PR was put together is no indicator of the quality of the PR or the thought process that led to it. Thats the equivalent of rejecting a (handwritten) essay for having too many corrections. ridiculous.<p>The code is all that should matter. Maybe comments for being nice to others and my future self. thats it.
        • locknitpicker8 hours ago
          &gt; The commits and history of how a PR was put together is no indicator of the quality of the PR or the thought process that led to it.<p>It is, because it means the person posting the PR didn&#x27;t even bothered to review the changes they are forcing others to review.<p>Just clean after yourself before asking others to read your stuff.
    • jhealy9 hours ago
      &gt; No one is ever going back and reading individual commits<p>I do, regularly! In a repository where care has been taken, it can be super valuable when tracking down a bug or regression, and understanding the intent of the author
      • bad_username6 hours ago
        The debate between these who don&#x27;t squash and these who do is the debate between these who use the history for bugfixing and those who don&#x27;t. And I think not using it is throwing away a super valuable tool that can reduce the fix ETA by an order of magnitude.
    • jolmg10 hours ago
      &gt; No one is ever going back and reading individual commits.<p>Straight from the git-log, maybe not, but sometimes you see code that makes you wonder how it came to be and it can help a lot to see it in context of the commit that introduced it. That&#x27;d be less helpful if that commit were some huge thing making lots of different changes at once.
      • paxys9 hours ago
        Seeing the individual change in the context of the larger feature is actually more helpful. Otherwise you find a tiny commit that changes A to B and then have to chase down 13 other commits around it to figure out why that change was even made.
        • jolmg9 hours ago
          Yeah, there&#x27;s a balance. I try to make my commits so they make sense on their own.<p>&gt; commits around it to figure out why that change was even made.<p>A commit should be such that the message can articulate the why.
    • nextlevelwizard7 hours ago
      How do I know you don’t work in a big team from this?<p>First thing I do every time I come back from vacation is to read through our git history to see what has happened.<p>It is also very useful when CI breaks. In fact I probably use some form of git history reading every day at work.<p>Also if your code base is so tiny and the features you work on are so small that you can just squash everything then maybe that is fine for you. I definitely love being able to actually see what is going on and selectively cherry picking or reverting commits
    • broodbucket10 hours ago
      Having a well curated one-logical-change-per-commit history is incredibly valuable when bisecting a regression.
      • efilife9 hours ago
        Didn&#x27;t you mean &quot;dissecting&quot;?<p>Edit: thanks guys, that&#x27;s very useful knowledge! Could have saved me many times in the past
        • psadauskas9 hours ago
          Nope, `bisect`: <a href="https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-bisect" rel="nofollow">https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;git-bisect</a><p>Figure out a command to test it, a known-good sha and a known-bad sha, and it will binary search its way through the history to find the commit that introduced the failure.
        • seba_dos19 hours ago
          Check out &quot;man git-bisect&quot;.
        • jolmg9 hours ago
          <p><pre><code> man git-bisect</code></pre>
    • Hendrikto3 hours ago
      I am always aghast at how proudly people pronounce that they don’t know how to use one of the most central and essential tools in the belt of a software engineer.<p>Maintaining history is well worth it, and allows you to use tools like<p><pre><code> git rebase git revert git bisect git blame # … </code></pre> It also makes reviewing and understand your code much easier.
      • fragmede3 hours ago
        git bisect, connected to a script that outputs good&#x2F;bad, is one of computing&#x27;s crowning achievements, imo.
    • Izkata8 hours ago
      I do multiple times a week, with repos that have barely been touched in a decade and all the original devs are gone. Squashing would make figuring out why something is the way it is a lot more painful, so I&#x27;m glad these repos are svn where squashing wasn&#x27;t an option. Several times I&#x27;ve discovered bugs that were introduced in linting commits that would have been squashed, so the fix ends up trivial since the intention is already there in the previous commit.
    • christophilus1 hour ago
      I’m with you, but it’s obviously a sensitive topic for a lot of folks, based on the replies. Some people’s brains are just wired differently, I guess. I rarely look at history, other than git blame. For me, history does not need to be granular at all. The replies make it sound like curating git history is the job, rather than shipping solutions to customers’ problems. I guess, if it helps you ship faster &#x2F; better, more power to you.
    • CuriouslyC2 hours ago
      Squashing everything has a significant downside compared to functional atomic commits: git-bisect gets WAY less useful.
    • aardvark1795 hours ago
      Having maintained internal forks, and having needed to pull in and rebase upstream changes I do read a lot of commits. Projects that take care with their commits are much easier to work with.<p>This is also true when creating with security patches and other things that need to be backported to multiple releases.
    • msteffen8 hours ago
      One use-case for curating commits other than git history is carefully structuring code reviews to be easy to review. Eg &quot;commit 1 just rearranges existing code, no business logic changes&quot;...&quot;change 2 modifies business logic, but in one localized place as the refactoring has already been done&quot;...&quot;change 3 only modifies comments&quot;
    • Cthulhu_4 hours ago
      I have a more nuanced view of this; in libraries and software projects that span years like Linux, curl, etc, this happens all the time. Bugs get fixed and they can point to the exact commit where it was first introduced, and that commit contains all information necessary to figure out why it was introduced in the first time.<p>But that&#x27;s projects like Linux, which is a whole different use case than for example what I do for a living, front-end applications that have at best a lifespan of 10 years and whose individual features &#x2F; screens &#x2F; components have less than that, and it&#x27;s much more rare that an older commit is still relevant today.<p>(that said, looking history up has made me dislike squash commits. I get it from a pragmatic point of view but it&#x27;s not ideal)
    • seba_dos110 hours ago
      Of course we do and it helps tremendously when the graph is reasonable.
    • smcameron8 hours ago
      Disagree. You need small, git bisectable commits. Use stgit to do it and it&#x27;s nearly effortless.
    • EPWN3D9 hours ago
      Sorry, no. Just because you&#x27;ve never done it doesn&#x27;t mean that no one ever will.<p>Beyond the archival benefits, I&#x27;ve found plenty of bugs by going back through my &quot;wip&quot; commits and creating a sane history from them.
    • sitkack9 hours ago
      That is like saying once the program is done, throw away the source.<p>Lemme guess all your for commit say &quot;wip&quot;
      • yjftsjthsd-h9 hours ago
        It&#x27;s really not. Source code, even with no history, can be modified, adapted, ported, fixed, and improved. Having history is nice, but it&#x27;s way lower marginal utility.
    • dkdbejwi3834 hours ago
      I could count the number of times I&#x27;ve written a detailed summary in the body of a commit message, and had it read by my colleague reviewing who then didn&#x27;t need to leave a comment on the PR asking why I did _x_ on zero hands.
    • Myrmornis10 hours ago
      One good reason is to keep your tests separate from the fixes that make your tests pass. That way you can check your test fails before the next commit makes it pass, eliminating the risk of a false negative (test passes that would have anyway).
      • Cthulhu_4 hours ago
        That&#x27;s one approach I suppose, it leaves evidence of &quot;I wrote a test first&quot; and such.<p>However, it also feels more like a &quot;work log&quot; than a &quot;commit log&quot;; I like to make my commits atomic (test + code at the same time), so that in theory, each individual commit will pass CI. If you separate them, you can&#x27;t just revert one commit, you need multiple.
      • assbuttbuttass9 hours ago
        That sounds like it would break bisect
        • bonzini8 hours ago
          You can develop with failing tests and reorder them after the code change before publishing your branch.
          • assbuttbuttass49 minutes ago
            Of course, but this thread was in the context of someone &quot;carefully curating&quot; their git history
        • Myrmornis9 hours ago
          Fair. I think what I&#x27;d say is that we don&#x27;t have to use plain git bisect -- it would be quick to make a bisect script that doesn&#x27;t land on the failing-test commits. Especially seeing as most teams squash before merging, we should have the freedom to create failing-test commits.
        • jolmg9 hours ago
          Right, maybe a better way to get what they&#x27;re going for would be<p><pre><code> git checkout @~ ^tests </code></pre> where ^tests is zsh&#x27;s way of saying * except for tests. So you get the tests&#x2F; of the current commit and the code of the prior.
        • locknitpicker8 hours ago
          &gt; That sounds like it would break bisect<p>Nonsense. First off, you can pick the starting commit, and nothing forces you to pick the test one. Second, bisect is designed to tracks changes from good state to bad state based on your personal criteria of what good and bad is. This means that you are free to put up tests that make sense to you (i.e., all tests except the one that was added as a red test) and even not run a test at all.
          • account421 hour ago
            And you can also use bisect by first figuring out the broken commit some other way and then marking everything as good if its before that one or bad if its after - but that&#x27;s not a very productive use of bisect and if its the only available one I think its fair to call it broken.
            • locknitpicker3 minutes ago
              &gt; And you can also use bisect by first figuring out the broken commit some other way (...)<p>Bisect exists to be a tool you can use to fix the problems you are facing.<p>It you are faced by problems you create for yourself and you are unwilling to work around the problems you are creating then there is no tool on earth that can help you.
          • assbuttbuttass39 minutes ago
            Suppose we have a failing test. For many commits, gp carefully separated their change that would break our test, from the change that would fix the test. At some point, someone forgot to run the tests, and introduced a commit that broke the test without adding a second commit to fix it. Now it&#x27;s treated as a &quot;pre-existing failure,&quot; and many more commits are added on top.<p>How would you identify the commit that broke the test?
            • locknitpicker0 minutes ago
              &gt; How would you identify the commit that broke the test?<p>You&#x27;re asking how to use bisect.<p>You start with a range of commits you picked. All that bisect does is help you search for a commit within that range that introduces a regression. The responsibility to specify which commits you cover is yours, not the tool.
    • fragmede7 hours ago
      &gt; No one is ever going back and reading individual commits.<p>Hell yes we are! Just because you aren&#x27;t going to doesn&#x27;t mean nobody else is going to.
    • locknitpicker8 hours ago
      &gt; No one is ever going back and reading individual commits.<p>Your assumption doesn&#x27;t match the real world practices I&#x27;ve experienced for years across multiple jobs. Even at the PR stage a clean commit history is of critical importance. Nowadays, with ai coding assistants assuming a central role in developing software, commit history is even used as input with context signal, allowing for flows such as &quot;evaluate the changes in commit X and Y and apply the same pattern to project Z&quot;.<p>Just because you don&#x27;t use a tool properly that doesn&#x27;t mean everyone around you makes the same mistake.
    • penguin_booze6 hours ago
      Might as well go back to the tar.gz days, eh?
    • vcf9 hours ago
      I almost never went back to read the history, but now I often have Claude go through the history when I wonder how we got to a certain point. It can point me to the relevant issues as well. Squashing is fine, up to a point.
    • LtWorf6 hours ago
      Spoken like a guy who really really doesn&#x27;t understand how git works and has never bothered to learn!
    • ex1fm3ta9 hours ago
      I do not agree at all. When you have multiple repos accross different services, commits are the best way to follow up with differents changes. We adopted conventional commits guidelines a few months ago and everyone is happy. Even ClaudeCode is able to keep up and auto fix stuffs with the proper commit messages. The changelog is dynamically updated. Everything so smooth when those commits messages are perfectly synchronized.
  • shepmaster11 hours ago
    &gt; That last part goes further than git rebase --update-refs, which only moves refs sitting inside the range you’re actively rebasing. git history instead finds and rewrites every local branch descended from the commit (while also having an option to limit it to only the current branch).<p>I&#x27;m reading that to mean that when I use `git rebase --update-refs` in this situation, where I&#x27;ve currently checked out `D` and update `B` to `B&#x27;`:<p><pre><code> A ──► B ──► C ──► D │ └───► E </code></pre> I&#x27;ll end up with this state, where `E` remains untouched?<p><pre><code> A ──► B&#x27; ─► C&#x27; ─► D&#x27; │ └───► B ──► E </code></pre> (EDIT: Originally I had `E` point to `B&#x27;`, which doesn&#x27;t make sense)<p>If I use `git history fixup`, it would also update `E` and end up with this?<p><pre><code> A ──► B&#x27; ─► C&#x27; ─► D&#x27; │ └───► E&#x27; </code></pre> If that&#x27;s the case, is there a way to get `git rebase` to have the same behavior? I&#x27;ve got decades of `git rebase` burned into my fingers at this point.
    • jolmg11 hours ago
      &gt; I&#x27;ll end up with this state, where `E` remains untouched?<p>Can&#x27;t, because a commit&#x27;s hash takes into account the parent hashes.<p>Haven&#x27;t used --update-refs, but reading it, it should result in your third graph. So,<p>&gt; is there a way to get `git rebase` to have the same behavior?<p>is already the case.
      • shepmaster10 hours ago
        &gt; Haven&#x27;t used --update-refs, but reading it, it should result in your third graph.<p>I don&#x27;t think it does. I tried locally:<p><pre><code> mkdir test; cd test; git init touch a; git add a; git commit -m &#x27;a&#x27; touch b; git add b; git commit -m &#x27;b&#x27; touch c; git add c; git commit -m &#x27;c&#x27; git checkout -b branched-feature HEAD~ touch d; git add d; git commit -m &#x27;d&#x27; git checkout main echo &#x27;change&#x27; &gt; b; git add b; git commit -m &#x27;fix b&#x27; git rebase -i --root --update-refs </code></pre> And ended up with this graph (`git log --graph --all`)<p><pre><code> * commit (HEAD -&gt; main) | | c | * commit | | b | | * commit (branched-feature) | | | | d | | | * commit |&#x2F; | b | * commit a </code></pre> Replacing the `git commit -m &#x27;fix b&#x27;; git rebase -i --root --update-refs` with `git history fixup HEAD~` produces what I&#x27;d like:<p><pre><code> * commit (branched-feature) | | d | | * commit (HEAD -&gt; main) |&#x2F; | c | * commit | | b | * commit a</code></pre>
        • jolmg10 hours ago
          Huh.. That&#x27;s a shame :(. Maybe what it refers to is if you had a branch on B rather than D, it might update that.<p>EDIT: Yeah, this seems to be it. `git branch b` on b, then `git rebase -i --update-ref @~3` from main caused branch ref `b` to move from d86229e to 02fcaf7:<p><pre><code> * 1e354fb (HEAD -&gt; main) fix b * 40e6f70 c * 02fcaf7 (b) b | * f4188e0 (branched-feature) d | * d86229e b |&#x2F; * 5fe78fa a</code></pre>
        • Izkata7 hours ago
          &gt; And ended up with this graph (`git log --graph --all`)<p>Add --oneline to get the compact version from the other reply.
      • seba_dos19 hours ago
        It won&#x27;t result in the third graph on its own as E isn&#x27;t reachable from D, but it could if you first merged D and E together and <i>then</i> used --update-refs with --rebase-merges. You could then just discard the merged branch and only take care of D&#x27; and E&#x27; on their own (and since you don&#x27;t care about the merged branch, you don&#x27;t have to care about resolving conflicts while preparing it either).
      • rmunn10 hours ago
        Unless E remained untouched because it was <i>not</i> rewritten, and ended up staying parented on B instead of getting reparented onto B&#x27;.<p>Which is usually <i>not</i> what you want; most of the time you want E&#x27;, which is E reparented onto B&#x27;. But <i>sometimes</i> you want E to remain untouched and stay parented on the original B. Depends on the situation.
        • jolmg10 hours ago
          Exactly, but the second graph where untouched E is reparented to B&#x27; is not something that git would allow.
          • shepmaster10 hours ago
            Ah, good catch. That&#x27;s more of a graphic issue and not what I was trying to express. Updated the OP.
    • lelandfe11 hours ago
      See: <a href="https:&#x2F;&#x2F;blog.hot-coffee.dev&#x2F;en&#x2F;blog&#x2F;git_update_refs&#x2F;" rel="nofollow">https:&#x2F;&#x2F;blog.hot-coffee.dev&#x2F;en&#x2F;blog&#x2F;git_update_refs&#x2F;</a>
      • shepmaster10 hours ago
        I&#x27;m not sure that answers my question. That shows a linear set of branches (my-feature-v3 depends on my-feature-v2 depends on my-feature-v1 depends on main). I&#x27;m asking about the case where two or more branches fork from a common ancestor and you want to fix the common ancestor.
    • m4639 hours ago
      off-topic, but that is a very clear readable comment you left with those line-drawing characters.
      • shepmaster9 hours ago
        You can thank ASCIIFlow for that ;)<p><a href="https:&#x2F;&#x2F;asciiflow.com&#x2F;" rel="nofollow">https:&#x2F;&#x2F;asciiflow.com&#x2F;</a>
  • whilenot-dev3 hours ago
    Cool, didn&#x27;t know about `history fixup`! I only ever did the manual dance with `rebase -i` and `rebase` for all other branches. That and `history split` will sure come handy!<p>What happens with a conflicting fix though? Do I still need to resolve all conflicts on the base branch and `reset --hard` all other branches?
  • quibono3 hours ago
    &gt; scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze<p>I&#x27;m glad to hear it, I thought that was just me. It gets especially hairy when moving commits around...<p>Plus I have 3-way diffs enabled and I usually get confused by which section is which at least once a day.<p>Also: does anyone know if `magit` has history support?
  • paularmstrong11 hours ago
    `git history split` is really going to help me help juniors break up their large PRs into smaller more concise changes. If only it had the option to split an entire branch in two easily.
    • jolmg10 hours ago
      Maybe the issue is they think of a PR as an expensive thing. Would be best if they could just do the small thing and make a PR of that from the get-go. If they want to base future changes on the ones they just did, they can just create a new feature branch from right there, and just not create the PR of the second feature until the first is merged, or create it and add a note to the reviewer that it includes the changes of the other PR so they should review that one first. Should they want to add changes to the first feature, they just need to checkout that branch, do the changes, and merge to the second feature branch so they&#x27;re available there.
      • CuriouslyC2 hours ago
        Small stacked PRs are a NIGHTMARE unless your org is consistently turning around PRs in low single digit hours, and team members are working on decoupled code so you don&#x27;t have any stack weaving. You end up in a situation where the engineering director and some tech leads really like tools like Graphite, while the entire team working under them mutters irately under their breath daily.
      • ellefire5 hours ago
        It&#x27;s expensive when you factor in each PR having to wait for someone to come and review it - it&#x27;s easier to get your work done in larger PRs when that&#x27;s the case, although it&#x27;s a perverse incentive
        • account4254 minutes ago
          Even with low review turnaround, having each PR get to a defined &quot;goal&quot; makes it clear if the early commits that prepare the co-debase for the goal are going in the right direction. If they were submitted as individual PRs the reviewer can only check that they don&#x27;t break things but has to trust the submitter that the design is right for what will follow.
    • catlifeonmars11 hours ago
      What does it mean to split a branch in two?
      • rmunn11 hours ago
        Probably to take a series of commits and decide &quot;this one goes on branch A, this one on branch B&quot;, e.g. if you intermingled fixing bug A and B in the same branch, you could more easily go through and assign each commit to a new branch.<p>The existing workflow for that would be (there are several possible workflows, but this is what I would do):<p><pre><code> git checkout intermingled-branch git branch bugfix-A git branch bugfix-B git checkout bugfix-A git rebase -i # Edit the file, keep commits that fix bug A, drop commits that fix bug B git push origin bugfix-A:bugfix-A git checkout bugfix-B git rebase -i # Edit the file, keep commits that fix bug B, drop commits that fix bug A git push origin bugfix-B:bugfix-B</code></pre>
        • LtWorf3 hours ago
          So git cherry-pick?
  • krick7 hours ago
    &gt; scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze<p>Complete bullshit. Might as well say &quot;scary screwdriver that can turn up in your recturm if you so much as sneeze&quot;. Sure, I believe that might have happened to you (heard stories from friends that work in the emergency room), but I run rebase -i 10 times during the time I work on each branch (literally: I don&#x27;t even care to write &quot;proper&quot; commit messages while writing the code, will reorganize and clean them up later anyway), and it never happened to me.
    • eviks6 hours ago
      &gt; commit messages while writing the code, will reorganize and clean them up later anyway<p>That&#x27;s just too primitive of a workflow, so repeating it will not run into the risk. You need to add an actual conflict in some feature branch and get stuck being forced to resolve it to compete the rebase to appreciate the op warning
  • hahahaa11 hours ago
    I like to be like an accountant. No editing history. Create a new &quot;journal entry&quot; (i.e. commit) to fix.
    • account4248 minutes ago
      There is history that has already happened (e.g. what has been merged to master) and history that will happen (e.g. unmerged pull requests).
    • seba_dos110 hours ago
      Commit graph is just a data structure. Sometimes it represents a &quot;history&quot;, sometimes other things.<p>Personally, I like it when project&#x27;s repository represents the history of the project rather than the history of random things developers do on their machines, but you do you.
      • hahahaa10 hours ago
        I am thinking of remote. Edits before pushing OK with me (they ate equivalent of recloning and redoing anyway)
        • seba_dos110 hours ago
          Remotes aren&#x27;t equal either. Sometimes the remote is my other machine, sometimes it&#x27;s a fork on a forge used for producing CI artifacts.<p>It&#x27;s a good rule of thumb to consider shared branches to be append-only, but not every remote branch is &quot;shared&quot; and, as with any proper rule of thumb, you can always find exceptions.
          • hahahaa4 hours ago
            Ok I amend to what I think I really mean: don&#x27;t edit history for anything deployed to prod (or released to public or customers) already.
    • what10 hours ago
      You probably shouldn’t be committing things that are broken…
      • plorkyeran7 hours ago
        You should be committing things that are broken all the time. Git works great as a persistent navigatible undo buffer, and you should commit every time you&#x27;re in a state that you might want to return to.
        • smcameron4 minutes ago
          That breaks git bisect.
      • normie30009 hours ago
        This is likely saying you shouldn&#x27;t save a word document that contains spelling mistakes.
      • moezd10 hours ago
        With tools like GitHub Actions and some added constraints, it&#x27;s not always possible. You literally need a commit to trigger the CI workflow and it starts to trash your branch. Besides, aren&#x27;t we all familiar with git commit -m &quot;typo&quot;?
        • ninkendo26 minutes ago
          &gt; With tools like GitHub Actions and some added constraints, it&#x27;s not always possible. You literally need a commit to trigger the CI workflow and it starts to trash your branch<p>I&#x27;m with you on your overall point, but as a side note: this state of affairs is so tragic. It&#x27;s been normalized for there to be test suites that nobody can run except the CI runner, and the only real way to run all the tests is to have GitHub do it. It&#x27;s pure lock-in, and it&#x27;s very sad that everything&#x27;s moved this way.<p>CI actions should be a simple file of &quot;action: command&quot; lines, with <i>at most</i> a separate file that describes when given actions should run. All actions should be runnable locally just as easily as they are in CI. Or if the actions are so complicated they need a complex-ish environment, that environment should be the kind of thing you could run locally too with your hypervisor of choice, without having to think about it. But <i>every</i> VCS host that has an actions&#x2F;pipelines product is financially incentivized to encourage you not to set things up this way, to preserve their lock-in.
      • hahahaa10 hours ago
        Commit yes you absolutely can. Merge to trunk? Probably not, depends on your strategy.
  • eviks6 hours ago
    &gt; Every 3 months, for the last 1.5 years, I try it out for a few days, really trying to make it part of my workflow but eventually I give up and go back to git.1<p>That&#x27;s not really trying, let&#x27;s assume you need 1 week to change ingrained workflows, so you just waste time every 3 months stopping right before the threshold. Better try once every year, but for a few*4 days...
  • runtime_lens6 hours ago
    git reflog is probably the Git command that has saved me the most stress. At some point you stop worrying about experimenting because you realize it&#x27;s surprisingly hard to lose work permanently. Git is muuch more forgiving than it first appears.
  • bentt11 hours ago
    Granted, I have a perspective of a game dev, but this kind of repo defiling just gives me the willies. IMO instead of finding a common ancestor and altering it, just make the desired change upstream and merge it to where it’s needed. If you can’t do that then you have already made a deal with the devil and might reconsider your approach. KISS
  • froh8 hours ago
    TIL, thx :-)<p>somewhat related Q:<p>how do you give two files the same ancestor? so git log will for each show the history to the beginnings of the originally unsplit file? useful for splitting large files.
    • bonzini8 hours ago
      That&#x27;s not possible, because files don&#x27;t have ancestors in git. Each commit&#x27;s tree is tracked independently and copy&#x2F;move is just something that&#x27;s detected via heuristics.
      • account4244 minutes ago
        But those heuristics could be better than they are now so that a git log &lt;file&gt; will show the shared history for both copies.
  • _nivlac_10 hours ago
    I like `git history reword`, would&#x27;ve found that useful in the past (e.g. fixing a bad typo in an older commit).<p>It sounds like there was probably an equivalent using an existing command but this is easier for me to understand. Thanks for sharing!
  • anuramat4 hours ago
    is there a way to use it with lazygit? unfortunately I&#x27;m addicted atp, and &quot;autorebase branches&quot; is exactly what I was missing the entire time
  • SCUSKU5 hours ago
    These graphics are great. Makes for a skimmable high signal article, nice work!
  • rushil_b_patel7 hours ago
    the &quot;reword&quot; option is same as git rebase -i HEAD~n, and then instead of pick replace it with reword to change the commit messsage.<p>BTW I have made a notion doc on git commands: <a href="https:&#x2F;&#x2F;rushilpatel.notion.site&#x2F;git" rel="nofollow">https:&#x2F;&#x2F;rushilpatel.notion.site&#x2F;git</a>
  • Sharlin4 hours ago
    Huh, TIL about `git commit —fixup`.
    • Cthulhu_4 hours ago
      Yeah I learned that one a few months ago, before that I&#x27;d use interactive rebase and shuffle the commits around manually in the editor that opens.<p>I appreciate that these commands are just utilities &#x2F; conveniences on top of a stable base though.
  • smcameron8 hours ago
    &gt; Working with lots of changes in parallel on git can be painful. You end up juggling branches and commits, and running scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze.<p>I mean, just use stgit[1] to maintain a stack of patches instead of parallel branches, it&#x27;s <i>so</i> much better. You can <i>easily</i> wrangle <i>thousands</i> of patches (aka commits) with stgit.<p>A lot of people, on first encountering stgit, read a bit about it, think &quot;why do I need this? I can do the same thing with just plain ol&#x27; git.&quot;. Yeah, you can. But not at scale. Not practically. Not with thousands of commits. And it makes the case when you just have a few tens of commits absolutely trivial. Try it for awhile and you&#x27;ll find it indispensible.<p>[1] <a href="https:&#x2F;&#x2F;stacked-git.github.io&#x2F;" rel="nofollow">https:&#x2F;&#x2F;stacked-git.github.io&#x2F;</a>
  • kazinator6 hours ago
    The thing is, when you are rewriting history to change an old commit, you have to solve the little problem that git commit messages refer to hashes such as:<p><pre><code> This regression was caused in &lt;hash&gt; on December 19, 2017. </code></pre> The fixup and rewrite of history has to ferret out these has references and fix them to the new hash of the same commit.<p>I have scripted this before!
  • skydhash11 hours ago
    &gt; Working with lots of changes in parallel on git can be painful. You end up juggling branches and commits, and running scary rebase -i commands that can leave your tree in a half-broken state if you so much as sneeze.<p>I think that only happens when you work on code as text files (i.e character streams) instead of code (i.e structured content with meaning). Like you have commit A and commit B that is in conflict, you should be glad because that&#x27;s a rough signal that the intent of A and B differs. Your goal should be to think about how to compose A and B so that both intent survives (unless one supersedes the other). Which means you should be at least familiar with A and B.<p>The issue I found with people that fears conflict is that they often don&#x27;t understand either A or B (or both). So they are a bad candidate to actually do the operation. It&#x27;s not a matter of git&#x27;s cli interface, it&#x27;s a matter of codebase comprehension and how well you&#x27;re familiar with the changes in question.
    • thfuran11 hours ago
      Git is the one treating code like a text file instead of code.
      • UnfitFootprint11 hours ago
        I pull out difftastic when it’s all too hard for this. Diffs based off tree sitter
        • NateEag6 hours ago
          Don&#x27;t forget mergiraf, for tree-sitter-based conflict resolution:<p><a href="https:&#x2F;&#x2F;mergiraf.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;mergiraf.org&#x2F;</a>
      • skydhash10 hours ago
        Git store whole files. The diff and the merge algorithm works by line by default, but that&#x27;s because line is a rough unit of code (statement, expression, and definition happens mostly within one line).
    • bulatb11 hours ago
      I can fully understand a conflict, know it&#x27;s coming, and fear it anyway because I&#x27;ll have to deal with Git&#x27;s behavior to fix it.
      • seba_dos111 hours ago
        Such as?<p>When you merge a commit in that changed a file that has been already changed since the common ancestor, Git runs a tool of your choice on this file. If the tool fails, it marks the file as needing a merge and doesn&#x27;t let you commit it until you unmark it to confirm that you have merged it manually. In case of octopus merges, it will just abort early. That&#x27;s basically its whole behavior when it comes to conflicts.
        • bulatb10 hours ago
          Such as moving down a fixup during interactive rebase when it&#x27;s going to conflict with parents, or I&#x27;ve added more commits mid-rebase, or the rebase started in a tool and now I need to think about the tool&#x27;s command and understand how many times the rebase point is view is backwards to interpret which is &quot;ours&quot; and which is &quot;theirs&quot; and whether it&#x27;s the tool, my editor, or my own experience I should ignore because it&#x27;s going to mislead me.<p>None of that word salad should matter, but it does. Git will ruin <i>everything</i> with glee and there is always an excuse for why that&#x27;s fine and it&#x27;s the user&#x27;s fault.
          • seba_dos110 hours ago
            There&#x27;s nothing &quot;backwards&quot; in &quot;rebase point of view&quot;. It&#x27;s just automated cherry-picking - it&#x27;s like applying patches, it&#x27;s as forwards as it gets. People who think it&#x27;s &quot;backwards&quot; usually just have holes in their mental model of the repository. And yes, I find tools doing what you&#x27;re asking them to do to be rather fine. In fact, Git makes it easy to notice when you&#x27;re adding commits mid-rebase, which is something I often do intentionally, as it tells you what the HEAD is (and even shows a detailed state of the in-progress rebase) while authoring the commit message.
            • bulatb10 hours ago
              I understand how rebase works and use it many times a day. Thanks for trying to explain but I won&#x27;t respond further.
              • seba_dos110 hours ago
                These aren&#x27;t troubles of someone who understands. If anyone else reading this has these kinds of troubles too - don&#x27;t worry, understanding abstractions takes time and effort, you&#x27;ll get there eventually (not if you&#x27;ll keep blaming others though).
                • bulatb9 hours ago
                  Let me eat the crow of getting drawn back in and cap this conversation with a summary. I think this is important because criticizing Git&#x27;s UX is always like this.<p>OP: No one should be worried about using Git to do a thing.<p>bulatb: I&#x27;m worried it will be unpleasant.<p>seba_dos1: Here is what will happen when you do the thing.<p>bulatb: I know, but doing it will be unpleasant.<p>seba_dos1: You must not understand what&#x27;s going to happen.<p>bulatb: I do. The process is unpleasant.<p>seba_dos1: You must not understand what&#x27;s going to happen.
                  • seba_dos19 hours ago
                    Had you actually read what I wrote, you would rather summarize it as &quot;Git is showing exactly what&#x27;s going to happen when you attempt to do it, all you have to do to make is pleasant is to not ignore it&quot;. Reading things requires unpleasant effort though, I get it.
                    • bulatb8 hours ago
                      I&#x27;m sorry (like actually sorry) if I&#x27;m getting into counter-condescension here, but, like...<p><i>&gt; all you have to do to make is pleasant</i><p>This is an assumption about what I find unpleasant and why. I take it you think &quot;reading information&quot; and &quot;understanding instructions&quot; are some of those things I don&#x27;t like. Your conclusion that I must not understand is based on that assumption.<p>The assumption is wrong.<p>If you can grant me that, my problem looks different. If you can&#x27;t or won&#x27;t, my summary was right.
                      • seba_dos17 hours ago
                        If the assumption was wrong, then your first comment was pretty much useless, and the second one didn&#x27;t help either as it just describes doing things carelessly and without proper understanding. So if that reading of it is wrong, then it was just complaining for complaining&#x27;s sake and not about Git at all, but rather about what you happen to find scary for some undisclosed reason?<p>People do have genuine troubles with these behaviors when they don&#x27;t grasp what&#x27;s going on well enough. These troubles go away pretty much entirely once they do. I think explaining them is the only thing one could write in such thread that will be useful to anyone, as the Git&#x27;s UX already does make a pretty good effort to help the user orient themselves in these cases and has been visibly improving in this regard over time.
                        • bulatb3 hours ago
                          My point to the OP is the same thing I&#x27;m saying to you. &quot;I understand the thing and think it&#x27;s fine&quot; does not imply that nobody who understands the thing can think it isn&#x27;t fine, or anyone who doesn&#x27;t like the thing just doesn&#x27;t understand it.<p>It&#x27;s not some deep or interesting idea, but it needs to be repeated any time &quot;git gud&quot; is used as an excuse for Git&#x27;s UX, which is always.
          • skydhash10 hours ago
            &gt; which is &quot;ours&quot; and which is &quot;theirs&quot;<p>&quot;ours&quot; is always HEAD, usually meaning the state of the working_tree, &quot;theirs&quot; is always the commit that is going to change the working_tree.<p>When merging, you are taking change from another branch (theirs) to create a new commit on the current branch (ours) that ties the two together. When rebasing interactively, you switch to the new base (ours) and replay the changes of the branch (theirs) according to the edit file.<p>Etymology matters. The conceptual model of git is simple, but people only focus on the operations. That&#x27;s like trying to learn algorithm and data structures and focusing on the words &quot;insert&quot;, &quot;remove&quot;, &quot;find&quot;, without trying to learn &quot;list&quot;, &quot;stack&quot;, &quot;tree&quot;,... first.<p>Instead learn about Git&#x27;s glossary [0], then how the operations use and modify those concepts.<p>[0] <a href="https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;gitglossary" rel="nofollow">https:&#x2F;&#x2F;git-scm.com&#x2F;docs&#x2F;gitglossary</a>
  • tangsoupgallery1 hour ago
    [flagged]
  • jocelyner9 hours ago
    [dead]
  • xyzsparetimexyz5 hours ago
    Tldr; use jj