创建Git分支,并将原始代码回滚到上游状态。

32

我最近把我的git仓库搞砸了,想知道是否有任何解决方法。

我的设置如下:

Central repo on github.
Personal repo on github (which is a fork of Central)
   +Central is setup as remote (upstream/master)
   +Master branch (origin/master)
   +Feature branch (origin/feature)

我的工作流程如下:

Need to fix something in Central:
   1. checkout Master
   2. Make changes
   3. Pull from upstream/master and merge
   3. Commit, push to upstream/master

Need to work on a New Feature:
   1. Checkout/Create Feature branch
   2. Work work work
   3. Pull from upstream/master and merge
   4. Commit, push to upstream/master

因此,我开始在主分支上工作。所以我对我的主分支进行了更改,不再可以从中获取Central的副本。每当我需要对Central进行一些修复和推送时,我都必须将Central克隆到另一个目录并从那里工作。

我的问题是:是否有一种方法可以将我的主分支“恢复”为与Central完全相同的副本,并将我在主分支上所做的所有更改移动到另一个分支(比如说Feature)中?

我知道这很令人困惑,如果有任何不清楚的地方,请帮忙澄清。谢谢。

3个回答

48

经过 Pat Notz 和 Bombe 的指引,解决方案相当简单。

#Make sure we're on the master branch
$ git checkout master

# Make a new branch to hold the work I've done
$ git branch old_master

# Save this branch on my remote repo (for backup)
$ git checkout old_master
$ git push origin old_master

# Reset my local master back to match the commit just before I started 
# working on my new feature
$ git checkout master
$ git reset --hard 2aa93842342342

# Get it to be the same as my Central
$ git pull upstream master

# Now DELETE my master on my remote repo
$ git push origin :master

# And recreate it
$ git push origin master

# Branch created!
#* [new branch]      master -> master

#

现在我有两个很好的分支:master和old_master。master是我中央仓库的副本,用于生产问题的修复,而old_master则包含我之前完成的所有工作!

谢谢!


1
感谢您跟进解决方案。我只是在尝试梳理您的情况,很高兴您已经解决了问题。 - Pat Notz
5
我觉得你应该使用 "git push origin old_master" 代替你的第四个命令:"git push old_master origin old_master"。我希望这是正确的,因为这个命令对我来说似乎是有效的。否则,你会收到一个错误信息:"fatal: 'old_master' does not appear to be a git repository"。 - Mu Mind
4
我无法执行 "git push origin :master"。这篇文章提供了一种解决方法。http://matthew-brett.github.com/pydagogue/gh_delete_master.html 关键是确保在 Github 上 master 不是默认分支。如果您正在处理 fork 的仓库,这是一个不错的策略。 - pduey
或者如果您有ssh /命令行访问裸库,则可以从裸库目录发出此命令git symbolic-ref HEAD refs/heads/old_master,然后删除,然后将符号引用切换回主分支:https://dev59.com/qG855IYBdhLWcg3wNxgM - Jason

16
# Make sure we're on the master branch
$ git checkout master

# Make a new branch to hold the work I've done
$ git branch old_master

# Reset my local master back to match origin/master
$ git reset --hard origin/master

现在你可以检出old_master分支,并像之前使用feature分支一样使用它。


origin/master 指的是我的 Master 的远程仓库。但我已经将更改 PUSH 到了我的 Github 仓库。 我需要重置它到 upstream/master,即我的中央仓库。有没有办法做到这一点? - Andriy Drozdyuk
毫不奇怪,git reset --hard upstream/master 看起来很好用(如果你已经将 upstream 设置为正确的仓库)。 - starwed

3

你的意思是什么?

我把我的主分支搞砸了,现在无法从它创建新的分支。

你可以随时从存储库中的任何提交创建新分支,无论它有多么“混乱” - 顺便说一下,这是Git没有概念的东西。

基本上,你可以将存储库恢复到它先前具有的任何状态,因为Git不会明确删除任何对象,它只会每隔一段时间垃圾回收未引用(悬空)的对象。所以你只需要找出你的存储库看起来像什么。gitkgit log可以帮助你。

在将本地存储库恢复到你喜欢的状态之后,你只需将其推回中央公共存储库即可。如果这导致非快进推送,则可能需要在推送时指定--force标志。


嗨,我的意思是我不能再从它分支以获取中央仓库的副本,以便我可以开始开发新功能。 关于您的建议,我考虑过了 - 但这会导致我失去我在主分支上所做的所有工作。不会吧?谢谢。 - Andriy Drozdyuk

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