Staging patches with Git add -p

(simonholywell.com)

27 points | by ankitg12 4 days ago

11 comments

  • BeetleB 53 minutes ago
    > If you’re not already using git add -p to stage your commits then you’re missing out.

    After switching to jujutsu, I assure you I don't miss this feature.

    jj takes the opposite approach. It keeps staging things, and you use split whenever you want to separate things out.

    (And yes, it stores the staged changes as revisions, so you can always back out to a previous staged state).

    • hamdingers 0 minutes ago
      > jj takes the opposite approach. It keeps staging things, and you use split whenever you want to separate things out.

      Sounds like `git add .` then `git reset -p`

    • pmarreck 49 minutes ago
      I've sadly had to back out of using jj after leaning into LLM coding assistance, as, even with an extremely well-written jj guide in its context (and literally blocking the use of git), it never failed to screw things up more than if I was just using git (I call this an "LLMpedance mismatch" problem)

      If LLM coding assistance continues to increase, it's going to be a rather large speed bump to cross

      One of the biggest problems is actually unsolvable if you want to keep colocated Git and git tooling around, because it has to do with how jj fundamentally works: detached HEADs, detached HEADs everywhere

      You yourself may not use AI, this is for those who do and are interested in switching to jj

      • BeetleB 45 minutes ago
        I don't let LLMs make commits for me - git or jj.

        OK, OK - I lie. For personal projects I do - some handle jj decently well. But at work I don't let it make any commits ... and it never tries to.

        What tools are you using that won't work with detached heads?

  • wren6991 15 minutes ago
    The worst part of this workflow is when you accidentally run `git commit -am` at the end and destroy all of your careful staging.
  • ninkendo 46 minutes ago
    My biggest problem with `add -p` is correcting any patches I added or rejected by accident. Often times I skip through dozens of things I don’t want to add, then realized that last hunk was something I did need. But I can’t re-visit it, I have to start over and try extra hard to not skip past it again.

    I wish the j and k shortcuts could revisit hunks I’ve already added/rejected, not just ones I haven’t reviewed yet. On a large set of unstaged changes that you mostly don’t want, it really sucks to “lose your place” in the list of hunks.

    • topsecret 11 minutes ago
      From the article, try J and K instead of j and k; that moves to next/previous hunk, not next/previous unreviewed hunk.
    • ghrl 21 minutes ago
      From skimming through the article, isn't that what the uppercase variants do?
  • chriswarbo 1 hour ago
    Magit allows selective staging/unstaging, either of hunks, or by selecting lines (AKA Emacs's "region"). I avoid staging from the git commandline, unless I'm just doing whole files.

    PS: Majutsu provides this too (a magit-like tool for jj)

    • rbjorklin 26 minutes ago
      Neogit, Magit inspired, does the same for Neovim. Would recommend!
      • skydhash 19 minutes ago
        I think you can do the same with tig and lazyvim. Sometimes you just need interactivity.
  • goosejuice 53 minutes ago
    I always use git add -i which is just one level up. The tui is pretty intuitive for day to day tasks, including staging partial chunks or lines of code.
  • natbennett 1 hour ago
    In the case of a newly committed file you can add just the file with

    git add . -N

    And then review the text itself as part of the git add -p workflow

  • zikohh 1 hour ago
    I find splitting hunks a pain. I wish I could just split by line, would be a great feature.
    • LVB 1 hour ago
      Use 'e' in -p mode and you can edit the hunks as you wish, choose lines, etc.
      • embedding-shape 1 hour ago
        The whole "Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?" line is pretty intimidating, but I urge anyone who still wants to understand git and be able to (themselves) use it effectively, to do "?" when you see it, read through what each action does and forcefully try them out to see what they do, in some low stakes project. Ends up being a super quick way of staging a whole bunch of work and avoiding staging other, but it's pretty weird at first glance.
      • feelamee 41 minutes ago
        it's not as easy as you said. it can be tricky and complicated to use edit mode. I usually use it, but still often don't understand - will this edit succeed or why it is failed.
    • elevation 34 minutes ago
      > splitting hunks a pain

      Sublime Merge for the win; a fantastic visual interface with context and reversible inputs. Don't leave home without it!

    • KwanEsq 52 minutes ago
      Mercurial's `hg commit -i` with the curses interface is so much better for this it's not even funny. Fortunately I'd assume Jujutsu's UX is similar, based on arccy's comment.
    • petepete 1 hour ago
      I've used tig for longer than I can remember for my selective staging needs.
    • arccy 1 hour ago
      use jj, the default is to select by line
  • Topgamer7 4 days ago
    I find grepdiff and this function are pretty useful if you want to pull certain hunks out of a large change set:

        #!/bin/bash
        
        # Put this into your .bashrc, or whatever.
        function git-add-regex {
          git diff -U0 | grepdiff -E "$1" --output-matching=hunk | git apply --cached --unidiff-zero
        }
    
    https://gist.github.com/smuuf/76bde33d65b3dbbc2411e8519f3e6c...
  • prideout 1 hour ago
    Super useful, and easy to do in the VS Code merge pane.
  • deepsun 1 hour ago
    IntelliJ has that since 2018, with visual change-by-change checkboxes that should go into each commit, very handy.
  • cerved 1 hour ago
    Vin fugitives difftool is even better

    Also, you can use -p for stash push

    • feelamee 45 minutes ago
      and also for git restore
      • juliend2 24 minutes ago
        and also for `git reset`, when you added one thing by mistake.