Public:Git tips

From YaddaWiki

Revision as of 17:04, 16 November 2015 by Mkobos (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Case with multiple branch pointers pointing at different parts of a common linear history

Incorporating changes from a separate branch

Before. We have a history like this:

         b1    b2
         |     |
         \/    \/
a--b--c--d--e--f
    \-g--h
         /\
         |
         b3

Where:

  • There's a fork in history after commit b.
  • Branch pointer b1 points at commit d, b2 points at commit f, branch b3 points at commit h.

After. We want the history to look like this:

                b1      b2
                |       |
                \/      \/
a--b--g--h--c'--d'--e'--f'
         /\
         |
          b3

That is, we want to cut out commits c--d--e--f and put them on the top of commit h.

The backstory. Where all these branches came from? That branch b3 was under public code review while we were independently privately working on functionalities in b1 and after that was done, we were working in the same way on functionalities based on that in branch b2.

What we want to do. We want to incorporate changes from branch b3 to the code in the second arm of the forked history - the one with branch pointers b1 and b2. We want to keep the history linear and keep the public history intact (i.e. branch b3 points at the tip of the history tree that is public).

Technical details. In order to do it, execute:

  • git checkout b2
  • git rebase b3
  • resolve merge conflicts in all conflicting commits and make sure that the tests run properly

This results in the following commit tree:

         b1             b2
         |              |
         \/             \/
a--b--c--d
    \-g--h--c'--d'--e'--f'
         /\
         |
         b3

Now we need to move branch pointer b1 to commit d'. This action will also automatically delete the old branch. This is done by executing:

  • git branch -f b1 d'

This results in the desired commit history.

Changing initial history

Before. We have a history like this:

         b1    b2    b3
         |     |     |
         \/    \/    \/
a--b--c--d--e--f--g--h

Where:

  • Branch b1 points at commit d, b2 points at commit f, branch b3 points at commit h.

After. We want the history to look like this:

   b1     b2      b3
   |      |       |
   \/     \/      \/
a--i--e'--f'--g'--h'

Where:

  • commit i is a commit that was created by squashing commits b, c, d.

The backstory. Where all these branches came from? The branch b1 was under a public code review while branches b2 and b3 were consecutively created based on previous branch. Now we want to squash commits b, c, d from the code review into a single commit before rebasing branch b1 onto master branch.

What we want to do. We want to change some old history of commits at the beginning of the shown history. To be more precise, we want to squash commits b, c, d.

Technical details. In order to do it, execute:

  • git checkout b3
  • git rebase -i a
  • during the interactive rebase session squash commits b, c, d

This results in the following commit tree:

         b1    b2
         |     |
         \/    \/
a--b--c--d--e--f
 \-i--e'--f'--g'--h'
                  /\
                  |
                  b3

The next step is to move branch pointers b1 and b2 to the other arm of the forked history:

  • git branch -f b2 f'
  • git branch -f b1 i'

This results in the desired commit history.

Moving part of the history to another branch

We want to cut off top part of one branch and attach it at the top of another branch. Namely:

before the change we have:

            b1
            |
            \/
a--b--c--d--e
    \-f--g--h--i--j
            /\    /\
            |     |
            b2    b3

while after the change we have:

            b1     b3
            |      |
            \/     \/
a--b--c--d--e--i'--j'
    \-f--g--h
            /\ 
            | 
            b2

In order to do it, execute:

  • git rebase --onto b1 b2 b3, where:
    • b1 is the destination branch pointer (or commit hash)
    • b2 is the cut point - the history will be cut after this branch pointer (or commit hash)
    • b3 is the tip of the moved history line.
Personal tools