Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does git require stash save-pop to switch branch?

Sometimes when there are local changes to the working directory, switching branch fails, but the following flow works:

  • Stash save
  • Switch branch
  • Stash pop

How come? Doesn't git know how to apply the local working directory changes to the target branch? What design choice made this procedure necessary? Is there a flag I could use in order to avert this slightly long procedure?

UPDATE:
Assume I want to keep the local changes as local changes when I switch branch. Sometimes it's a practical scenario...

like image 270
Jonathan Livni Avatar asked Jan 30 '26 18:01

Jonathan Livni


2 Answers

There are two scenarios when the current branch is dirty and you try to switch branch:

  1. You forgot to commit the changes.

    In which case git warns you that switching to another branch will cause you to lose your changes. This is basically the default assumption which is why the error message was written the way it is.

  2. Your changes are temporary and you want to switch anyway.

    In which case you need to stash the changes and then apply it again after switching. Git never thinks this is what you want. If I'd have to guess why it's probably because Linus doesn't do this often.

Since git can't read your mind it waits for you to tell it to either commit or stash. Though by the error message I'd say if git were to try to read your mind it will guess that you want to commit instead of stash - but that would be a wrong guess in your case.


Additional answer

Sorry for the long delay between replies but I just today noticed your updated question.

For local changes, my strategy is to create a local changes branch. Then fork all feature branches from that instead of master. This works because local changes usually apply to all working branches.

But doing this makes rebasing with master a bit tedious since you basically need to rebase twice - once to local_changes and then from local_changes to your topic branch. But you could easily write a shell script for this:

# rebase_master.sh
git rebase master local_changes
git rebase local_changes

Another advantage of this is that if you need to reconfigure your environment then changing local_changes will propagate your changes to all topic branches.

To merge back to master you can use git rebase master to remove local_changes from your topic branch before merging.

like image 170
slebetman Avatar answered Feb 01 '26 09:02

slebetman


To cover the final part of your question, if you're doing this a lot, you could create an alias to shorten the procedure:

switch = !f() { git stash && git checkout $1 && git stash pop; }; f

Usage: git switch branchName

like image 36
bcmcfc Avatar answered Feb 01 '26 10:02

bcmcfc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!