Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move HEAD to other branch in Git without checking out files or updating any refs?

Tags:

git

I usually do it by echo ref: refs/heads/new_branch > .git/HEAD. How to do it properly?

Some use cases:

  1. You imported source code from some other location, now want to commit it into Git (but not into current branch).
  2. Your .git is just a symlink and now you are accessing it from other workdir (I already know about git-new-workdir to do it properly)

Therefore you want to choose manually what parent the next commit should have and what ref should be updated by it.

like image 391
Vi. Avatar asked May 16 '13 13:05

Vi.


3 Answers

The git plumbing command for this is

git symbolic-ref HEAD refs/heads/existing_branch

You cannot go into detached head state (it needs a ref, not a SHA). However you can switch to an nonexisting ref (aka. unknown branch). To prevent that, perhaps use following git alias:

git config --global alias.switch '!f() { git show-ref --heads --verify "refs/heads/$1" && git symbolic-ref -m "switch to branch $1 not touching workdir" HEAD "refs/heads/$1"; }; f'

Then you can use it like git switch existing_branch. Please note, that you need option -m to see an entry in git reflog, this is usually what you want.

Notes:

  • git reflog HEAD shows the ref log of HEAD (you will see the comment given at option -m again). The full file (which includes before-after SHAs in case you want to find some lost commit) is stored at $(git rev-parse --git-dir)/logs/HEAD (for HEAD)
  • git show-ref --heads lists all refs you can use on the RHS. As shown in the alias you can use it with --verify to check if an argument is a proper (existing) ref (aka. branch).
  • Beware: git symbolic-ref can point to any other ref like refs/tags/ or refs/remotes/ or even inside packed refs. This is probably not what you want, hence the alias restricts this to refs/heads/.
like image 96
Tino Avatar answered Oct 14 '22 15:10

Tino


git reset --soft $branch_to_make_HEAD

man git reset docs on the --soft option:

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

like image 40
intuited Avatar answered Oct 14 '22 13:10

intuited


git checkout -B existing_or_new_branch # HEAD by default
git reset       existing_branch@{1}    # or anywhere else for a new_branch
like image 41
MarcH Avatar answered Oct 14 '22 14:10

MarcH