1

Some one merged a non working code into git and there were couple check-ins after that. I have two options, 1. To revert changes one by one and then when I reach good code, stop there. Option 2. Branch out the clean version using the checkin sha and make it the head. I see the question posted here and several other question. If I try option one, after couple resets when I try to reset next one I get:

On branch master
Your branch is ahead of 'origin/master' by 3 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

Then I checked out the version I want to move to HEAD, and try to commit that. But I get this:

HEAD detached at 0c1b8c1
nothing to commit, working directory clean

When I try option 2 get the correct version of the code, but when I try to commit, it says nothing to commit. What's the best way to take an old version of the code and make it the latest and greatest in GIT? This is what I'm trying to do: enter image description here

Community
  • 1
  • 1
Sïd
  • 65
  • 2
  • 11

2 Answers2

4

Check out the last good master into a new branch (so if you accidentally push at the wrong time we don't destroy code):

git checkout <last good master hash> -b local_master_branch

Now, you can cherry-pick the things you want on that branch:

git cherry-pick (HASH OF DESIRED COMMITS)

This works really well, but can be time consuming if there are a lot of branches.

====================================

What I suggest instead is to checkout the good branches

git checkout good_branch

rebase it onto the new_branch

git rebase local_master_branch

and then merge that into the local master

git checkout local_master_branch
git merge good_branch

And then rinse and repeat with the good code.

===================================

If your good branches don't actually exist, and you just have the broken master to work with, check it out

git checkout origin/master -b broken_master

and do an interactive rebase on top of the good master

git rebase -i local_master_branch

This will allow you to specify the stuff you actually want to keep, and is actually the fastest of the three methods.

++++++++++++++++++++++++++++++++++++++++++++++++++

THEN! DANGER! HERE BE DRAGONS!

++++++++++++++++++++++++++++++++++++++++++++++++++

Once finished, you should make a backup of the current (broken) master

git checkout origin/master -b broken_master

Then checkout your clean, totally building and has no problems branch with everything fixed:

git checkout local_master_branch

rename your local branch

git branch -m master

then force-push that to master

git push origin master -f

DANGER! This is DANGEROUS if you don't know what you are actually doing, because you are resetting the master on origin.

And for all the people that are like "Hey now the master I was working on doesn't exist any more," have them rebase on the new master.

n_b
  • 1,116
  • 1
  • 11
  • 20
  • I created a new branch with last good checkin sha. Now when I checkout that branch I get this message: `git checkout origin/clean_branch Note: checking out 'origin/clean_branch'. You are in 'detached HEAD' state..... do so (now or later) by using -b with the checkout command again. Example: git checkout -b ========= Now if I do `git rebase local_master_branch fatal: Needed a single revision invalid upstream local_master_branch' – Sïd Sep 09 '16 at 21:57
  • When you get that message, do `git checkout -b new_branch_name` . You need to name the branch before you can work with it. – n_b Sep 10 '16 at 04:16
  • I did a manual merge to get to what I need. When you create a branch using -b, it'll get pushed as new branch. what I wanted was to push into origin/master or in other words I've a branch origin/clean_code which is behind origin/master and force it to origin/master – Sïd Sep 13 '16 at 18:48
0

It depends on whether you want to

  1. rewrite the history starting from Clean Code (requires forced push if already pushed) or
  2. append history just nullifying the effect of bad commits (push friendly).

1) is already described
2) looks like

1 git checkout <CleanCode hash> 
2 git symbolic-ref HEAD refs/heads/master
3 git commit -m <commit message>
4 git cherry-pick <good commit>
  1. detached checkout, index is synched with CleanCode commit
  2. HEAD points to master top again, index is still holding state of CleanCode
    (1 & 2 can be substituted with get reset <CleanCode hash> and git reset --soft <master top hash>)
  3. make new commit with effective index from CleanCode - effect of every commit after original CleanCode is nullified (bad and good)
  4. apply good delta (restore effect of good commit)

After all that history will look like this

<cherry-picked delta>
|
<CleanCode state copy>
|
<delta to cherry-pick>
|
<bad commit>
..
|
<CleanCode>
|
..
zx485
  • 28,498
  • 28
  • 50
  • 59
IrLED
  • 438
  • 2
  • 5