180

I've completely messed up the master branch of my forked git repo.

I want to completely reset the master branch that was pushed to my fork with the contents of the upstream master repo. I have no interest in retaining any master branch changes or history.

The simplest approach would have been to delete my forked repo and refork from the upstream project. However, I have work in other pushed branches that I don't want to lose.

Thus how to I reset my pushed master branch with the upstream master?


git clone https://myrepo.git
cd myrepo
git remote add upstream https://upstream.git
git fetch upstream

Where do I go from here to reset my local and remote master branches with the upstream master?

Stefan Dorunga
  • 679
  • 6
  • 18
fossfreedom
  • 2,903
  • 2
  • 19
  • 40

4 Answers4

324

You can reset your local master branch to the upstream version and push it to your origin repository.

Assuming that "upstream" is the original repository and "origin" is your fork:

# ensures current branch is master
git checkout master

# pulls all new commits made to upstream/master
git pull upstream master

# this will delete all your local changes to master
git reset --hard upstream/master

# take care, this will delete all your changes on your forked master
git push origin master --force

(You can define the original repo as "upstream" with git remote add upstream /url/to/original/repo.)

Pain
  • 111
  • 1
  • 2
  • 12
Johannes Barop
  • 7,323
  • 2
  • 25
  • 33
  • 3
    It should probably be `git reset --hard upstream/master` to reset the working directory, too. But your answer is correct nevertheless. – j6t Feb 19 '17 at 21:30
  • Not using "--hard" also works while keeping local changes. I would do the hard reset in a sperated step to possibly inspect the diff. – Johannes Barop Aug 04 '17 at 18:20
  • 10
    Need to call `git fetch upstream` first – Henry E Jan 09 '18 at 13:34
  • 5
    As @HenryE notes, failing to fetch upstream changes first with `git fetch upstream` typically yields the following non-human-readable error: `"fatal: ambiguous argument 'upstream/master': unknown revision or path not in the working tree."` – Cecil Curry Aug 17 '18 at 01:47
  • 3
    Just be careful that the forced push automatically closes all open pull-requests you made for the upstream. I wasn't aware of this, which was a bit of a surprise. – Frank Buss Sep 22 '19 at 06:52
  • This solution does not work. The command `git pull upstream master` created a lot of conflicts. – Alex May 19 '22 at 18:00
  • The original solution was edited to "pull". Try `git fetch` instead of `git pull`. – Johannes Barop May 24 '22 at 16:08
  • What if I already pushed the changes to the origin? I found that "git reset upstream/master" just updates the head to the last commit of the (remote) forked repository which, in my case, already has the changes in there. – a6i09per5f Jun 01 '22 at 14:46
15
git reset --hard @{upstream}

or, shorter:

git reset --hard @{u}

Or you can even take it one step further and setup an alias that will allow you to simply type git scrub:

git config --global alias.scrub 'reset --hard @{upstream}'

(This assumes that your branch is configured to track the corresponding remote branch, which it typically is, unless you are doing something special. See git-branch(1) for more details on tracking and git-rev-parse(1) for details on the branch specification syntax.)

And then you just git push --force to your fork, as explained in other answers.

kirelagin
  • 13,248
  • 2
  • 42
  • 57
11

This would reset your master branch with the upstream master and if the branch has been updated since your forked it would pull those changes as well.

git checkout master 
git reset upstream/master
git pull --rebase upstream master
git push origin master --force

PS: Assuming Upstream is the original repo while origin is your copy.

Bhavesh Gupta
  • 176
  • 1
  • 8
  • It would appear as if you'd created your branch from a different commit. The primary reason for rebasing is to maintain a linear project history. That said, you should never rebase commits once they have been published to a public repository because this replaces old commits with new ones. For details please see https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase – user8128167 Jun 24 '19 at 13:57
0

I have tried the method like this:

$REPO=<repo>
$ORIGIN=<user>/$REPO
$UPSTREAM=<upstream>/$REPO

$ git clone git@github.com:$ORIGIN.git
$ cd $REPO
$ git checkout master
$ git remote add upstream git@github.com:$UPSTREAM.git
$ git reset --hard upstream/master
$ git pull --rebase upstream master
$ git push origin master --force

the output will show a warning:

fatal: ambiguous argument 'upstream/master': 
unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

So the correct way is put git pull before git reset:

$ git clone git@github.com:$ORIGIN.git
$ cd $REPO
$ git checkout master
$ git remote add upstream git@github.com:$UPSTREAM.git
$ git pull --rebase upstream master
$ git reset --hard upstream/master
$ git push origin master --force

then the output will be like this:

From github.com:<upstream>/<repo>
 * branch                master     -> FETCH_HEAD
 * [new branch]          master     -> upstream/master
HEAD is now at 7a94b1790 Merge pull request #4237 from <upstream>/...
Current branch master is up to date.
Everything up-to-date.
eQ19
  • 9,880
  • 3
  • 65
  • 77