170

I'm writing some scripts for my Git workflow.

I need to reset other (existing) branch to the current one, without checkout.

Before:

 CurrentBranch: commit A
 OtherBranch: commit B

After:

 CurrentBranch: commit A
 OtherBranch: commit A

Equivalent of

 $ git checkout otherbranch 
 $ git reset --soft currentbranch
 $ git checkout currentbranch

(Note --soft: I do not want to affect working tree.)

Is this possible?

0

5 Answers 5

346

Set otherbranch to point at the same commit as currentbranch by running

git branch -f otherbranch currentbranch

The -f (force) option tells git branch yes, I really mean to overwrite any existing otherbranch reference with the new one.

From the documentation:

-f
--force

Reset to if exists already. Without -f git branch refuses to change an existing branch.

9
  • 1
    I get fatal: Cannot force update the current branch. when trying to do this.
    – Fuad Saud
    Commented Jun 25, 2014 at 15:42
  • 4
    @FuadSaud that's because you already have otherbranch checked out. This SO question is specifically about resetting another branch to a different commit (i.e. not resetting the checked-out branch). What you want to do is reset the current branch with git reset targetbranch to force the current branch to be pointed at targetbranch. Add --hard to also force the work tree to that content. Or --soft to leave the index alone and only change the branch itself. Commented Jun 25, 2014 at 19:28
  • 1
    Right, so, I know about reset. What I was looking for was a way to, inside a routine, always point local master to upstream/master, independently of what's checked out. I thought branch -f could do that.
    – Fuad Saud
    Commented Jun 25, 2014 at 19:32
  • @FuadSaud You could use git checkout -B master upstream/master which would work regardless of whether master is checked out locally. But it will also switch the branch to master. If you have local changes in the workspace, probably bad. Commented Mar 23, 2015 at 16:23
  • 1
    git branch -f <branchname> <start-point> works fine with remote refs so long as you provide the full ref name as git branch -f master refs/remotes/origin/master
    – Adam
    Commented Sep 10, 2021 at 14:39
110

The workflows you describe are not equivalent: when you perform reset --hard you lose all the changes in the working tree (you might want to make it reset --soft).

What you need is

git update-ref refs/heads/OtherBranch refs/heads/CurrentBranch
7
  • 6
    Man, I wish this worked without the superfluous refs/heads/ Commented Apr 15, 2013 at 23:09
  • 48
    A much nicer way to do this is git push . current:other. This works without refs/heads (/cc @elliottcable), and it also prevents you from updating the checked-out branch. Note that you may need to pass -f (or use +current:other) if the update isn't a fast-forward. Commented Jun 6, 2013 at 7:41
  • 7
    You can also use -m 'some text' argument to record the reason for the ref update to be shown by git reflog OtherBranch command, such as "synched to CurrentBranch". May be useful to remember why you did it later. Commented Dec 11, 2013 at 21:16
  • 23
    Why would you use git update-ref refs/heads/OtherBranch refs/heads/CurrentBranch or git push . CurrentBranch OtherBranch when you could use the much cleaner (IMO) git branch -f OtherBranch CurrentBranch instead? (See my answer on git branch -f below) Commented Jan 9, 2014 at 16:33
  • 6
    @ColinDBennett to save future readers some time: git branch -f won't work if OtherBranch is currently checked out, whereas git update-ref will.
    – Nickolay
    Commented Dec 13, 2020 at 23:44
28

You can sync with this command your branches at any time

$ git push . CurrentBranch:OtherBranch -f

Also without -f it replace this set of commands

$ git checkout OtherBranch
$ git merge CurrentBranch
$ git checkout CurrentBranch

It can be useful when you don't need commit all your files in CurrentBranch and so you can't switch to another branches.

2
  • May cause "remote: error: denying non-fast-forward"
    – Basilevs
    Commented Jun 4, 2014 at 15:13
  • 3
    I wouldn't include -f option unless it’s absolutely inevitable. It works well without it in my case.
    – Melebius
    Commented Mar 31, 2015 at 7:43
2

The other answers are good but a little scary. I'm just providing another option to achieve exactly what was asked for somewhat simply with variations on commands I use every day.

In short, None of these options mess with the current branch you're on or current head.

git branch -C other_branch (force-create other_branch from current HEAD)

To reset other_branch to a branch you're not on...

git branch -C old_branch other_branch (force-create other_branch from old_branch)

To reset other_branch to some_branch on the remote, it's a little bit different...

git pull -f origin old_branch:other_branch (force-pull (which ignores the already-up-to-date stuff) origin/old_branch into local's other_branch)

1

git branch -f destroys the upstream branch info etc. Typing a git update-ref command, which principally operates cleanly, is tedious and error-prone. It could create any kind of nonsense file under .git.

As this operation is needed frequently, do it via a rather safe alias or script:

git reset-other OTHERBRANCHNAME TARGETREF

After adding e.g. this alias to your config:

[alias]
    reset-other = "!f() { git show -s refs/heads/$1 -- && git update-ref refs/heads/$1 $2 && git show -s $1; }; f"

Add from command-line:

git config --global alias.reset-other "!f() { git show -s refs/heads/$1 -- && git update-ref refs/heads/$1 $2 && git show -s $1; }; f"

When the move succeeded to a wrong target by a slip you already have the SHA printed on the screen to move back ...

1
  • I really appreciate described lower-level commands, namely git show and git update-ref. They make life much easier, because I don't have to checkout other branch just for updating it from remote and then checkout back to orignal branch. Big thanks! Commented Jun 28 at 8:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.