views:

1632

answers:

3

I recently screwed up my git repo and would like to find out if there is any remedy to it.

My setup is this:

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)

My workflow was like this:

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

This way I always had a pristine state of Central in my Master branch.

Now what I did was started working on Master branch instead. So I made changes to my master and can no longer branch from it to get a copy of Central. Whenever I need to make and push some fixes to Central, i have to clone the Central into another directory and work from there.

My question: Is there a way to "revert" my master to be an identical copy of the Central, while moving all the changes I have made on my Master into another branch (say Feature)?

I know it's confusing, and I would appreciate any help. I will clarify if anything is unclear.

+2  A: 

What exactly do you mean by

I messed [up] my master and can no longer branch from it.

You can always create a new branch from any commit in your repository, no matter how “messed up” it may be–which by the way is something Git has no notion of.

Basically you can revert your repository to any state it previously had because Git will not explicitely delete any objects, it will only garbage collect unreferenced (dangling) objects every now and then. So you just need to find out what your repository looked like. gitk or git log can help you there.

After you restored your local repository to a state you like you can simply push it back to your central public repository. If that results in a non-fast-forward push you might need to specify the --force flag when pushing.

Bombe
Hi, I meant that I can no longer branch from it to get a copy of the Central repo, so I can start working on a new feature.Regarding your suggestion, I thought of that - but that will cause me to loose all my work I did on my master. Will it not? Thanks.
drozzy
+3  A: 
# 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

Now you can checkout old_master and use it just like you did your feature branch

Pat Notz
Origin/master refers to the remote repository of my Master. But I already PUSHED my changes to my github repo.What I need to to is reset it to upstream/master where my Central repo is. Is there any way to do that?
drozzy
+4  A: 

Well the solution was pretty simple, hinted by Pat Notz and 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 old_master 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

#

Now I have two nice branches: master and old_master. With master being a copy of my Central, for fixes to production, and old_master holding all the work that I did previously!

Thanks!

drozzy
Thanks for following up with your solution. I was just trying to sort out your situation -- glad you figured it out.
Pat Notz
I think instead of your 4th command there, "git push old_master origin old_master", you should have "git push origin old_master"? I'm hoping that's right, because that's what seemed to work for me. Otherwise I got an error message: "fatal: 'old_master' does not appear to be a git repository"
Mu Mind