On my local git repo I\'ve got many commits, which include \'secret\' connection strings :-)
I don\'t want this history on github when I push it there.
Essen
I don't have enough reputation to comment, so I'll post an answer.
If you have submodules, an approach similar to Paschalis' answer provides a more stable alternative (cherry-pick
does not take submodules into account) and minimises conflicts (none in my case).
Here's my preferred approach:
git checkout OLDSHA -b temp
git merge --squash master
git commit -m "All my work"
Where OLDSHA
is the oldest commit you feel safe to push to the public repository and master
is the branch that contains all your work.
This creates a new branch (temp
), which "hides" (by squashing) all history between OLDSHA
and the most recent commit on master
. The message for the new commit will be "All my work".
You can then delete master and make temp the new master (before doing this, make sure master has been safely pushed to another repository or backed up)
git branch -d master
git branch -m temp master
And push to a new remote, keeping your old remote intact
git remote rm origin
git remote add origin NEW_URL
git push --set-upstream origin master
You can branch your current work, rewind the master, then cherry-pick the latest commit back to the master:
git branch secret
git reset --hard HEAD~3
git cherry-pick secret
In pictures,
A--B--C--D--E (master)
after git branch secret
:
A--B--C--D--E (master, secret)
after git reset --hard HEAD~3
:
A--B (master) \ C--D--E (secret)
after git cherry-pick secret
:
A--B--E' (master) \ C--D--E (secret)
Finally, if you git checkout secret; git rebase master
, you can get:
A--B--E' (master) \ C--D (secret)
You cloned a project and made a ridiculous amount of commits for a new feature, and the time has come to open source it or share it for review. And you don't want anyone to see your commit mess!
The original branch was cloned_branch
, your messy commits were on dev
branch, and you want to publish your clean work on the public_branch
branch.
cloned_branch
:SHA0: Implemented X, and Y. (author:authorA)
SHA1: Implemented Z. (author:authorA)
SHA2: Implemented W. (author:authorA)
dev
branch and pushed some commits:SHA3: trying to implement Q feature to work..
SHA4: shit, I doesn't work
SHA5: messed up even more! :(
SHA6: GOT IT WORKING!!!!
SHA7: cleanup!
public_branch
:git checkout SHA2 -b public_branch # new branch at `authorA`'s last commit
git merge --squash SHA7 # squash commits up to your last one
git commit -m "Implemented Q (author:me)"
Branches cloned_branch
and dev
remain as before, whilepublic_branch
branch contains:
SHA0: Implemented X, and Y. (author:authorA)
SHA1: Implemented Z. (author:authorA)
SHA2: Implemented W. (author:authorA)
SHA8: Implemented Q. (author:me)