41

If I do git checkout my-super-branch git tells me:

error: Your local changes to the following files would be overwritten by checkout: somedir/somefile.py Please, commit your changes or stash them before you can switch branches. Aborting 

Is there a simple way to tell git to do stash+pop automatically?

7
  • 1
    Make an alias or a shell script that will do that for you. Note though that stash pop can be a dangerous operation, and you really shouldn’t make this an automatic step. Applying a stash can cause conflicts which you will need to resolve manually, and if you used stash pop then the original stash is gone, so you have no way to go back. Commented Jan 26, 2018 at 8:59
  • 2
    Are you sure you want this to happen automatically? That could be quite annoying in some scenarios (e.g. you've modified a file that doesn't exist in my-super-branch). Commented Jan 26, 2018 at 9:00
  • You can use git hooks for that. Commented Jan 26, 2018 at 9:00
  • 9
    @poke stash pop does not drop the stash entry if the stash does not apply cleanly. Commented Jan 26, 2018 at 9:07
  • 1
    @mmlr Oh, you’re right! For some reason, I always thought that it would remove the stash in any case. Good to know! (This still applies though which is why I personally avoid pop) Commented Jan 26, 2018 at 9:38

7 Answers 7

38
git checkout -m target-branch 

or

git checkout --merge target-branch 

https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---merge

Sign up to request clarification or add additional context in comments.

6 Comments

So simply... Need to be the accepted answer.
@vernou This doesn't work with staged files. > git checkout -m main fatal: cannot continue with staged changes in the following files: src/util.test.ts
It would be nice if --autostash could be added to checkout and essentially just do the same thing as above. Merge just isn't the mental model that people come at this problem with. I for one have been manually stashing as a workaround for years until I just found this answer today and that's mainly DX issue.
I would not expect this to work with staged changes, as the staged diff is based on a different base. This answer is pretty much solving the original question, as misleading as the word merge is. This is a pretty common scenario, whenever you have permanent local changes over files that are not ignored, or some other debugging related changes that you might want to keep for the longer run without the need of refactoring. Would be great to get your input @guettli
Cool Thanks! This is exactly what I was looking for forever. Why is it called autostash for pull and rebase, but merge for checkout? This again is one of the many parts, where the git UI is completely broken.
|
5

There is no command-line option for autostash on checkout. I created a script checkout.sh like this:

#!/bin/bash git stash && git fetch && git checkout $1 && git stash pop 

So I can use it with my chosen branch: checkout.sh my-branch

3 Comments

I think it would be more optimal to have it simply aliased inside the ~/.bash_profile :).
Why not git stash --include-untracked?
If there is no file to stash initially, then stash pop will pop wrong stash entry.
2

Git allows Pipelining operations:

git stash && git fetch && git checkout your-branch && git stash apply

Your changes are still in stash as I used git stash apply.

Resolve conflicts if any.

In case you wish to remove your changes from stash after above call below:

git stash drop

Otherwise you could just use git stash pop

1 Comment

&& is a feature of the shell, not Git.
1

To stash your changes and move them onto another branch, add this to your .gitconfig:

[alias] stashonto = "!f() { if [ -z \"$1\" ] ; then echo 'Error: stashonto requires destination branch.\nExample: git stashonto master\nExample: git stashonto -b new-branch 98e7f99e' ; else git stash --include-untracked && git checkout $* && git stash apply ; fi; }; f" 

That creates a git alias that calls a shell function so we can chain several git commands. Here's the function broken down so it's easier to read:

f() { if [ -z \"$1\" ] ; then echo 'Error: stashonto requires destination branch.\nExample: git stashonto master\nExample: git stashonto -b new-branch 98e7f99e' else # stash everything (git stash --include-untracked # switch branch && git checkout $* # apply stash (you must 'git stash drop' to delete the stash if everything goes well) && git stash apply) fi } f 

Warning: It's not fancy enough to detect whether stash saved anything, so if you don't have any changes to stash it will print "No local changes to save" and then apply your previous stash. That's why I'm using apply instead of pop.

Usage:

# stash changes and apply on master git stashonto master # stash changes and apply on new branch 'project' off of commit 98e7f99e git stashonto -b project 98e7f99e 

Comments

1

I made this "smart switch" command. Before to switch, it tries to stash uncommitted changes, leaving a mark in the message.
When you are back, it looks for any marked stash associated to that branch and pop it.

https://gist.github.com/mgaitan/d9a3523d79cd5f9fbfd626f646f0560b

I hope it'll be useful for somebody else.

Comments

0

Hey i was facing the same issue and I didn't really like the other solutions people used to get around this problem so I created a vscode extension that mimics the built in "Git: Checkout to" command but automatically stashes and pops your changes Marketplace link. I am still working on the extension so it is still a WIP but it works well enough to be actually used. More functionality like creating branches etc coming soon.

1 Comment

A link to an external source is not considered a good answer (it could also considered being advertising). Providing a short code snippet from your project could be more helpful.
-3

GIT >= 2.27.0

Having changes not staged for commit:

git switch other_branch

and now we are on other_branch with those changes.

3 Comments

This gives me the same error message as with using checkout, unfortunately.
This just doesn't work. AFAIK switch is an alias to checkout.
This frequently works (both with checkout and switch) — I think when the local changes were to a file that is same on both branches? But the question was specifically about situations where it refuses to switch and prints the error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.