Bogdan Alexandru
Bogdan Alexandru

Reputation: 5542

Rebase instead of fast forward

I'm new to GIT and I can't figure out if my question already has an answer. Please read it carefully before marking it as duplicate.

I have a branch, let's call it public, which is pushed and in sync with origin. At one point, I create another branch, private, which pops out of public, because I want to do a lot of work which I want to remain secret. So I only work on private and I do, let's say, 10 commits, until I finally arrive to a state which can be made public.

Now, I obviously don't want to do a fast-forward merge of public because all the intermediary commits would appear on the remote server. How can I do a rebase given that the public branch has not diverged from the point where private was created.

Clearly, I want to create a new commit on the public branch that contains all the modifications from the 10 private commits. I know that translates into a rebase, but I don't know how to do it.

Upvotes: 4

Views: 2005

Answers (3)

Gauthier
Gauthier

Reputation: 41945

To be exact, creating a new commit on public that contains the modifications from private does not call for rebase. It calls for merge.

Rebasing to squash together the commits of private before seems to be what you want, you keep a branch and a merge commit.

However since you don't care about the detailed history of your private branch, you could just as well:

$ git checkout public
$ git merge --squash private
$ git commit

The index is first updated with the content of private, and you can make a single commit of it on top of public.

Upvotes: 3

merlin2011
merlin2011

Reputation: 75545

First of all, the fact that public is tracking a remote branch that lives on origin does not mean that the local branch public is equivalent to the remote branch origin/public.

Because of git's distributed nature, you can make a bunch of commits on your local public branch without anything making it to the server, as long as you do not push.

With respect to what you are trying to do given the current state of your system, here are some detailed steps, assuming you do not care about keeping your original 10 commits.

  1. Begin interactive rebase against the current state of the remote server.

    git checkout private
    git rebase -i origin/public
    
  2. An editor will pop up. The specific editor will depend on the platform and the environmental variable settings. Inside this editor, you will see the hashes of your 10 commits, with the word "pick" in the left hand column. For the first row, keep pick. For the subsequent rows, replace pick with squash. Save the file and quit the editor.

  3. At this point, git will have merged the 10 commits into a single commit, so we can merge into public and push.

    git checkout public
    git merge private
    git push
    

If you wanted to keep your original 10 commits on the local private branch, you can instead do a fast-forward merge onto the local public branch and rebase there instead.

git checkout public
git merge private
git rebase -i origin/public
# Do the same rebase steps as above
git push

Upvotes: 7

Preuk
Preuk

Reputation: 632

use git rebase -iand select squashfor your 10 commits so you'll only have one big commit rebased on your public branch.

When using -i with rebase, you'll get a text editor where you can choose how each commit will be rebased (or if it will berebased at all). Squash is the option that allow you to integrate multiple commits in a single one with this kind of syntax (from github doc, link below) :

pick 1fc6c95 Patch A
pick 6b2481b Patch B
squash dd1475d something I want to split
squash c619268 A fix for Patch B
squash fa39187 something to add to patch A
squash 4ca2acc i cant' typ goods
squash 7b36971 something to move before patch B

This will rebase 2 commits : "Patch A" will be verbatim will "Patch B" will include the changes from the next "squashed" commits.

Please see "Interactive Rebasing" in reference or the nice github doc page for details.

Upvotes: 5

Related Questions