13 comments

[ 0.19 ms ] story [ 8.3 ms ] thread
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...
IntelliJ has that since 2018, with visual change-by-change checkboxes that should go into each commit, very handy.
I find splitting hunks a pain. I wish I could just split by line, would be a great feature.
Super useful, and easy to do in the VS Code merge pane.
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

Vin fugitives difftool is even better

Also, you can use -p for stash push

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)

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.
> 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).

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.

The worst part of this workflow is when you accidentally run `git commit -am` at the end and destroy all of your careful staging.
While I see the utility of partial file commits, I think that it promotes committing untested code. Fossil scm doesn’t have an equivalent feature because of this very issue.
Ive got a tendency to modify many things as I go and break them into commits later. Generally I do git add -p until things are too interwoven. In that case, I've ended up with the following strategy:

git commit -m "WIP" & git revert HEAD & git revert HEAD & git reset HEAD^

Now I've got a copy of the changes as a commit and I'm my work tree. I widdle it down until its one change only. Then I do:

git commit -m "Bla" & git rebase -i HEAD~3 -X theirs

Them order Bla above WIP. I keep doing this "double revert" trick until the WIP no longer applies. Then done.