wiki:GitCreateBundle

Version 2 (modified by Piero Campalani, 13 years ago) ( diff )

fixes

Back to [ProvideFix How To Provide A Fix].

Why git bundles

Currently, the repo is folded into different public branches, letting a contributor choose on which of these branch his new patch is meant to be applied (see here for details).

This wiki page is meant for developers who need to reflect a merge operations to the public repo: indeed a solution which provides both un-linearized history and submission to the [patchmanagaer patch manager] is to submit a bundle.

This allows no behind-the-scenes merge operations, and at the same time reflects the actual merge in the history of the repo, which otherwise won't be visible with patches:

  • REPO STATUS BEFORE MERGE :
      o-------A------B   master
               \           
                C-------D   feature_X
    
  • REPO STATUS AFTER MERGING BUNDLE :
      o-------A------B------M   master
               \           /
                C---------D   feature_X
    
  • REPO STATUS AFTER MERGING PATCH :
      o-------A------B------P   master
               \          
                C---------D   feature_X
    

Although git bundles are pretty powerful, that is they can add commits, merge branches, etc. It is important here to follow some rules when submitting a bundle, which mainly are:

  • HONESTY:
    Each patch must be associated to a ticket (see [StandardsAndGuideLines guidelines]), hence a git bundle should only perform the merge of two branches: no new "patches" should be stacked in, in none of the two branches (number of refs in the bundle will be checked anyway by the patch manager);
  • NAMING CONVENTIONS
    • the name of the merging commit must follow the naming convention "Merge branch 'feature_X' into master", so actually leave the default title that git sets;
    • the name of the bundle file must follow the pattern "ticket:NNN_descriptionOfMerge.bundle", referring to the ticket which justifies the merge.

Creating and submitting a bundle

When it's time to merge a branch which is publicly available, the situation can be very painful, but this is ​another story.

First of all, the status of the two branches to be merged must be the _exactly_ the same before starting to merge. In this case, we can imagine we want to merge feature_X into master:

  o-------A-------B  master
           \
            D-------E  feature_X

Going to the terminal, this means:

$ git fetch origin
$ # already up-to-date? otherwise pull new changes on both branches.

$ git branch
  feature_X
* master
  release_8.4
  release_8.5
$ git merge feature_X --no-ff
$ # In case of "Automatic merge failed; fix conflicts and then commit the result.", then see you later.

$ # Check:
$ git log --oneline -1 master
3f36d7f Merge branch 'feature_X' into master

After the merge, the situation (locally) is then:

  o-------A--------------M  master
           \            /
            C----------D  feature_X

To publish this on the public repo you can create the bundle, but first (again) remember that:

  • local snapshot of two branches must exactly be synchronized with that of the public repo;
  • consequently, the names of the merging branches must be the same as well (developers tend to open new branches for local development...).

If all is fine, create the bundle:

  • Synopsis:
    $ git bundle create <bundle_name> <branch_name> <refs>
    
  • Example:
    # A graph view first:
    $ git log master --graph -4
    *   commit 3f36d7f1a19c3e4cfeab66807dd39f6d7fda771b
    |\  Merge: 5ee465b f7ed86b
    | | Author: Willie The Merger <w.merger@jacobs-university.de>
    | | Date:   Tue Oct 15 12:37:53 2013 +0200
    | | 
    | |     Merge branch 'feature_X' into master
    | |   
    | * commit f7ed86b6eba15e141202b44279d7f7afa4484944
    | | Author: Jack Shortie <j.shortie@jacobs-university.de>
    | | Date:   Tue Oct 8 12:34:54 2013 +0200
    | | 
    | |     D
    | |   
    | * commit 79e8805fe4b4ba2502be9c0e4b312b8b97e739b9
    |/  Author: Johnnie Cannuccia <j.cnnuccia@acme.org>
    |   Date:   Tue Oct 8 12:21:58 2013 +0200
    |   
    |       C
    |  
    * commit 5ee465b1ca5306590dce61e97acb97f1e88aa3c1
    | Author: Piero Campalani <p.campalani@jacobs-university.de>
    | Date:   Thu Aug 8 14:24:32 2013 +0200
    | 
    |     A
    
    
    $ # Verify which HEADs will go into the bundle
    $ git log master ^5ee465 --oneline
    3f36d7f Merge branch 'ProvaMerge' into ProvaMergeMaster
    f7ed86b D
    79e8805 C
    
    $ # Create the bundle
    $ git bundle create ticket:XYZ_MergingFeature_xOnMaster.bundle master ^5ee465
    Counting objects: 14, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (9/9), done.
    Writing objects: 100% (9/9), 838 bytes, done.
    Total 9 (delta 8), reused 0 (delta 0)
    
    $ # See inside it:
    $ git list-heads ticket:XYZ_MergingFeature_xOnMaster.bundle
    3f36d7f1a19c3e4cfeab66807dd39f6d7fda771b refs/heads/master
    

Verifying the bundle

In case you need to locally verify that you produced a good bundle, you can create a new local repo and test it:

$ # Create/init new empty repo
$ echo `pwd`
/home/rasdaman/rasdaman
$ mkdir ~/test_repo
$ cd ~/test_repo
$ git init

$ # push two branches to the test repo
$ cd /home/rasdaman/rasdaman
$ git remote add test_remote ~/test_repo
$ git push test_remote master
$ git push test_remote feature_X

$ # Now move to the test repo
$ cd ~/test_repo
$ git branch
  feature_X
* master

$ # check out on a branch you're not merging into:
$ git checkout feature_x
$ git branch
* feature_X
  master

# Apply the bundle: [verify &] apply
$ git bundle verify /path/to/ticket:XYZ_MergingFeature_xOnMaster.bundle
$ git fetch /path/to/ticket:XYZ_MergingFeature_xOnMaster.bundle master:master

Further reading

Note: See TracWiki for help on using the wiki.