I have the following git history.
While working on "Feature 1" I realized a major bug in the MASTER branch (existant in all "red" commits) and I had to reset MASTER to the last "blue" commit. From there on I worked on "Feature 2" and the final commit in this branch is now the deployed version. Feature 1 is still work in progress - but incorps the bug.
What I would like to do:
- Make "Feature 2" the new master branch.
- Have a version of "Feature 1" without the bug.
- Delete all commits with bug.
Additional Info: This is not a team project, I am working alone on it, so there a no more branches and different versions floating around than what is shown here.
CodePudding user response:
First, as you already did, reset the master to the last sain commit git reset <last_sain_commit> --hard
.
Please ensure the repository is clean (using something like git clean -fxd
).
This makes sure that you don't accidentally commit the bug again.
Afterward, you will have two strains, "feature_2" with only blue commits and "feature_1" with only red commits.
Now simply reset the master branch to the feature_2 branch using git reset feature_2 --hard
.
You can also replace feature_2 with a specific commit or another branch.
To get rid of the buggy commit, switch to "feature_1". Now we have two options, revert and remove. I'd recommend you revert, as it removes the bug without potentially destructive changes to the history, but you might actually want to use remove.
Revert
Revert the specific commit using git revert <invalid_commit_id>
.
This will produce the following structure (from newest to oldest):
- Revert "Red 1"
- Red 7
- Red 6
- ...
- Red 1
- Blue (shared)
Remove
Open a rebase prompt by running: git rebase --no-autosquash --interactive --keep-empty <hash_of_last_blue_commit_in_branch>
.
This will open a text editor containing a bunch of lines similar to this.
pick <commit_hash> Red 1
pick <commit_hash> Red 2
pick <commit_hash> Red 3
pick <commit_hash> Red 4
pick <commit_hash> Red 5
pick <commit_hash> Red 6
pick <commit_hash> Red 7
Replace "pick" with "drop" for all commits that introduced part of your problem. So, in your example:
drop <commit_hash> Red 1
pick <commit_hash> Red 2
pick <commit_hash> Red 3
pick <commit_hash> Red 4
pick <commit_hash> Red 5
pick <commit_hash> Red 6
pick <commit_hash> Red 7
Confirm and exit. This will replay all commits except the ones marked with drop.
Don't forget to push the modified history (using git push -f
).
CodePudding user response:
If I understand correctly, master is already pointing (with a hard-reset, I assume) to what is shown as feature2, right?
Then, I would also assume that you would like to bring over the revisions that were part of master before resetting to feature2 past the first red commit (which I, again, assume you want to avoid from bringing over into master, right?)
Then.... this is what I would do:
git branch bug the-id-of-the-revision-where-the-bug-was-introduced
git branch old-master the-old-revision-where-master-was
git checkout master
# apply the old revisions of master that you left behind with the hard reset
# ... AND do NOT apply bug
git cherry-pick bug..old-master
# put feature1 on top of the new master
git rebase --onto master old-master feature1
I think that's it