483

Is there a way I can stash just my staged changes? The scenario I'm having issues with is when I've worked on several bugs at a given time, and have several unstaged changes. I'd like to be able to stage these files individually, create my .patch files, and stash them away until the code is approved. This way, when it's approved I can stash my entire (current) session, pop that bug and push the code.

Am I going about this the wrong way? Am I misunderstanding how git can work in other ways to simplify my process?

MrDuk
  • 12,340
  • 13
  • 55
  • 113
  • 1
    Yes, you probably are doing things wrong to get into this situation. Still a useful question. You really ought to stash or branch before starting on the next fix. The, tangential, answer https://stackoverflow.com/a/50692885 is probably a better way to handle this in git. Playing around with the stash often does weird stuff to my work-area if I have pulled commits from upstream. – Samuel Åslund Oct 11 '19 at 08:32

15 Answers15

585

Yes, It's possible with DOUBLE STASH

  1. Stage all your files that you need to stash.
  2. 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).
  3. Run git stash push -m "good stash"
  4. Now your "good stash" has ONLY staged files.

Now if you need unstaged files before stash, simply apply first stash (the one created with --keep-index) and now you can remove files you stashed to "good stash".

Enjoy

Iain Samuel McLean Elder
  • 16,665
  • 10
  • 59
  • 76
Bartłomiej Semańczyk
  • 52,820
  • 43
  • 206
  • 318
  • It stashes changes in submodules even though they are not staged. Is there a way around this? – rluks Aug 15 '16 at 13:45
  • 1
    this somehow left all new files (even staged) out. – Aurimas Mar 05 '17 at 16:45
  • 14
    @Aurimas, to stash new files, you need to use the `-u` switch. – Gyromite Sep 22 '17 at 14:55
  • 4
    when you reapply the first stash and get all changed back while you might be only interested in your unstages changes use `git stash apply --index` option. This will try to keep your un(staged) state. Its easier to remove the unwanted changes from the working tree now. – otomo Sep 27 '18 at 12:58
  • While I did not need to do exactly what this answer said, knowing about the --keep-index flag was very helpful. – Aaron Krauss Nov 07 '18 at 17:00
  • i thought this answer was very confusing, will go with `git stash push --patch` instead – Doug Jul 01 '19 at 09:50
  • @Bartłomiej Semańczyk, your answer was very helpful to me, just had a case where I had to un-do an accidental file deletion caused by some buggy code that I've wrote, messed up more than my git working tree, used your answer to fix my problem, kudos. Posted it further down below if somebody runs into the same problem as I just did. – wmax Aug 09 '19 at 10:22
  • 1
    Version 2.17.1 of `git stash -m "good stash"` gives `error: pathspec '[...]/good stash' did not match any file(s) known to git. Did you forget to 'git add'?`. I'll update the answer with the new syntax (replace the `-m` with `save`). – Iain Samuel McLean Elder Nov 21 '19 at 10:55
  • Updated again with `push -m`. I just learned that `save` is deprecated now. – Iain Samuel McLean Elder Nov 21 '19 at 11:12
  • I run `git stash drop stash@{n}` after this. – Marc.2377 Jan 24 '20 at 11:05
  • 1
    You can include untracked files in **step 2** running `git stash --keep-index --include-untracked`. – Wesley Gonçalves Jul 06 '20 at 20:17
  • This worked well however it didn't un-stash the unstaged items. I ran `git stash pop --index 1` to restore unstaged changes and delete the unstaged stash. Only "good stash" is in the stash list afterwards. – Luke Aug 25 '20 at 00:55
152

With latest git you may use --patch option

git stash push --patch   # since 2.14.6

git stash save --patch   # for older git versions

And git will ask you for each change in your files to add or not into stash.
You just answer y or n

UPD
Alias for DOUBLE STASH:

git config --global alias.stash-staged '!bash -c "git stash --keep-index; git stash push -m "staged" --keep-index; git stash pop stash@{1}"'

Now you can stage your files and then run git stash-staged.
As result your staged files will be saved into stash.

If you do not want to keep staged files and want move them into stash. Then you can add another alias and run git move-staged:

git config --global alias.move-staged '!bash -c "git stash-staged;git commit -m "temp"; git stash; git reset --hard HEAD^; git stash pop"'
aexl
  • 3,472
  • 2
  • 36
  • 51
Eugen Konkov
  • 15,716
  • 7
  • 69
  • 107
  • 21
    Technically does not answer the question - but a really nice technique which achieves selective stashing. – alexreardon Jul 12 '17 at 07:18
  • 7
    Agree, this is okay, but the idea here with the question is I've ALREADY done all of this work of staging the changes I want to do something with (ostensibly originally to commit, but now want to stash), not looking to just do it all over again. – Steven Lu Jun 04 '18 at 20:02
  • 4
    does not work for newly created files (works on the modified files only) – Derek Liang Sep 20 '18 at 16:22
  • 1
    @DerekLiang: Newly created files are not tracked at all. You probably should check `-u|--include-untracked` option of `git-stash` – Eugen Konkov Sep 20 '18 at 16:40
  • 2
    From the [docs](https://git-scm.com/docs/git-stash): "**save**: This option is deprecated in favour of _git stash push_. It differs from 'stash push' in that it cannot take pathspecs, and any non-option arguments form the message." – Borjovsky Apr 10 '19 at 16:09
  • I'm using git version `2.7.1.windows.2` and it doesn't have `git stash push` but it has `git stash save --patch` – user829755 Jul 12 '19 at 09:14
  • @DerekLiang: Newly created file is one patch. You can not split it. But you can press `e` command and then remove `+` lines which you do not want to stash – Eugen Konkov Feb 21 '20 at 23:27
  • Beware: creating and running the 2ns alias "git move-staged" without the 1st one messed up my repo. – Shankar Thyagarajan Oct 07 '20 at 02:06
  • WARNING: The `git move-staged` command dropped my latest commit when I had a file partially staged. Had to recover from the origin. – Shankar Thyagarajan Oct 07 '20 at 02:12
96

TL;DR Just add -- $(git diff --staged --name-only) for your git <pathspec> parameter

Here is a simple one-liner:

git stash -- $(git diff --staged --name-only)

And to add a message simply:

git stash push -m "My work in progress" -- $(git diff --staged --name-only)

Tested on v2.17.1 and v2.21.0.windows.1

Limitations:

  • Please be aware that this will stash every single thing, if you have no files staged.
  • Also if you have a file that is only partially staged ( i.e. only some changed lines, are staged while some other changed lines are not), then the whole file will get stashed (including unstaged lines).
Somo S.
  • 2,604
  • 3
  • 19
  • 31
55

I made a script that stashes only what is currently staged and leaves everything else. This is awesome when I start making too many unrelated changes. Simply stage what isn't related to the desired commit and stash just that.

(Thanks to Bartłomiej for the starting point)

#!/bin/bash

#Stash everything temporarily.  Keep staged files, discard everything else after stashing.
git stash --keep-index

#Stash everything that remains (only the staged files should remain)  This is the stash we want to keep, so give it a name.
git stash save "$1"

#Apply the original stash to get us back to where we started.
git stash apply stash@{1}

#Create a temporary patch to reverse the originally staged changes and apply it
git stash show -p | git apply -R

#Delete the temporary stash
git stash drop stash@{1}
Joe
  • 567
  • 4
  • 3
  • 7
    I'd add that you can turn the script into a git command by following http://thediscoblog.com/blog/2014/03/29/custom-git-commands-in-3-steps/ – Petr Bela Nov 22 '16 at 15:57
  • 3
    This is great! I've tweaked it to prompt the user for a stash description if they don't enter one on the command line: https://gist.github.com/brookinc/e2589a8c5ca33f804e4868f6bfc18282 – brookinc Sep 08 '17 at 22:30
  • Thanks, I upvoted and turned it into an alias here: https://stackoverflow.com/a/60875067/430128. – Raman Mar 26 '20 at 19:58
  • Cool! This did the job. Other solutions were not what I was looking for. Thank you – Artemious Oct 19 '20 at 14:29
28

To accomplish the same thing...

  1. Stage just the files you want to work on.
  2. git commit -m 'temp'
  3. git add .
  4. git stash
  5. git reset HEAD~1

Boom. The files you don't want are stashed. The files you want are all ready for you.

Michael
  • 782
  • 12
  • 13
  • 5
    This is easily the best answer and the easiest to remember – Kevin Jan 21 '20 at 15:59
  • Upvoted because useful, but this doesn't answer the question -- what ends up in the stash is the unstaged changes at step #1, whereas the question is asking about stashing just the staged changes. You're answering the opposite of this question: https://stackoverflow.com/q/7650797/430128. I built an alias that essentially does this, with some enhancements here: https://stackoverflow.com/a/60875082/430128. – Raman Jan 23 '21 at 06:03
10

In this scenario, I prefer to create new branches for each issue. I use a prefix temp/ so I know that I can delete these branches later.

git checkout -b temp/bug1

Stage the files that fix bug1 and commit them.

git checkout -b temp/bug2

You can then cherry pick the commits from the respective branches as require and submit a pull request.

Shamps
  • 428
  • 3
  • 10
  • 3
    While fancy stashing sounds is nice to know about, in practice this seems like an approach I'm less likely to bork. – ryanjdillon Oct 19 '18 at 09:49
  • 1
    Use "git cherry-pick tmpCommit" to get the temporary commit back w.o. a merge-commit or "git merge tmpCommit" + " git reset HEAD^ " to get the changes without the commit. – Samuel Åslund Oct 11 '19 at 08:12
  • 1
    As this answer shows sometimes it is better to ask directly what you want to achieve instead of how to achieve it with given technique. Temporary branches and cherry-pick are handy in complicated situations. – Guney Ozsan Nov 09 '19 at 20:27
  • if you staged a file partially, you will need to stash your changes before moving back to the original branch and popping them again – jan-glx May 15 '20 at 18:30
10

Stashing just the index (staged changes) in Git is more difficult than it should be. I've found @Joe's answer to work well, and turned a minor variation of it into this alias:

stash-index = "!f() { \
  git stash push --quiet --keep-index -m \"temp for stash-index\" && \
  git stash push \"$@\" && \
  git stash pop --quiet stash@{1} && \
  git stash show -p | git apply -R; }; f"

It pushes both the staged and unstaged changes into a temporary stash, leaving the staged changes alone. It then pushes the staged changes into the stash, which is the stash we want to keep. Arguments passed to the alias, such as --message "whatever" will be added to this stash command. Finally, it pops the temporary stash to restore the original state and remove the temporary stash, and then finally "removes" the stashed changes from the working directory via a reverse patch application.

For the opposite problem of stashing just the unstaged changes (alias stash-working) see this answer.

Raman
  • 13,024
  • 3
  • 72
  • 95
  • How would you do the opposite of this? I need to stash just the unstaged changes – scaly Jan 20 '21 at 05:15
  • @scaly See the link in the last sentence. – Raman Jan 20 '21 at 06:49
  • Great answer! I've updated it a bit not to do wrong things when there's nothing staged by adding `! git diff --cached --exit-code --quiet && \ ` as first line, so we abort (non-zero exit first in the chain of `&&`s) in that case. Also note that this doesn't work when setting `diff.noprefix = true` (git version 2.29.2), but it was no problem for me since I have also aliases for diff, so I've just added `--no-prefix` to those. – nandilugio Apr 28 '21 at 17:02
8

Why don't you commit the change for a certain bug and create a patch from that commit and its predecessor?

# hackhackhack, fix two unrelated bugs
git add -p                   # add hunks of first bug
git commit -m 'fix bug #123' # create commit #1
git add -p                   # add hunks of second bug
git commit -m 'fix bug #321' # create commit #2

Then, to create the appropriate patches, use git format-patch:

git format-patch HEAD^^

This will create two files: 0001-fix-bug-123.patch and 0002-fix-bug-321.patch

Or you can create separate branches for each bug, so you can merge or rebase bug fixes individually, or even delete them, if they don't work out.

knittl
  • 197,664
  • 43
  • 269
  • 318
2

git stash --keep-index is a good solution... except it did not work correctly on paths that have been removed, which has been fixed in Git 2.23 (Q3 2019)

See commit b932f6a (16 Jul 2019) by Thomas Gummerer (tgummerer).
(Merged by Junio C Hamano -- gitster -- in commit f8aee85, 25 Jul 2019)

stash: fix handling removed files with --keep-index

git stash push --keep-index is supposed to keep all changes that have been added to the index, both in the index and on disk.

Currently this doesn't behave correctly when a file is removed from the index.
Instead of keeping it deleted on disk, **--keep-index currently restores the file.**

Fix that behaviour by using 'git checkout' in no-overlay mode which can faithfully restore the index and working tree.
This also simplifies the code.

Note that this will overwrite untracked files if the untracked file has the same name as a file that has been deleted in the index.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
1

Is it absolutely necessary to work on several bugs at once? And by "at once," I mean "having files edited for multiple bugs at the same time." Because unless you absolutely need that, I'd only work on one bug at a time in your environment. That way you can use local branches & rebase, which I find far easier than managing a complex stash/stage.

Let's say master is at commit B. Now work on bug #1.

git checkout -b bug1

Now you're on branch bug1. Make some changes, commit, wait for code review. This is local, so you're not affecting anyone else, and it should be easy enough to make a patch from git diffs.

A-B < master
   \
    C < bug1

Now you're working on bug2. Go back to master with git checkout master. Make a new branch, git checkout -b bug2. Make changes, commit, wait for code review.

    D < bug2
   /
A-B < master
   \
    C < bug1

Let's pretend that someone else commits E & F on master while you're waiting on review.

    D < bug2
   /
A-B-E-F < master
   \
    C < bug1

When your code has been approved, you can rebase it on to master with the following steps:

git checkout bug1
git rebase master
git checkout master
git merge bug1

This will result in the following:

    D < bug2
   /
A-B-E-F-C' < master, bug1

Then you can push, delete your local bug1 branch, and off you go. One bug at a time in your workspace, but with using local branches your repository can handle multiple bugs. And this avoids a complicated stage/stash dance.

Answer to ctote's question in the comments:

Well, you can go back to stashing for each bug, and only work with one bug at a time. Atleast that saves you the staging issue. But having tried this, I personally find it troublesome. Stashes are a bit messy in a git log graph. And more importantly, if you screw something up you can't revert. If you have a dirty working directory and you pop a stash, you can't "undo" that pop. It's much harder to screw up already existing commits.

So git rebase -i.

When you rebase one branch onto another, you can do it interactively (the -i flag). When you do this, you have the option to pick what you want to do with each commit. Pro Git is an awesome book which is also online in HTML format, and has a nice section on rebasing & squashing:

http://git-scm.com/book/ch6-4.html

I'll steal their example verbatim for convenience. Pretend you have the following commit history, and you want to rebase & squash bug1 onto master:

    F < bug2
   /
A-B-G-H < master
   \
    C-D-E < bug1

Here's what you will see when you type git rebase -i master bug1

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

To squash all commits of a branch down into a single commit, keep the first commit as "pick" and replace all subsequent "pick" entries with "squash" or simply "s". You will get the opportunity to change the commit message, too.

pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit

So yeah, squashing is a bit of a pain, but I would still recommend it over heavy use of stashes.

Mike Monkiewicz
  • 3,503
  • 1
  • 20
  • 18
  • 1
    Thanks for the detailed post! This solves a lot of my issues for sure - the only problem I see is our current team has requested we keep all deliveries to a single commit. :( – MrDuk Feb 07 '13 at 21:14
  • 1
    If they don't need or want your working history in the production repo that's fine: make your tracking master history-less by applying diffs rather than merging branches. You can work out how to keep a decorated-master branch that has the actual merged history and do your real work from that, that way it'll be easy to automate generating the correct diffs. – jthill Feb 08 '13 at 01:41
  • 2
    Note that `git checkout master; git checkout -b bug2` can be shortened to `git checkout -b bug2 master`. The same applies to `git checkout bug1; git rebase master; git checkout master; git merge bug1`, which is identical to `git rebase master bug1; git push . bug1:master` (granted, the `push` trick is not obvious) – knittl Feb 08 '13 at 14:11
  • Thanks for the tipps, knittl – Mike Monkiewicz Feb 08 '13 at 14:30
  • ctote: What do you mean by a single commit? bug1 has to be delivered in a single commit? Or they want bug1, bug2, and bug3 all in a single commit? Either way, that's probably just a question of rebasing (and possibly squashing with rebase -i). If you give a detailed example of your problem, I can again provide a detailed answer. – Mike Monkiewicz Feb 08 '13 at 14:32
  • Sorry, I should have been more clear. Yeah, so they want to keep our code history "clean" by only having a single commit per bug. This way, once an architect starts reviewing my code they can view a single consolidated commit. So, I assumed, if I wanted to branch to bug1, then start working on bug2, I'd have to commit b1 before transitioning to b2. I keep hearing horror stories about "trust me, you don't want to squash commits - it's so nasty" I haven't tried it; what's the big deal? – MrDuk Feb 08 '13 at 19:05
  • 1
    I gave a walkthrough for stashing above in the main answer so I could use fancy formatting – Mike Monkiewicz Feb 08 '13 at 19:23
  • Thanks for all of the detail! The current process that most people have adopted (due to the limitation on allowed commits) has been to clone the same stream twice, once for development and the other for delivering / build testing. Essentially, they will #hackhack on "dev", create patch files and apply them to "baseline" to build test, back out all of their patch files and apply each patch individually to deliver. [continued...] – MrDuk Feb 08 '13 at 19:57
  • [...] Can you see an advantage of one over the other? The primary advantage that is argued to me is, it's _easier_ to do build tests on several bugs through applying several patch files to their "baseline" stream, rather than trying to keep all of their bugs logically separate in git. – MrDuk Feb 08 '13 at 19:58
  • Yep, I can see their point. It is easier to apply stashed changes to a master branch for testing. But it's also much easier to screw up your changes pulling them in and out of stash. You're just going to have to find a workflow that works for you. – Mike Monkiewicz Feb 09 '13 at 03:09
  • If you go with local branches & commits for bugs, you may want to check out: http://stackoverflow.com/questions/7516632/merge-git-branch-without-moving-branch-pointer. It would allow you to apply a branch to master without losing your branch pointer. If you decide to go with stashes, might I recommend working on only one bug at a time, stashing it, and then you can use `git stash apply` when you want to test multiple at once (but preserving their separate patches in the stash). – Mike Monkiewicz Feb 09 '13 at 03:11
  • 7
    I've downvoted because this doesn't answer the original question. I'm in a branch working on something, and I just made a change that I think should be committed to the integration branch separately. All I want to do is stage that change and stash it so I can switch to another branch and commit separately, instead of my current "work in progress" branch. (Warning, git ranting ahead.) It is absurd that this is so difficult to do; I have to imagine that this is a *common* occurrence. (Working in one branch and spotting a quick change that needs to be made and forgetting to switch first.) – jpmc26 Jan 17 '15 at 00:31
  • May have helped the OP but did not answer the question for future reference. I really wish people who answer would not assume they know all use-cases and assert their opinions. If you are going to give opinions only, at least answer the OP's original question first. – MikeSchinkel Jan 20 '16 at 09:24
  • 1
    There's nothing incorrect here, and it's a valuable perspective, but it also pretty objectively does not answer the question at all, so downvoted. – danShumway Mar 15 '16 at 12:47
  • in some cases (on very tiny projects, or projects not yet shared with others) it's more handy to work on a single branch and add clean commits for steps that you've done imho. But your answer most likely the best way to go in other cases. In a current case of mine, I just had to fix a tiny problem, wouldn't dare to make a branch for just one two-liner commit, as it can stand clean and tidy on it's own. – wmax Aug 09 '19 at 10:31
0

Out of your comments to Mike Monkiewicz answer I suggest to use a simpler model: Use regular development branches, but use the squash option of the merge to get a single commit in your master branch:

git checkout -b bug1    # create the development branch
* hack hack hack *      # do some work
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
git checkout master     # go back to the master branch
git merge --squash bug1 # merge the work back
git commit              # commit the merge (don't forget
                        #    to change the default commit message)
git branch -D bug1      # remove the development branch

The advantage of this procedure is that you can use the normal git work flow.

Rudi
  • 17,566
  • 3
  • 50
  • 74
0

To prune an accidental change, especially the deletion of multiple files, do the following:

git add <stuff to keep> && git stash --keep-index && git stash drop

in other words, stash the crap and throw it away with the stash altogether.

Tested in git version 2.17.1

wmax
  • 785
  • 8
  • 19
  • 2
    a downvote without a comment is neither helpful to me nor the next reader... zaenks grumpy anon. Though I can imagine one problem with this one-liner: One should be very careful not to forget to add all wanted changes to the index, otherwise those important changes will also be deleted. But then again, un-careful use of any cli tool can be very dangerous to one's precious time and job in the worst case. – wmax Aug 23 '19 at 09:25
0

I haven't seen this solution that requires no use of git stash :

You don't even need to use git stash at all. You can work this out using a dedicated branch as covered here (branches are cheap).

Indeed, you can isolate separately un- and staged changes with a few consecutive commands that you could bundle together into a git alias :

Create and switch to an new branch where you'll commit separately staged and unstaged changes : see here

At any moment you can git cherry-pick -e one commit from the created branch to apply it where you want (-e to change its commit message).

When you don't need it anymore, you can delete this "stash branch". You may have to use the -D option to force deletion (instead of the -d normal option) because said branch is not merged and git might consider that you risk losing data if you delete it. That is true if you haven't cherry-picked commits that were on it before deletion :

git branch -D separated-stashes

You can also add an alias to your ~/.gitconfig in order to automate this behavior :

git config --global alias.bratisla '!git switch -c separated-stashes; git commit -m "staged changes"; git add -u; git commit -m "unstaged changes"; git switch -' # why this name ? : youtu.be/LpE1bJp8-4w

before "stashing"
after "stashing"



Of course, you can also achieve the same result using two consecutive stashes

As stated in other answers, you have some ways to stash only unstaged or only staged changes using git stash (-k|--keep-index) in combination with other commands.

I personally find the -k option very confusing, as it stashes everything but keeps staged changes in staged state (that explains why "--keep-index"). Whereas stashing something usually moves it to a stash entry. With -k the unstaged changes are stashed normally, but staged ones are just copied to the same stash entry.


Step 0 : you have two things in your git status : a file containing staged changes, and another one containing unstaged changes.

Step 1 : stash unstaged + staged changes but keep the staged ones in the index :

git stash -k -m "all changes"

The -m "..." part is optional, git stash -k is actually an alias for git stash push -k (that does not push anything remotely btw don't worry) which accepts a -m option to label you stash entries for clarity (like a commit message or a tag but for a stash entry). It is the newer version of the deprecated git stash save.


Step 1bis (optional) :

git stash

Stash staged changes (that are still in the index). This step is not necessary for the following, but shows that you can put only staged changes in a stash entry if you want to. If you use this line you have to git stash (pop|apply) && git add -u before continuing on step 2.


Step 2 :

git commit -m "staged changes"

Makes a commit containing only staged changes from step 0, it contains the same thing as the stash entry from step 1bis.


Step 3 :

git stash (pop|apply)

Restores the stash from step 1. Note that this stash entry contained everything, but since you already committed staged changes, this stash will only add unstaged changes from step 0.

nb: "restore" here does NOT mean "git restore", which is a different command.


Step 4 :

git add -u

Adds the popped stash's content to the index


Step 5 :

git commit -m "unstaged changes"

"Unstaged" here, as "staged" in steps 2 and 3's comments, refers to step 0. You are actually staging and committing the "staged changes" from step 0.


Done ! You now have two separated commits containing (un)staged changes from step 0. You may want to amend/rebase them for either additional changes or to rename/drop/squash them. Depending on what you did with your stash's stack (pop or apply), you might also want to git stash (drop|clear) it. You can see you stash entries with git stash (list|show)

dilavasso
  • 1
  • 2
0

Another approach to this is to create a temporary commit with files you don't want to be stashed, then stash remaining files and gently remove last commit, keeping the files intact:

git add *files that you don't want to be stashed*
git commit -m "temp"
git stash --include-untracked
git reset --soft HEAD~1

That way you only touch files that you want to be touched.

Note, "--include-untracked" is used here to also stash new files (which is probably what you really want).

Genjutsu
  • 29
  • 3
  • 9
-1

TL;DR; git stash-staged

After creating an alias:

git config --global alias.stash-staged '!bash -c "git stash -- \$(git diff --staged --name-only)"'

Here git diff returns list of --staged files --name-only
And then we pass this list as pathspec to git stash commad.

From man git stash:

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

<pathspec>...
   The new stash entry 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.

Eugen Konkov
  • 15,716
  • 7
  • 69
  • 107
  • Does this work properly if for some specific file I have both staged, and unstaged changes? At first glance, `--name-only`, it doesn't look like it handles that case. [that answer](https://stackoverflow.com/a/60875067/717732) seems much better. – quetzalcoatl Jun 23 '20 at 14:55
  • Also, that's basically a copy of [this answer](https://stackoverflow.com/a/59874960/717732) – quetzalcoatl Jun 23 '20 at 14:56
  • @quetzalcoatl: Yes, it similar to that answer. But this one provide an alias which saves your typing for next commands – Eugen Konkov Jun 23 '20 at 16:19
  • @quetzalcoatl: You are right. `--name-only` will not handle staged/unstaged changes at once. But why you mark first and then stash? It would be better to stash required changes right now. I recommend you to try `git stash push --patch` described [here](https://stackoverflow.com/a/44824475/4632019) – Eugen Konkov Jun 23 '20 at 16:24