Sïd
Sïd

Reputation: 65

How to take an old version of git code and make it the latest

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

Upvotes: 1

Views: 3894

Answers (2)

IrLED
IrLED

Reputation: 448

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

Upvotes: 0

n_b
n_b

Reputation: 1156

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.

Upvotes: 4

Related Questions