如何在一个 forked 仓库中将 git 主分支重置为上游分支?

182

我彻底搞砸了我fork的git仓库的主分支。

我希望完全重置被推送到我的fork的主分支,用上游主仓库的内容替换。我对保留任何主分支更改或历史记录没有兴趣。

最简单的方法是删除我的fork仓库并从上游项目重新fork。但是,我在其他已推送的分支中有工作,我不想失去这些工作。

因此,如何将我推送的主分支与上游主分支重置?


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

我该如何重置本地和远程主分支以使其与上游主分支一致?

4个回答

326

您可以将本地主分支重置为上游版本并将其推送到您的起点(origin)仓库。

假设“upstream”是原始仓库,“origin”是您的分支:

# 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

您可以使用git remote add upstream /url/to/original/repo将原始 repo 定义为“上游(upstream)”。


3
你的答案虽然正确,但可能需要使用git reset --hard upstream/master来重置工作目录。 - j6t
不使用“--hard”也可以保留本地更改。我会将硬重置作为一个单独的步骤来执行,以便可能检查差异。 - Johannes Barop
10
需要先执行 git fetch upstream - Henry E
5
如@HenryE所述,如果没有先使用git fetch upstream获取上游更改,通常会产生以下非人类可读错误:"致命错误:模糊参数'upstream/master':未知修订或路径不在工作树中。" - Cecil Curry
3
请注意,强制推送会自动关闭您在上游仓库中打开的所有拉取请求,请谨慎操作。我之前并不知道这一点,感到有些意外。 - Frank Buss
显示剩余4条评论

16
git reset --hard @{upstream}

或者,更简洁一点:

git reset --hard @{u}

或者您甚至可以更进一步,设置一个别名,使您只需键入git scrub即可:

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

假设你的分支已经配置好了跟踪相应的远程分支(如果你没有做特殊的事情,一般都是这样)。有关跟踪和分支规范语法的详细信息,请参见git-branch(1)git-rev-parse(1)

然后只需像其他答案中所解释的那样,git push --force 到你的 fork 中即可。


11

这将使用上游主分支重置您的主分支,如果该分支在您派生它后已更新,则还会拉取这些更改。

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

PS:假设 Upstream 是原始代码库,而 origin 是你的副本。


看起来你是从不同的提交创建了你的分支。重新基础的主要原因是为了保持线性项目历史。尽管如此,一旦提交到公共存储库,就不应该再次基础提交,因为这会用新提交替换旧提交。有关详细信息,请参见https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase。 - user8128167

0

我已经尝试过这样的方法:

$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

输出将显示警告:

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>...]'

所以正确的方法是在git reset之前执行git pull

$ 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

那么输出将会是这样的:

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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接