I have multiple active branches that I need to work on at the same time. Clearly I can create two working directories with a distinct branch per directory. Is that the only way to do it without having to "commit" and "checkout" in order to switch from one branch to another?
6 Answers
If you are temporarily switching branches git stash
is useful, however, remember that commits don’t need to persist forever; you may make temporary commits to roll back later.
So my recommendation is, if it is a many hours long switch, to do a git commit
instead, because, depending on your memory, stashes can be easy to forget/lose/etc.
[In MyBranch]
>$ git commit -m "WIP: Stuff I was working on."
>$ git checkout AnotherBranch
[Do Stuff]
>$ git checkout MyBranch
>$ git reset HEAD^
[Continue]
And since this is a question about best practices, remember to give your stash a useful message using git stash save
otherwise it can be difficult to find later.

- 466
- 2
- 5
-
if you work in different PCs (eg: at office-location-1 and at office-location-2) by this way, u can commit your not-finalized work [at office-location-1] and push to remote, then later u can pull [at office-location-2] and reset it, do stuff and make a final-completed-commit. :) – kdaShivantha Aug 02 '19 at 07:00
Yes, though you can use git stash
instead of commit
if you're not ready to finalize your current work in progress.

- 75,175
- 8
- 100
- 122
-
1I was unaware of this command. i like it because it's exactly what I was thinking. Just a place to put my stuff until I was really ready to commit. In the last week I have committed "snap" several times so that I could change branches. It made me very mad because many of those changes are likely to change again... In the meantime these changes will become public to my team when I push... some of which might be embarrassing. "stash" is to be tested ASAP. Thanks! – Richard Jun 21 '10 at 02:22
-
2Glad to help. It's important to realize, as cweider noted, that you can always rewrite your local history as long as a commit hasn't been pushed. For example, if you have a "snap" commit between other commits you want to keep, you could `cherry-pick` it into a different branch, then do a `rebase -i` to remove it from the other branch. – dahlbyk Jun 21 '10 at 13:08
git clone
, through the local protocol, is a good alternative to be able to work on multiple branches at the same time.
I usually clone one local bare repo into multiple copies (one for each active branch), and use that bare repo as a central integration repo (since I can push easily to a bare repo, versus not being able to push to non-bare repo).

- 1,262,500
- 529
- 4,410
- 5,250
-
For the "bare repo" justification, see http://stackoverflow.com/questions/2041823/git-how-to-see-pulled-pushed-changes-in-origin/2041865#2041865 for instance – VonC Jun 16 '10 at 20:41
-
2that's what people did with svn, now you can use git branching features, you don't need many local repositories. that's the main point of git. – Gismo Ranas Oct 23 '14 at 14:31
-
4
I got tired of switching between branches and so I wrote a smarter git checkout
. Insert the following into your ~/.bash_profile
, source it, and then simply use gch
to switch to the last branch you were on.
current_git_branch() {
git branch | grep \* | awk '{ print $2 }'
}
# a smart git checkout, with no args it switches to last branch.
gch() {
if [ -n "$1" ]; then
echo `current_git_branch` >"/tmp/last_git_branch_used.txt"
git checkout "$@"
else
if [ ! -f "/tmp/last_git_branch_used.txt" ]; then echo >&2 "ERROR: Please run gch with 1 argument first."
else
echo `current_git_branch` >"/tmp/last_git_branch_used.temp"
git checkout `cat /tmp/last_git_branch_used.txt`
mv "/tmp/last_git_branch_used."{temp,txt}
fi
fi
}

- 1,421
- 12
- 21
-
Is this still how you'd approach the problem, a bit over a year later? Just curious because I was looking for exactly this. :) – Matt Passell Apr 16 '15 at 17:54
-
1Yup, this exact snippet is still in my bash profile. One downside to this is that the `last_git_branch_used.txt` carries no information about the git repo, so if you're switching back and forth between different branches of different repos, this isn't so useful. But I still think I've saved a million keystrokes. – skensell Apr 25 '15 at 07:33
-
2I've been using it for the past few days and finding it very handy. I do most of my work in one repo, so that's definitely a limitation I can live with. By the way, it works fine with zsh (which isn't surprising, since zsh is derived from bash). I'll share this with the rest of my team. Thanks! – Matt Passell Apr 27 '15 at 13:48
-
So I made some improvements to this script, that caches previously switched branches to the project's .git folder, regardless if you're in a subfolder or not. https://gist.github.com/spoike/3c84325b2dc35d18bbdf630606c7d034 – Spoike Dec 07 '16 at 14:09
-
3Seems like you can switch to previously checked out branch with `git checkout -`, which is synonymous with `git checkout @{-1}`. You can read about [special cases for branch references in the git docs](https://git-scm.com/docs/git-checkout#git-checkout-ltbranchgt). – Spoike Dec 07 '16 at 14:26
If you are doing what is called branch-per-feature development as explained here:
http://martinfowler.com/bliki/FeatureBranch.html
you might want to also ensure that you switch the database schemas. Git can help in this by means of smudge and clean. Managing multiple databases locally is then possible. When you checkout a new branch, you smudge the connection string to annotate the database name with the branch name. Should the configuration file be committed at any point, it is cleaned by removing the name of the branch from the connection.
For more information, take a look at the Pro Git book.

- 232,980
- 40
- 330
- 338

- 124,556
- 26
- 146
- 141
I have a bash function like this:
function gitredocommit {
lastcomment=`git log | grep Date -A 2 -m 1 | tail -1 | sed -e 's/^ *//' -e 's/ *$//' | grep -v Merge`
if [ -n "$lastcomment" ]; then
git reset --soft HEAD^; git add ../; git commit -m"$lastcomment"
else
echo "last commit was a merge, won't redo it"
fi
}
You create a new branch, make a first (and last) commit and then with this you can do new stuff and overwrite this commit. If you need to update from the master you do it with
git rebase master
of course, so your commit is always on top in the branch. This works as long as you don't merge the branch in master.

- 6,043
- 3
- 27
- 39
-
1Is the `lastcomment=` line how you detect if a commit is a merge or not ?? – Andrew C Oct 23 '14 at 15:15
-
-
Sorry, that was my attempt at saying "That's a completely insane way of detecting if something is a merge commit and it has horrible performance implications". Try using `git rev-parse HEAD^2` instead. – Andrew C Oct 24 '14 at 14:22
-
if it works, it works, it has not to be published on the annals of the academic experts of baloney computer science to be good. thank you for your suggestion anyway, I'll check how many pico-seconds performance I will gain with it. – Gismo Ranas Oct 27 '14 at 09:36
-
2Except it doesn't work. You aren't detecting merge commits, you are detecting the word "Merge" and getting false positives and negatives. And if you do `git log` (without -1) on even a medium size project you are talking about wasting 10s of seconds to minutes. – Andrew C Oct 27 '14 at 14:12