views:

29

answers:

2

I have a git repo which has a few branches - there's the master branch, which is our stable working version, and then there is a development/staging branch which we're doing new work in.

Unfortunately it would appear that without thinking I was a bit overzealous with rebasing and have pulled all of the staging code into Master over a period of time (about 80 commits... yes, I know, stupid, clumsy, poor code-man-ship etc....).

Due to this it makes it very hard for me to do minor fixes on the current version of our app (a rails application) and push out the changes without also pushing out the 'staged' new features which we don't yet want to release.

I am wondering if it is possible to do the following:

  1. Determine the last 'trunk' commit
  2. Take all commits from that point onward and move them into a separate branch, more or less rolling back the changes
  3. Start using the branches like they were made for.

Unfortunately, though, I'm still continually learning about git, so I'm a bit confused about what to really do here.

By the way, commits have been pushed to a remote, but I don't mind re-pushing with --force, I am the only one who pushes remote.

Thanks!

A: 

have you already pushed your commit to a remote repository? if you haven't you can simply use git reset <commit> (make sure to read the manpage before, reset can be dangerous and confusing)

knittl
Sorry I should have added that - these commits have been pushed to remote, but I don't mind force-pushing them back out again, I'm the only one pushing to remote.
Matthew Savage
well, in that case make sure everybody else also deletes the commit
knittl
+2  A: 

There will be the issue of publication (meaning you will have to:

  • force push the new master to your remote
  • communicate with anyone having already pulled from that remote in order for them to reset their master to the remote one )

if your situation is:

m1-m2-m3-m4-s1-s2-s3-s4 (master,stage)

that is, if your current master its actually also the current stage branch, a simple reset is in order (as knittl mentions in his answer)

But if your situation is:

m1-m2-m3-m4-s1-s2-s3-s4-m5-m6 (master)
                       \
                        -s5-s6 (stage)

as in: "I have integrated stage into master, and then go on working on master!"
, then a rebase --onto is in order:

git checkout master
git reset --HARD m4
git rebase --onto master s4 m6

you will get:

m1-m2-m3-m4-m5'-m6' (master)
           \
            -s1-s2-s3-s4-s5-s6 (stage)
VonC
very good answer. +1
knittl
Thanks for the detailed answer, both your and knittl's responses were extremely helpful... now I just need to punish myself for screwing up the workflow :P
Matthew Savage