620

This often happens to me: I write some code, go to check in my changes, and then realize I'm not in the proper branch to check in those changes. However I can't switch to another branch without my changes reverting. Is there a way to move changes to another branch to be checked in there?

gmarmstrong
  • 138
  • 2
  • 12
mainsocial
  • 7,443
  • 3
  • 23
  • 24

5 Answers5

1139

git stash is your friend.

If you have not made the commit yet, just run git stash. This will save away all of your changes.

Switch to the branch you want the changes on and run git stash pop.

There are lots of uses for git stash. This is certainly one of the more useful reasons.

An example:

# work on some code
git stash
git checkout correct-branch
git stash pop

Update: No need to use stash command. uncommitted changes do not belong to any branch so just use git checkout -b <new-branch>

GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
Bill Door
  • 18,272
  • 3
  • 32
  • 37
  • 182
    No need to stash uncommitted changed, they go with you when you check out a branch. Stash is more for longer term storage of temporary things (stuff you want to finish and commit later, but you need to do something else right now). – Tekkub Aug 28 '11 at 00:26
  • 3
    I get this. So I have to stash, switch branch and then pop `C:\kf [develop +0 ~4 -0]> git checkout feature/customers
    error: Your local changes to the following files would be overwritten by checkout:
    AspWebApp.vNext/global.asa
    RestApi/Web.config
    Please, commit your changes or stash them before you can switch branches.
    Aborting`
    – IsmailS Jul 21 '14 at 06:52
  • 6
    @Tekkub "longer term storage of temporary things" that saying feels very awkward, another point to use stash is it pushes it in a stack so if you don't want it to carry over and work on something else it is useful in that way. Yes you don't have to but just feels cleaner and more in control. – Atherion Feb 22 '16 at 18:17
  • bravo baby! should append what you should do if you made the commits – Ishan Srivastava Jan 13 '18 at 12:39
  • Using stash has one big disadvantage. If you must merge after the stash pop, then the diffs are a mess: LOCAL and REMOTE are mixed up; at least with Git Extensions and Perforce P4Merge. REMOTE or Theirs is your stash and LOCAL or Ours is someone elses code from the branch. Do you still get it? So I prefer Amber's approach. – ffonz Apr 06 '18 at 14:58
  • @bill You are awesome. This worked like a charm. Of course I didn't have very many edits before I discovered that I was on wrong branch. Life-saver. – Energetic Pixels Dec 10 '18 at 01:31
  • 17
    @Tekkub That is only true if the branch you are switching to is up to date with the branch you are on. If for example you are accidentally working on prod branch and need to switch to stage branch but stage has changed in the mean-time stash is the only way to make the switch. – danielson317 Jul 06 '19 at 17:50
  • @Tekkub the real answer's in the comments ;) – Max Coplan Feb 05 '20 at 15:29
  • Instead of using `git stash pop`, it's safer to use `git stash apply` and when all the changes are applied to your desired branch, then you could run `git stash drop` to drop stash. This helps you to not lose changes when there are merge conflicts. If you use `git stash pop`, you might end up losing some changes in case of conflicts. – Anu Aug 05 '20 at 03:41
  • _"...you might end up losing some changes in case of conflicts"_ **No comments on this??!** @Atherion, I agree `stash` seems like a good command workflow. – xtian Feb 26 '22 at 16:47
322

If you haven't already committed your changes, just use git checkout to move to the new branch and then commit them normally - changes to files are not tied to a particular branch until you commit them.

If you have already committed your changes:

  1. Type git log and remember the SHA of the commit you want to move.
  2. Check out the branch you want to move the commit to.
  3. Type git cherry-pick SHA substituting the SHA from above.
  4. Switch back to your original branch.
  5. Use git reset HEAD~1 to reset back before your wrong-branch commit.

cherry-pick takes a given commit and applies it to the currently checked-out head, thus allowing you to copy the commit over to a new branch.

Benjol
  • 63,995
  • 54
  • 186
  • 268
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 17
    You shouldn't even need to cherry-pick here. `git reset HEAD~N --soft` and then `git checkout -b` to move all the _now_ uncommitted code to a new branch. – Aaron Feb 03 '16 at 04:11
  • 35
    **changes to files are not tied to a particular branch until you commit them.** <-- this. This solved a mystery for me. Thanks. – Tschallacka Jan 13 '17 at 14:03
  • 13
    I get the following error when trying to switch branches: "local changes to the following files would be overwritten by checkout". So, it doesn't seem like I can move to a different branch and commit normally. – Mischa Oct 24 '17 at 01:23
  • 3
    @Mischa it does not work if you are switching between two branches that have different histories – watashiSHUN Jan 30 '18 at 00:42
  • 1
    @Aaron that's much nicer (for the post-commit scenario)! Please make a separate answer. – Jacktose Nov 07 '18 at 22:17
  • But in my case I can't change the branch it aborts, ask to do something about changed files "error: Your local changes to the following files would be overwritten by checkout:" – rkscodes Feb 04 '23 at 19:46
23

Sadly this happens to me quite regularly as well and I use git stash if I realized my mistake before git commit and use git cherry-pick otherwise, both commands are explained pretty well in other answers

I want to add a clarification for git checkout targetBranch: this command will only preserve your working directory and staged snapshot if targetBranch has the same history as your current branch

If you haven't already committed your changes, just use git checkout to move to the new branch and then commit them normally

@Amber's statement is not false, when you move to a newBranch,git checkout -b newBranch, a new pointer is created and it is pointing to the exact same commit as your current branch.
In fact, if you happened to have an another branch that shares history with your current branch (both point at the same commit) you can "move your changes" by git checkout targetBranch

However, usually different branches means different history, and Git will not allow you to switch between these branches with a dirty working directory or staging area. in which case you can either do git checkout -f targetBranch (clean and throwaway changes) or git stage + git checkout targetBranch (clean and save changes), simply running git checkout targetBranch will give an error:

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

watashiSHUN
  • 9,684
  • 4
  • 36
  • 44
10

A soft git reset will put committed changes back into your index. Next, checkout the branch you had intended to commit on. Then git commit with a new commit message.

  1. git reset --soft <commit>

  2. git checkout <branch>

  3. git commit -m "Commit message goes here"

From git docs:

git reset [<mode>] [<commit>] This form resets the current branch head to and possibly updates the index (resetting it to the tree of ) and the working tree depending on . If is omitted, defaults to --mixed. The must be one of the following:

--soft Does not touch the index file or the working tree at all (but resets the head to , just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

JSON C11
  • 11,272
  • 7
  • 78
  • 65
0

If you created new files you can do this:

git checkout main
git checkout -b branch-b
git checkout branch-a :rel/path/to/yourchangedfiles
git commit -m "w"
git checkout branch-a

git checkout main :rel/path/to/yourchangedfiles

# if this happens:
error: pathspec ':rel/path/to/yourchangedfiles' did not match any file(s) known to git

# then just rm the folder
trash-put rel/path/to/yourchangedfiles
jaksco
  • 423
  • 7
  • 18