Switch Git branch without files checkout
Solution 1
Yes, you can do this.
git symbolic-ref HEAD refs/heads/otherbranch
If you need to commit on this branch, you'll want to reset the index too otherwise you'll end up committing something based on the last checked out branch.
git reset
Solution 2
In v2.24
git switch
is something like a safegit checkout
.
Hence I renamed the alias below togit hop
for
"hop on the branch without changing worktree"
For the benefit of the reader:
While I think that Charles Bailey's solution is a correct one, this solution needs a tweak when switching to something, which is not a local branch. Also there should be some way how to do it with regular commands which is easy to understand. Here is what I came up with:
git checkout --detach
git reset --soft commitish
git checkout commitish
Explained:
-
git checkout --detach
is the same asgit checkout HEAD^{}
which leaves the current branch behind and goes into "detached head state". So the next modification ofHEAD
no more affects any branch. DetachingHEAD
does not affect the worktree nor the index. -
git reset --soft commitish
then movesHEAD
to the SHA of the givencommitish
. If you want to update the index, too, leave--soft
away, but I do not recommend to do so. This, again, does not touch the worktree, and (--soft
) not the index. -
git checkout commitish
then attachesHEAD
to the givencommitish
(branch) again. (Ifcommitish
is a SHA nothing happens.) This, too, does not affect index nor worktree.
This solution accepts everything which refers to a commit, so this is ideal for some git
alias. The rev-parse
below is just a test to make sure, nothing breaks in the chain, such that typos do not accidentally switch into detached head state (error recovery would be way more complex).
This leads to following git hop treeish
alias:
git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'
FYI, you can find it in my list of git
aliases.
Solution 3
Wouldn't be a better solution to have two working directories (two working areas) with one repository, or even two repositories?
There is git-new-workdir tool in contrib/
section to help you with this.
Solution 4
I think you're looking for the plumbing command git read-tree
. This will update the index but will not update any files in your working directory. For example, assuming branch
is the name of the branch to read:
git read-tree branch
If you want to then commit to the branch you just read, you will also need to:
git symbolic-ref HEAD refs/heads/branch
Solution 5
You can overwrite your HEAD file with a different branch name:
echo "ref: refs/heads/MyOtherBranch" > .git/HEAD
tig
Updated on July 11, 2022Comments
-
tig almost 2 years
Is it possible in Git to switch to another branch without checking out all files?
After switching branch I need to delete all files, regenerate them, commit and switch back. So checking out files is just a waste of time (and there are about 14,000 files - it is a long operation).
To make everything clear:
I need all this to upload documentation to GitHub.
I have a repository with the gh-pages branch. When I rebuild documentation locally, I copy it to the repository directory, commit and push to GitHub. But I was not happy, because I had two copies of documentation locally. And I decided to create an empty branch and after committing, switch to empty and delete files. But switching back is a long operation - so I asked this question.
I know that I can just leave on the gh-pages branch and delete files, but I don't like dirty working trees.
-
Greg Hewgill almost 15 yearsIt's probably better to use the symbolic-ref command to do this for you:
git symbolic-ref HEAD refs/heads/MyOtherBranch
kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html -
Anonigan almost 15 yearsYou can use
git-new-worktree
for that instead (incontrib/
) -
tig over 14 yearsno I only need to switch branch, no any other changes - so symbolic-ref is good enough
-
tig over 14 yearsThe question already got an answer: stackoverflow.com/questions/1282639/…
-
cadorn over 11 yearsUse
echo "ebff34ffb665de0694872dceabe0edeaf50ec5a9" > .git/HEAD
followed bygit reset
to point to a ref instead of a branch. -
Alexander Bird over 11 yearsDirectly writing to the HEAD file is less dependable. What if you are in a subdir? For detached head (head pointing to SHA1 directly), try this:
git update-ref HEAD refs/heads/otherbranch
-
Winny almost 10 yearsIf you want to check out to a fresh branch from the current branch, another way to do this is to 1.
git stash
2.git checkout -b otherBranch
3.git stash pop
-
tomekwi over 8 years@AlexanderBird:
git update-ref
is useful, but it also moves the tip of the current branch. -
tomekwi over 8 years@GregHewgill, this is the only way I know of to move the HEAD to a commit hash. Can you do that with
git symbolic-ref
? -
Ryuu about 7 yearsIs git-new-workdir the same as git's own worktree command? I use worktree when I want to checkout a branch into a different folder (without having to clone the entire repo).
-
Anonigan about 7 yearsThe
git-new-worktree
script predatesgit worktree
subcommand; this command was not available when the answer was written. The script for example requires symlink support; IMHO it is better to use native support. -
David almost 7 yearsI often did something similar, which is copying my local directory before doing any "scary git stuff" as a newbie (like changing branches, etc). I'd encourage people to go that route until you feel confident in your git-fu, but to move away from it when possible. Keeping two distinct repos is ok, but adds a layer of complication and doesn't let you take advantage of git's many useful features (merging, cherry-picking, etc).
-
kyb over 5 yearsDon't you want to use
$@
rather than$*
? The difference is that $@ with not expand quoted arguments, which have spaces inside. -
Tino over 5 years@kyb The function trick is stolen from another SO answer. And
$@
is definitively not meant here.$*
is used instead of$1
, such thatgit switch -f b
becomes the same asgit switch '-f b'
which should be an error. This way I can shorten the alias by leaving away some error handling like!f() { [ 1 = $# ] || { echo 'WTF!'; return 1; }; ..
-
Andry over 4 years
read-tree
generates the error:fatal: Not a valid object name branch
if there was no anygit switch branch
yet -
Nils-o-mat over 4 yearsVery good solution. Especially, that it can be used for remote branches!
-
Joerg over 2 yearsI used
git reset refs/heads/otherbranch
directly to get the same result -
tejasvi88 over 2 years@Andry Replace
branch
with your target branch name.