Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git interactive unstage part of a file or by hunks

Tags:

git

There's git add -p to stage changes and git checkout -p to discard changes interactively. How can I unstage changes from index by hunks?

(I thought that git unstage -p or git reset HEAD -p might work.)

like image 940
Dziamid Avatar asked Sep 07 '11 16:09

Dziamid


People also ask

How do I commit only part of a file?

In the Commit window, select the file you want to partially commit, then select the text you want to commit in the right pane, then right-click on the selection and choose 'Stage selected lines' from the context menu.

How do you Unstage a file in git?

To unstage commits on Git, use the “git reset” command with the “–soft” option and specify the commit hash. Alternatively, if you want to unstage your last commit, you can the “HEAD” notation in order to revert it easily. Using the “–soft” argument, changes are kept in your working directory and index.

What are hunks in git?

When you enter Git's patch mode, the chunks of code ('hunks') you're offered to stage/skip can sometimes be bigger than you'd want. Maybe a hunk you're offered contains multiple lines with changes that belong in more than one commit. Luckily, the s option is there to split the hunk down further.

Is it possible to stage only some part of file git?

Staging PatchesIt's also possible for Git to stage certain parts of files and not the rest.


2 Answers

If I am not mistaken, what you want is to unstage hunks interactively? I thought git reset -p does exactly that. Its prompt message is even exactly like Unstage this hunk?

Also from the manual:

This means that git reset -p is the opposite of git add -p, i.e. you can use it to selectively reset hunks. See the “Interactive Mode” section of git-add(1) to learn how to operate the --patch mode.

like image 151
manojlds Avatar answered Nov 07 '22 15:11

manojlds


I found this answer very helpful when learning staging, so I thought I'd modify it for unstaging, as I haven't found a thorough answer on stackoverflow to this "How to git unstage one line or part of a file?" question.

As @manojlds says, you can use git reset --patch <filename> (or -p instead of --patch for short), and git will begin to break down your file into what it thinks are sensible "hunks" (portions of the file).

Git will then prompt you with a variant of this question:

Unstage this hunk [y,n,q,a,d,g,/,j,J,k,K,s,e,?]? 

Here is a description of each option:

  • y unstage this hunk from the next commit
  • n stage this hunk for the next commit
  • q quit; do not unstage this hunk or any of the remaining hunks
  • a unstage this hunk and all later hunks in the file
  • d do not unstage this hunk or any of the later 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 hunk help

NOTES ABOUT e MANUAL EDITING: Be extra careful when using the edit (e) mode above as it is not intuitive. I'll include and then revise the in-line git documentation:

# To remove '+' lines, make them ' ' lines (context). # To remove '-' lines, delete them.                 # Lines starting with # will be removed.  

Revised for clarity:

  • All lines starting with + are lines currently staged to be added which will now be unstaged. To keep + lines from being unstaged (i.e. to leave them as staged changes), replace the initial + with a space character.
  • All lines starting with - are lines currently staged to be deleted which will now be unstaged. To keep - lines from being unstaged (i.e. to leave them as staged changes), delete each line entirely.
  • All lines with #, are comment lines and do not affect the content of the commit.
  • Perhaps also keep in mind @Daniel-Alder's comment, to avoid accidentally unstaging the whole hunk.

Afterwards, you can use:

  • git diff --staged to check that you unstaged/staged the correct changes
  • git add -p to stage mistakenly removed hunks
  • git commit -v to view your commit while you edit the commit message.

Reference for future: Git Tools - Interactive Staging

like image 45
LHM Avatar answered Nov 07 '22 15:11

LHM