Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stash changes to specific files

Tags:

git

git-stash

I have a large git project that I, stupidly, imported to eclipse and ran an autoformat on. Now, every file in the project is showing as modified. Rather than commit my formatted files, I would rather revert all the files that I have only been formatted and not had other changes. For instance:

$ git status # On branch master # Changes not staged for commit: #   (use "git add <file>..." to update what will be committed) #   (use "git checkout -- <file>..." to discard changes in working directory) #   (commit or discard the untracked or modified content in submodules)  #     modified: dir/file1.cpp #     modified: dir/file1.h #     modified: dir/file2.cpp #     modified: dir/file2.h #     modified: dir/file3.cpp #     modified: dir/file3.h #     modified: dir/file4.cpp #     modified: dir/file4.h 

I know that file2.cpp, file2.h, and file3.cpp have been modified with content (i.e., not just formatted). I want to stash the changes to these three files and then checkout an old revision, so that I can reapply the changes to these files after. I would rather avoid something like:

$ cp file2.cpp ~/tmp $ git checkout blahblahblah $ cp ~/tmp/file2.cpp . 

If there's an obvious way to do this that doesnt involve stashing, let me know. whatever gets the job done.

like image 312
ewok Avatar asked Sep 06 '12 17:09

ewok


People also ask

How do I stash changes to a specific file in git?

The syntax of the command to stash specific files in Git is git stash push <file> . Thus, we do as follows to stash the changes done only to the file example. txt . Thus, we have stashed the changes only of the file example.

Does git stash change files?

By default, running git stash will stash: changes that have been added to your index (staged changes) changes made to files that are currently tracked by Git (unstaged changes)

Can I stash committed changes?

A commit creates a new save point on a branch; a stash reverts to a previous save point. A new commit leaves files in the working tree unchanged; a stash resets files in the working tree to the previous commit point. A commit is a public record of file changes; a stash is local.


2 Answers

You can add the files with changes you want to keep, then stash the rest of the files and clear the stash:

git add file2.cpp file2.h file3.cpp git stash --keep-index 

At this point, you've stashed your unwanted changes. If you'd like to permanently get rid of them, run:

git stash drop 

Now you have file2.cpp, file2.h, and file3.cpp staged for commit. If you then want to stash these files (and not commit them):

git reset git stash 

Now you'll be at your previous commit, with only those three files stashed.

Update:

Git 2.13 and later includes a more direct way to stash specific files with git stash push, as VonC explains in his answer.

like image 115
redhotvengeance Avatar answered Sep 17 '22 18:09

redhotvengeance


I know that file2.cpp, file2.h, and file3.cpp have been modified with content (i.e., not just formatted).
I want to stash the changes to these three files and then checkout an old revision, so that I can reapply the changes to these files after.

With Git 2.13 (Q2 2017), git stash will have officially a way to stash changes for specific files with

git stash push [--] [<pathspec>...] 

See commit 9e14090, commit 1ada502, commit df6bba0 (28 Feb 2017), and commit 9ca6326, commit 6f5ccd4, commit f5727e2 (19 Feb 2017) by Thomas Gummerer (tgummerer).
(Merged by Junio C Hamano -- gitster -- in commit 44c3f09, 10 Mar 2017)

As now documented:

For quickly making a snapshot, you can omit "push".
In this mode, non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash.
The two exceptions to this are stash -p which acts as alias for stash push -p and pathspecs, which are allowed after a double hyphen -- for disambiguation.

When pathspec is given to 'git stash push', the new stash records the modified states only for the files that match the pathspec.
The index entries and working tree files are then rolled back to the state in HEAD only for these files, too, leaving files that do not match the pathspec intact.

Note, as pointed out by medmunds in the comments, that git stash would use paths relative to the root folder of the git repo.


And with Git 2.26 (Q2 2020), "git rm" and "git stash" learns the new "--pathspec-from-file" option.

If you have a list of files to stash in filesToStash.txt, then this is enough:

git stash --pathspec-from-file=filesToStash.txt` is enough. 
like image 37
VonC Avatar answered Sep 17 '22 18:09

VonC