Stashing only un-staged changes in Git

老子叫甜甜 提交于 2020-03-17 03:42:04

问题


I'd like to do the following work flow:

  1. Add changes to the stage.
  2. Stash all the other changes that were not staged.
  3. Do some stuff with the things in stage (i.e. build, run tests, etc)
  4. Apply the stash.

Is there a way to do step 2?

Example

 echo "123" > foo
 git add foo # Assumes this is a git directory
 echo "456" >> foo
 git stash
 cat foo # Should yield 123

回答1:


git stash save has an option --keep-index that does exactly what you need.

So, run git stash save --keep-index.




回答2:


This may be done in 3 steps: save staged changes, stash everything else, restore index with staged changes. Which is basically:

git commit -m 'Save index'
git stash push -u -m 'Unstaged changes and untracked files'
git reset --soft HEAD^

This will do exactly what you want.




回答3:


git stash save --keep-index

Also, Re:

Why not commit your changes after staging them? – Shin

A: Because you should always checkin tested code :) That means, you need to run the tests with only the changes you are about to commit

All this apart from the fact that of course, as an experienced programmer, you have the innate urge to test and review just those changes -- only partly kidding




回答4:


With git version 2.7.4 you may do:

git stash save --patch

The git will ask you to add or not your changes into stash.
And you then just answer y or n

You can restore working directory as you always do that:

git stash pop

or, if you want to keep saved changes in stash:

git stash apply



回答5:


Extending previous answers, I sometimes have a complex set of changes staged, but wish to commit a separate change first. For example, I might have spotted a bug or otherwise incorrect code that I'd like to fix ahead of my staged changes. One possible route to take is this:

first stash everything, but leave the staged changes intact

$ git stash save --keep-index [--include-untracked]

now stash the staged changes separately too

$ git stash save

make changes for fix; and test; commit them:

$ git add [--interactive] [--patch]

$ git commit -m"fix..."

now restore the previously staged changes:

$ git stash pop

resolve any conflicts, and note that if there were conflicts, git will have applied but not dropped that top stash entry.

(... Then commit the staged changes, and restore the stash of all the other changes, and continue ...)




回答6:


Another tip, related to the question:

When you effectively stash your unstaged changes using

$ git stash save --keep-index

you might wish to give the stash a message, so that when you to do a git stash list it's more obvious what you have stashed before, especially if you follow that stash operation by further saves. For example

$ git stash save --keep-index "changes not yet staged"

(although actually it does contain all the changes as noted in other answers).

For example, the above might be followed immediately by:

$ git stash save "staged changes for feature X"

Beware, though, that you can't then use

$ git stash apply "stash@{1}" ### ✘ doesn't quite do what you might want

to restore just the unstaged changes.




回答7:


To add the unstagged (not added to commit) files to stash, run the following command:

git stash -k

Then you can commit the staged files. After that you can get back the last stashed files using the command:

git stash pop



回答8:


Git doesn't have a command that stashes only your unstaged changes.

Git does, however, let you specify which files you want to stash.

git stash push --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

If you only want to stash specific changes in those files, add the --patch option.

git stash push --patch --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

The --include-untracked option lets you stash untracked files.

git stash push --include-untracked --message 'Untracked files' -- app/controllers/widgets_controller.rb test/controllers/widgets_controller_test.rb

Run git help stash (or man git-stash) for more info.

Note: If your unstaged changes are rather disoganized, @alesguzik's answer is probably easier.




回答9:


The modern form of that command is git stash push [--] [<pathspec>...], since Git 2.16+ (git stash save is deprecated)

You can combine that with a wildcard form, for example:

git stash push --all --keep-index ':(glob)**/*.testextension' 

But that does not work well with Git for Windows, until Git 2.22 (Q2 2019), see issue 2037, considering git stash has been re-implemented in C (instead of a shell script)

See commit 7db9302 (11 Mar 2019) by Thomas Gummerer (tgummerer).
See commit 1366c78, commit 7b556aa (07 Mar 2019) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit 0ba1ba4, 22 Apr 2019)

built-in stash: handle :(glob) pathspecs again

When passing a list of pathspecs to, say, git add, we need to be careful to use the original form, not the parsed form of the pathspecs.

This makes a difference e.g. when calling

git stash -- ':(glob)**/*.txt'

where the original form includes the :(glob) prefix while the parsed form does not.

However, in the built-in git stash, we passed the parsed (i.e. incorrect) form, and git add would fail with the error message:

fatal: pathspec '**/*.txt' did not match any files

at the stage where git stash drops the changes from the worktree, even if refs/stash has been actually updated successfully.




回答10:


I use an an alias, which accepts a string to use as a message to the stash entry.

mystash = "!f() { git commit -m hold && git stash push -m \"$1\" && git reset HEAD^; }; f"

Which:

  • commits everything in the index,
  • stashes what is changed in the working tree (could of course add -u or -a),
  • resets the last commit back to the working try (may want to use --soft to keep it in the index).


来源:https://stackoverflow.com/questions/7650797/stashing-only-un-staged-changes-in-git

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!