Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: how to use stash -p to stash specific files?

Tags:

git

git-stash

I'm trying to figure out how to stash two specific files among many uncommitted changes.

This very promising answer, Stash only one file out of multiple files that have changed with Git?, doesn't show the usage and I'm having trouble working it out.

The following doesn't work and the man page isn't very helpful (it appears to talk about terminal output, not actually stashing). I want to stash application.conf and plugins.sbt and then commit everything else.

app (master)$ git status
On branch master
Your branch is ahead of 'origin/master' by 29 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   views/mobile/blog.scala.html
        modified:   views/mobile/slideshow.scala.html
        modified:   ../public/css/mobile/styles.css

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

        both modified:   ../conf/application.conf

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)

        modified:   ../project/plugins.sbt

app (master)$ git stash -p ../conf/application.conf ../project/plugins.sbt 

usage: git stash list [<options>]
   or: git stash show [<stash>]
   or: git stash drop [-q|--quiet] [<stash>]
   or: git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
   or: git stash branch <branchname> [<stash>]
   or: git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
                       [-u|--include-untracked] [-a|--all] [<message>]]
   or: git stash clear
like image 473
doub1ejack Avatar asked May 16 '14 20:05

doub1ejack


People also ask

How do I stash specific files 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.

How do I apply a specific file to a stash?

To stash a specific file, use the “git stash push” command and specify the file you want to stash. However, the other tracked files that may be modified in your current working directory are untouched.

How do I stash only staged files?

Stage all your files that you need to stash. Run git stash --keep-index . This command will create a stash with ALL of your changes (staged and unstaged), but will leave the staged changes in your working directory (still in state staged). Now your "good stash" has ONLY staged files.

How do I remove a single file from a git stash?

Here's what I did to solve the issue: git restore --staged path/to/file. git reset HEAD -- path/to/file to remove the file from the staging area.


3 Answers

Use

git stash --patch

git will then show a dialog like the following, for every hunk in your possible commit:

diff --git files over files
index e69de29..ac4f3b3 100644
--- a/file.txt
+++ b/file.txt
@@ -0,0 +1 @@
+you did awesome stuff!
Stash this hunk [y,n,q,a,d,/,e,?]?

A hunk is a coherent diff of lines as git-diff produces it. To select a single file you'll have to decline adding hunks as long as you reach that file, then you might add all hunks from that file.

You're also able to choose a single hunk by answering the question with yes. If the hunk seems to be too big, you even might split it. It is also possible to edit the current hunk.


Using the --patch-option is possible on different git commands (f.e. stash, commit and add).

This is the detailed explanation of the --patch-function, which i grabbed from the developers documentation:

This lets you choose one path out of a 'status' like selection.
After choosing the path, it presents the diff between the index
and the working tree file and asks you if you want to stage
the change of each hunk.  You can select one of the following
options and type return:

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

If you're interested in a more comfortable way to handle this task, you may also take a look on git gui tools like LazyGit. I use this one to split up my daily work into atomic commits.

like image 124
Florian Neumann Avatar answered Oct 20 '22 03:10

Florian Neumann


In the most recent versions of Git (> v2.13) you can stage the specific files you want to stash using

git stash push -- <pathspec>

For example, if you stage the specific files you want to stash you can use this command to specifically stash only those file(s):

git stash push -- example/file/path/and/file.html

You can save yourself some typing by using a globbing pattern to stash the specific files in the path

git stash push -- **/path/**

You'll want to stage only the files you want to stash since any other staged files will be stashed with the specific files, but also remain staged after stashing so if you git stash pop you would get conflicts.

like image 23
mtpultz Avatar answered Oct 20 '22 02:10

mtpultz


Use git stash -p without arguments. You will then be able to interactively select changes that you want to stash:

diff --git a/test b/test
index acbd8ae..662d47a 100644
--- a/test
+++ b/test
@@ -10,6 +10,7 @@ test
(...)
+    test
(...)
Stash this hunk [y,n,q,a,d,/,e,?]?

Unfortunately it's not possible to select files, only hunks.

like image 7
Gergo Erdosi Avatar answered Oct 20 '22 03:10

Gergo Erdosi