Question

I often add some debug code while developing so I need to remove these changes later.

Currently, I check the git diff and remove the changes manually or just type git checkout -- myfilename if I would like to undo the entire file.

I love the interactive patch function (git add -i). Is there a tool or a command in git which can undo changes interactive like git add -i?

In other words: I would like to interactively checkout files and hunks out of the index.

Was it helpful?

Solution

The command you are looking for is

$git checkout -p

The git checkout Manual Page says:

-p

--patch

Interactively select hunks in the difference between the (or the index, if unspecified) and the working tree. The chosen hunks are then applied in reverse to the working tree (and if a was specified, the index).

This means that you can use git checkout -p to selectively discard edits from your current working tree. See the “Interactive Mode” section of git-add(1) to learn how to operate the --patch mode.


If you want to restore staged changes interactively, use git reset --patch or git reset -p.

From the docs:

git reset (--patch | -p) [] [--] [...]

Interactively select hunks in the difference between the index and (defaults to HEAD). The chosen hunks are applied in reverse to the index.

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.

and about git add -p it says

-p

Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the index.

This effectively runs add --interactive, but bypasses the initial command menu and directly jumps to the patch subcommand. See “Interactive mode” for details.

So basically with git reset -p you can select what you reset.

OTHER TIPS

Before Git 2.25 (Q1 2020), "git reset --patch $object" would not work in a new repository (where there is no commit yet).

Without any pathspec, it should allow a tree object to be given, but incorrectly required a committish, which has been corrected.

See commit 0a8e303 (24 Nov 2019) by Nika Layzell (mystor).
(Merged by Junio C Hamano -- gitster -- in commit 6b3cb32, 05 Dec 2019)

reset: parse rev as tree-ish in patch mode

Signed-off-by: Nika Layzell

Since 2f328c3d ("reset $sha1 $pathspec: require $sha1 only to be treeish", 2013-01-14, Git v1.8.2-rc0 -- merge), we allowed "git reset $object -- $path" to reset individual paths that match the pathspec to take the blob from a tree object, not necessarily a commit, while the form to reset the tip of the current branch to some other commit still must be given a commit.

Like resetting with paths, "git reset --patch" does not update HEAD, and need not require a commit.
The path-filtered form, "git reset --patch $object -- $pathspec", has accepted a tree-ish since 2f328c3d.

"git reset --patch" is documented as accepting a <tree-ish> since bf44142f ("reset: update documentation to require only tree-ish with paths", 2013-01-16, Git v1.8.2-rc0 -- merge).
Documentation changes are not required.

Loosen the restriction that requires a commit for the unfiltered "git reset --patch $object".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top