111

let's say that we have an hotfixes branch which was created from master. we added commits to hotfixes, but those commits were not useful, so now we want to start from a fresh copy of master again.

to clarify better, this is the reference workflow: http://nvie.com/posts/a-successful-git-branching-model/

let's also say that we pushed hotfixes to the origin remote because we have an awful set up and that's the only way to test something, so we need to reset the branch also on the remote server.

how to reset hotfixes to a copy of master?

danza
  • 11,511
  • 8
  • 40
  • 47

5 Answers5

190

this is how i did it with basic Git commands:

git checkout hotfixes
git reset --hard master
git push --force origin hotfixes

of course it's important to notify everyone working on hotfixes. most likely they will have to delete their local copy and start from a fresh one. an alternative, less invasive idea is to create a new branch:

git checkout master
git branch -tb hotfixes-2 # this creates branch `hotfixes-2` from a copy of `master`
git push origin HEAD # this creates `hotfixes-2` on the remote server
danza
  • 11,511
  • 8
  • 40
  • 47
  • 1
    Thanks for the preference, but i am curious to know why you find it less error-prone – danza Nov 22 '16 at 16:14
  • 2
    I should have stated that it is a personal preference and wasn't trying to state a fact. To me, it requires more actions, which describe better what you are doing rather then just pushing to a different remote, which, in turn, makes me more aware of what I'm doing. Also, the extra `-f` flag and `reset --hard` have warning with GUI tools like sourcetree for instance.. – Daniel Dror Nov 23 '16 at 09:13
  • 2
    Sorry, I meant to say that if you are using a GUI tool like source tree, then using the steps above makes you more aware, because there are warnings along the way, which means you can abort at any time.. – Daniel Dror Nov 23 '16 at 09:24
  • This is the right answer. `reset --hard` shifts the local HEAD pointer for the current branch to the specified ref *and* updates the working directory tree to match it (discarding any differences). – benjimin Feb 11 '23 at 07:24
51

You mean you want to push your local master to the remote hotfixes branch? Like this:

git push origin +master:hotfixes

However, this requires that you are allowed to re-write the history on the remote side.

Michael Wild
  • 24,977
  • 3
  • 43
  • 43
  • 2
    Is this the correct syntax? When I did this I got a new remote branch with the plus (+) in the name. I had to move the plus like `git push origin +master:hotfixes`. This is according to the git spec: http://git-scm.com/docs/git-push – jwynveen Jul 01 '14 at 21:17
  • 23
    fyi, the plus sign is shorthand for doing a `--force` during the push: http://stackoverflow.com/questions/1475665/why-git-push-helloworld-mastermaster-instead-of-just-git-push-helloworld – Jim Geurts Mar 01 '16 at 15:23
  • 16
    I think it's worth noting that this does not update your local (hotfixes) branch. You will still probably want to `git reset --hard origin/hotfixes` afterwards. – Vyskol Apr 13 '16 at 21:00
  • For future readers, I strongly suggest you take your time and understand the given command before running it to avoid a mess afterwards – Shahlin Ibrahim Jul 03 '21 at 18:06
11

If I understood your question correctly, what you're looking for is a way to move the branch pointer of origin/hotfixes to point to the current revision of origin/master.

If that be the case, these set of command should work (assuming you already have checked out hotfixes in your local git repo any time in the past):

# git branch -f does not allow modifying the currently checked out
# branch, so checkout any other branch than hotfixes
git checkout <SOME_OTHER_BRANCH_THAN_HOTFIXES>

# Move the branch pointer of hotfixes to the commit currently
# pointed by origin/master
git branch -f hotfixes origin/master

# Force push the history rewrite in the hotfixes branch
# into origin
git push -f origin hotfixes
Tuxdude
  • 47,485
  • 15
  • 109
  • 110
4

The answers here are solid. I have needed this exact change when resetting my staging branch to master. In that case I want to both reset the origin to match master and also reset my local to match that. So here is a git alias that allows you to pass in the branch name and do both commands in one move. (It's a little dangerous)

reorient = "!f() { git push origin +master:$1 && git reset --hard origin/$1 ; }; f"

Then use it like:

git reorient hotfixes

The answers above were totally correct. But this will simply allow for fewer keystrokes and a quicker turnaround! Hope it helps.

Aaron Wortham
  • 175
  • 1
  • 1
  • 10
  • 3
    i wouldn't wrap a `git reset --hard` in an alias so easily ... i'd be afraid to forget and lose important changes – danza Jan 25 '18 at 11:39
  • 3
    Yeah. Like I said in the explanation "it's a little dangerous". However, in certain instances you can find yourself doing this on the regular, in which case you may want something quicker. – Aaron Wortham Jan 30 '18 at 00:47
  • 2
    @danza ....then again, a `reset --hard` mistake is not unfixable. Reflog is our (dearest) friend! – Romain Valeri Jun 29 '18 at 13:22
1

Based on a few of the answers in this thread, I did the following script with a few prompts to reduce risk of messing stuff up:

#!/bin/bash
# Questions for loop:
for value in {1..3}
do
  # Asking if user wants to reset hotfix:
  if [ "$value" == "1" ] ;then
    echo -n "Are you sure you want to hard reset the hotfix branch (y/n)? "
    read answer
    if [ "$answer" == "${answer#[Yy]}" ] ;then
        echo 'Okay, maybe next time.'
        exit
    fi
  fi
  # Asking if user is in void:
  if [ "$value" == "2" ] ;then
    echo -n "Are you in the void branch (y/n)? "
    read answer
    if [ "$answer" == "${answer#[Yy]}" ] ;then
        echo 'You should checkout to the void branch.'
        exit
    fi
  fi
  # Asking if user has any uncommited changes:
  if [ "$value" == "3" ] ;then
    echo -n "Do you have any uncommited changes (y/n)? "
    read answer
    if [ "$answer" == "${answer#[Nn]}" ] ;then
        echo 'You should commit your changes to avoid losing them.'
        exit
    fi
  fi
done

echo 'Resetting...'
git checkout void
git branch -f hotfix origin/master
git push -f origin hotfix

100% open to any feedback to improve this script.

rmolinamir
  • 1,121
  • 14
  • 15
  • 2
    First, not clear why you need a loop here. Second, you can check for branch/uncommitted changes yourself. The better prompt would be "You have uncommitted changes. Commit them before proceeding" – Sergei Jan 22 '20 at 09:58
  • Thanks Sergei. Regarding #1, I agree, not sure why I added a loop there lol. Regarding #2, an amazing idea. I think the command is along the lines of `if [ -z "$(git status)" ];`, I'll do some digging later then improve the script. – rmolinamir Jan 22 '20 at 17:31
  • If you want to make a tool to automate frequent git tasks, have a look at python and GitPython. Worked great for me. https://gitpython.readthedocs.io/en/stable/tutorial.html – Sergei Jan 23 '20 at 11:14