Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move branch to another point in history

Tags:

git

branch

We have the following history

start         master  public
|                 |   |
v                 v   v
o---o-- ... --o---o---o

Unfortunately we made some commits into the master branch containing some sensitive data. We amended this in a separate branch called public. Now we want to "cut-off" the public branch in order get a complete and clean "state" in public but without the compromising history parts still contained via master. In other words we want the following new history:

start         master
|                 |
v                 v
o---o-- ... --o---o
 \
  o <- public

Now checking out public shall lead to the same working tree as in the original situation but without the sensible history details. Afterwards we mothball the old master branch: Rename it to unsafe and elaborate a new master branch out of the new public branch. This way we conserve the old history in unsafe and are able to push the public branch into the public without any worries:

start         unsafe
|                 |
v                 v
o---o-- ... --o---o
 \
  o---o-- ... --o <-- public
   \           /
    o-- .. --o-- ... --o <-- master

What are the right git commands to achieve this?

PS: Of course we could checkout start, make a new branch and commit there the entire working tree of the public branch. But there must be a different, fancier, git way!

like image 512
phlipsy Avatar asked Oct 10 '22 03:10

phlipsy


1 Answers

The proper way to merge all commits in public into one commit (i.e. merging several commits to one, or removing individual commits entirely, etc.) is to use git rebase -i. So what you would do is (assuming the first commit has a tag start as your graph indicates):

git checkout public
git rebase -i start

An editor window comes up where you can edit the order of all the patches simply use squash for all your patches. After you saved that file and closed the editor, git will recombine your patch history as requested. Of course, the master branch will not change its history at all.

To rename your current master as unsafe and start all further development on public, I would do:

git checkout -b unsafe master # <- creates a new branch "unsafe"
git checkout master
git reset --hard public    # <- forces master branch to point to public

If you don't create the unsafe branch, the hard reset will loose all commits in master and you won't be able to (easily) access them any more. So make sure you really created that branch.

An alternative would be to rename master to unsafe and then create a new master branch:

git branch -m master unsafe  # renames master to unsafe
git checkout -b master public  # creates new branch master as a copy of public

Both should result in the exact same branch structure. (Granted, the second does not have that danger of loosing the history...)

like image 189
Reinhold Kainhofer Avatar answered Nov 02 '22 14:11

Reinhold Kainhofer