23

I usually add changes with git add -p, and many times there are large hunks with several blocks of code, separated by blank lines.

However, git won't split the hunk any further, and I have to resort to manual editing.

How can I increase the granularity of the hunks, such that every block of code will be in a separate hunk?

Edit: This is a different question from Git: show more context when using git add -i or git add -e?, since I'M not looking to increase the context around each hunk, but rather increase the number of hunks.

0

4 Answers 4

24

It cant be done,

These are the options you can do within add -p:

y - stage this hunk n - do not stage this hunk q - quit, do not stage this hunk nor any of the remaining ones a - stage this and all the remaining hunks in the file d - do not stage this hunk nor any of the remaining hunks in the file g - select a hunk to go to / - search for a hunk matching the given regex j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk ? - print help 

Once you use the s it will pick the chunk of code which can be considered as a standalone change. If you want to split it even more you will have to use the e to edit the hunk and then add it back to the stage area.

Summary:

To split hunks you use the s flag.
If you need to split it into even smaller chunks you will need to manually edit it using the e option.

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thx, but I'M well aware of how add -p works, and I'M looking for a workaround without resorting to manual editing.
@dimid: The answer is "can't be done", and I'm afraid you insisting you want to do it won't help.
4

As @codeWizard said in his answer, git just doesn't support what you want, and it hence can't be done in git add.

Now, you could write a script yourself that does the following:

  1. copy your locally changed version of to somewhere outside the tree
  2. git checkout -- <changedfile> to bring your modified file to an unmodified state
  3. write a user interface of your own to select ranges in the file that you want to add now
  4. add the modifications to the in-tree .
  5. git commit
  6. If desirable, go to 3. again

Comments

2

git gui lets you select specific lines to stage.

Open git gui in your git repository, then right click on the desired line > "Stage Line For Commit".

Now, it will not let you edit a file (I wish it could open a temporary file in your favorite editor). To work around this, you can simply mark the commit message with a reminder:

AMENDME: Add x do not forget to rename thing 

When you are done with your coding stretch, you can use git rebase -i <original branch>, mark the "AMENDME" commit with the edit command and amend that commit.

2 Comments

I strongly disagree. My development platform cannot be simpler: a text editor (emacs) and the git command line utility. I sometimes use git gui et al. to review and work out hairier commits; when I spot a typo, it's a bit of a pain to go back to my editor just to correct it, when it could do that for me.
I don't see the point in committing and amending. It is lengthy.
0

However, git won't split the hunk any further, a

And that is an issue as well when you use the config diff.suppressBlankEmpty (A boolean to inhibit the standard behavior of printing a space before each empty output line. Defaults to false. Introduced in Git v1.6.1-rc1, Q3 2008, initially as diff.suppress-blank-empty):

"git add -p"(man) by users with diff.suppressBlankEmpty set to true failed to parse the patch that represents an unmodified empty line with an empty line (not a line with a single space on it), which has been corrected with Git 2.47 (Q4 2024), batch 1.

See commit 60cf761, commit 39bdd84 (20 Jul 2024) by Phillip Wood (phillipwood).
(Merged by Junio C Hamano -- gitster -- in commit d71121c, 31 Jul 2024)

add-patch: handle splitting hunks with diff.suppressBlankEmpty

Reported-by: Ilya Tumaykin
Helped-by: Jeff King
Signed-off-by: Phillip Wood

When "add -p" parses diffs, it looks for context lines starting with a single space.
But when diff.suppressBlankEmpty is in effect, an empty context line will omit the space, giving us a true empty line.
This confuses the parser, which is unable to split based on such a line.

It's tempting to say that we should just make sure that we generate a diff without that option.
However, although we do not parse hunks that the user has manually edited with parse_diff() we do allow the user to split such hunks.
As POSIX calls the decision of whether to print the space here "implementation-defined" we need to handle edited hunks where empty context lines omit the space.

So let's handle both cases: a context line either starts with a space or consists of a totally empty line by normalizing the first character to a space when we parse them.
Normalizing the first character rather than changing the code to check for a space or newline will hopefully future proof against introducing similar bugs if the code is changed.

While this is considered as a bug now fixed, check if a git -c diff.suppressBlankEmpty=true add -p would not increase the granularity in your case, with a Git older than 2.47.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.