How do I save work in progress without using git-stash?

Let's try it this way:

  • Q: How can you save something in Git?

  • A: Commit it.

  • Q: What about git stash, it seems to save things, how does it manage that?

  • A: It commits.

  • Q: But it doesn't put any commits on my branch.1

  • A: They're on the special "stash" thing, which is not a branch. But they're still commits.

1This is, technically, not a question. :-)

If you want to save something in Git, commit it

This is the Git bottom line, as it were: a commit saves things. Otherwise all you have is stuff in your work-tree, and stuff in your index (staging-area). The staging-area stuff becomes permanent when you run git commit. The work-tree stuff is never permanent: you have to copy it to the staging area and then commit it.

This is what git stash does. It actually makes two commits, one for the current index, and one for the work-tree.2 It just makes them both on something other than a branch, using the name stash to find them instead.

There's nothing stopping you from making your own commits, though. It's just a bit of a pain to make two or more commits and then have to undo them, which is why git stash exists.

2When you use --include-untracked as you did, it actually makes three commits: one for the index, a second for the work-tree, and a third one for the untracked files. That third commit is extra-tricky, both to make and to restore. The stash script uses a temporary index rather than trying to do the work in the main index.

You can always use another clone

Each Git repository is, in general, independent of all other Git repositories, but can peer with any related Git repository. So you can clone one repository to another, and thereby get another work-tree where you can do work. This work-tree also comes with its own (separate) index / staging-area.

If you make the clone locally, on your local file system, Git is often able to avoid a lot of repository-file copying. So while this might seem expensive, it's usually not that bad. The main problem is that you now have two repositories to remember to commit-to, and you must fetch and/or push between them and/or whatever upstream you originally cloned from.

For quick side work, git worktree add (2.5 and newer only)

Before Git 2.5 there was a "contributed" script to make alternate work-trees. As of 2.5 it became officially supported, though there were some important bug fixes since then (and even now it has some rough edges). You can now run git worktree add to create a new worktree that will use a different branch, but share the underlying repository.

No two work-trees that share one underlying repository may use the same branch. (This is because of the way Git stores its idea of the "current branch" and "current commit", and the way Git advances the current branch when you make a new commit.) If your goal, however, is to make a fix in some other branch than the one you are working on now, this is just what you need anyway.

Thanks to every answer I received. I achieved two possible solutions:

git worktree add -b BUGFIX ../bugfix_temp master
pushd ../bugfix_temp
touch BUGFIX
git add BUGFIX
git commit -a -m "emergency BUGFIX"
rm -rf ../bugfix_temp
git worktree prune


touch BUGFIX
git add BUGFIX
git commit --only BUGFIX -m "emergency BUGFIX"