Be aware that when you say "at the current stage", that implies something you clearly don't mean. (staged
means 'in the index' in git-speak; that would definitely not include untracked files - nor unstaged changes to tracked files.)
As for what command to use, you should not use git stash save
; it is deprecated, so you should use git stash push
instead. (push
is the default, so you don't have to name any subcommand at all when creating a stash.)
I'm not sure what you mean about how you want ignored files to be handled. If you want ignored files included in the stash
git stash --all
if you don't want the ignored files in the stash (and so want them to remain in the worktree)
git stash -u
And when you apply
the stash, you need to let git know that you want the index restored
git stash apply --index
Note that this only works when the stash apply process doesn't generate conflicts; for this use, it shouldn't conflict, but if you apply to a different commit than from where the stash was created, it can.
To create a branch instead of a stash:
There's a shortcut you can use here, because a stash is really a collection of commits with a specially-handled ref. So you can create the stash as usual, then
git checkout stash
git checkout -b my_branch
git stash drop
The branch will look a little weird, because stash uses merges in a somewhat unusual way to assemble the untracked, unstaged, and staged change sets.
If you don't want to use the stash command at all, then it's harder. You can only commit changes that are staged, so you'd have to do something like
git checkout -b my_branch
git commit -m "staged changes"
git commit -a -m "unstaged changes"
# if you want a commit with only the non-ignored
# untracked files
git add :/:
git commit -m "untracked files'
# if you want a single commit with all untracked
# files (ignored or not), then skip the previous
# command and run this; if you want a separate
# commit for ignored files, run the previous
# command and *then* run this:
git add -f :/:
git commit -m "ignored files"
(Note that you could even combine the unstaged, untracked, and ignored files all into one commit (though stash does not); but you really have to commit the staged changes separately, in order to restore the index accurately later.)
Then you need to restore your working state and continue work. The exact commands to use depend on which of the above commands you ran. First you want to detach from your stash-like barnch
git checkout --detach
Then restore the index with the staged changes. If you created all 4 commits, this would be
git reset --mixed HEAD~3
If you only created one commit for untracked files
git reset --mixed HEAD~2
(Or, if you only created one commit for unstaged changes and untracked/ignored files, it would be
git reset --mixed HEAD~1
or equivalent.)
Then move HEAD
the rest of the way off the branch
git reset --soft HEAD~1
Finally check out your working branch again; e.g. if you started on master
git checkout master
With all of that done, you've stored all the same information as a stash; but you still don't have the automation of the stash command to help you, so in the future if you want to restore that state again, you would have to clean the work tree, check out the stash-like branch, and repeat the whole detach/reset/checkout procedure again.
And if you want to apply those changes to a different base commit (stock functionality for stash
) you'd have to first rebase the stash-like branch to the new commit, and then restore the changes there.