[ell-i-developers] Git best practises #2: Rebasing your changes on the ell-i master

  • From: Pekka Nikander <pekka.nikander@xxxxxx>
  • To: "ell-i-developers@xxxxxxxxxxxxx" <ell-i-developers@xxxxxxxxxxxxx>
  • Date: Tue, 28 Jan 2014 17:51:39 +0200

A reoccurring problem in almost all projects that use git is to handle 
concurrent changes by multiple developers.  After having tried a few different 
ways, I've came to the conclusion is to avoid unintentional merges, favouring 
rebasing.  In this e-mail I try to briefly explain how to do that, and 
especially how to avoid merges at the head of the current development branch.  
To so so, I have to start with some background.

First, consider a situation where two developers, say I and P, are developing 
in parallel.  They are both pushing to a joint remote repository, say E.  Now, 
consider a situation where, starting from the same remote head E1, P has 
created commits P1, P2 and P3 and I commits I1 and I2.  The merge way of 
handling these is to consider the commits really parallel, let the commit tree 
to branch, and then merge the trees, like this:

     P1--P2--P3
    /          \
  E1        +---M1 
    \      /
     I1--I2

While that is fine and something that is needed sometimes, in general, while 
doing new development, it is better to serialise the commits using rebasing.  
For this, the developers needs to *rebase* their commits on the top of others.  
In general, it is a good practise to rebase your local changes on the top of 
the "truth", or the remote repository E.  

Hence, in this example, if P commits first, after his commits the history in E 
looks like this:
  
  E1--P1--P2--P3

Now, instead of being able to push I1 and I2 directly to E, I needs first to 
rebase them on P3.  After the rebase, his local history looks like this:

  E1--P1--P2--P3--I1--I2

He can now trivially push this to the remote repo E, without using force.

There are quite a few good articles in the next explaining this in more detail; 
for example, the following are pretty good and apparently referred to from many 
places:

http://randyfay.com/content/rebase-workflow-git
http://mettadore.com/analysis/a-simple-git-rebase-workflow-explained/
https://sandofsky.com/blog/git-workflow.html
https://blogs.atlassian.com/2013/10/git-team-workflows-merge-or-rebase/

Another thing that is good to know is "git stash", which allows you to 
temporarily store your changes so that you can pop them back with "git stash 
pop".

Now that you have read and understood that all :-), what remains is to set up 
your local repos to use rebasing by default.  That is, once you've configured 
your local repo right, whenever you do a git pull, git will automatically 
rebase your changes on the top of the remote head.

Firstly, you want to make sure that all of your new repos (either cloned or 
inited) will use the rebase workflow.  To so so, you insert the following lines 
to your $HOME/.gitconfig:

[branch]
        autosetuprebase = always

Incidentally, while you are doing that, you may also add the following lines 
there:

[color]
        ui = auto
[push]
        default = tracking

Secondly, you have to add rebasing to the branches in your local repo.  For 
that, you must add a "rebase = true" definition to all branches in your local 
repo.  You can either manually edit your $REPO/.git/config, and make sure that 
the branches look like the following (the example is for the 'master' branch):

[branch "master"]
        remote = origin
        merge = refs/heads/master
        rebase = true

Or, alternatively, you can do this with the git config command:

  $ git branch.<name>.rebase true

Once this is is in place, whenever you do "git pull" pulling the content from 
the remote master, e.g. Ell-i/Runtime.git, your local committed changes will be 
automatically rebased.

--Pekka


Other related posts:

  • » [ell-i-developers] Git best practises #2: Rebasing your changes on the ell-i master - Pekka Nikander