gitworkflow:triangularworkflow

This is an old revision of the document!


Git Triangular Workflow

This git workflow focuses on:

  • Keeping in sync a FreeBSD release branch, e.g. releng/X.Y and not -CURRENT
  • Develop improvements/fixes on top of this release branch and publish them in a personal git repository
  • Once these changes have been tested and have matured enough, up-port them on top of HEAD for review
  • Once review accepted, push them in HEAD
  • Rebase in review/too recent changes from releng/X.Y to releng/X.(Y+1) to keep them relevant for future HEAD inclusion

For experimented git users this is only common sense, but might help you to start FreeBSD contributions with a simple git workflow.

Introduction

This workflow assumes you use multiple repositories, at least:

origin repository:: Our own personal repository with full access, e.g. https://github.com/user/freebsd/

upstream repository:: The official FreeBSD repository with read-only access, e.g. https://github.com/freebsd/freebsd/

  • Main Rules
    • Changes coming from upstream are merged
    • Changes made in origin are rebased

Local Git Repository First Steps

Clone personal FreeBSD git repository

$ git clone git@github.com:user/freebsd.git
$ cd freebsd/

Add FreeBSD upstream as remote repository and fetch changes

$ git remote add upstream git@github.com:freebsd/freebsd.git
$ git fetch upstream
  • Note: git fetch upstream command will take roughly 5/10 minutes depending on our internet connection

Origin Repository Branches

Origin repository branches will look like:

8.3-next/
8.4-next/
10.0-next/
10.1-next/
10.2-next/

The X.Y-next branches are where changes/fixes are added. These branches are created from corresponding upstream release branches releng/X.Y/ from https://github.com/freebsd/freebsd. See below how they are created.

Create a X.Y-next Branch

Get last upstream changes

$ git fetch upstream

Create new X.Y-next branch from corresponding upstream/releng/X.Y release branch

$ git checkout -b 10.2-next upstream/releng/10.2

Publish branch to origin repository

$ git push -u origin 10.2-next

If the X.Y-next is already created in origin repository:

$ git fetch origin
$ git checkout -t origin/10.2-next

Make and Publish Custom Changes

Checkout local work branch and get last remote changes

$ git checkout 10.2-next
$ git pull --rebase

Make source code changes and locally commit them

$ vim foo/bar.c
# Hack, test, hack
$ git add foo/bar.c
$ git commit -m "[bz#42]: Fix this issue"

Once tested, rebase on top of last origin changes if any, and publish yours

$ git pull --rebase
$ git push origin HEAD

Merge Errata/Security Patches from Upstream

  • Note: No Operating System is without sins, thus you need to merge Errata/Security patches from corresponding release branch

Checkout local work branch and get last origin changes

$ git checkout 10.2-next
$ git pull --rebase

Get last upstream changes and check the log for Errata/Security information

$ git fetch upstream
$ git log upstream/releng/10.2

Merge last changes from upstream release branch

$ git merge upstream/releng/10.2 -m "Merge Errata/Security from releng/10.2 into 10.2-next"

Resolve conflicts if any, than check final result

$ git log -p -m --first-parent

Publish merged upstream changes in orign

$ git push origin HEAD

Next you can update FreeBSD release number in release/Makefile and create your private tag for release purpose. See below.

$ git tag -a v10.2.4.0 -m "My FreeBSD Release 10.2.4.0"
$ git push --tags
$ git checkout -t tags/v10.2.4.0

Rebase Custom Changes onto a New Release Branch

Get all origin and upstream repositories changes. For example to rebase changes made in 10.1-next to 10.2-next

$ git fetch upstream
$ git fetch origin
$ git checkout 10.1-next
$ git pull --rebase
$ git checkout 10.2-next
$ git pull --rebase

Start an interactive rebase for all changes made in X.Y to X.(Y+1)

$ git rebase -i --onto 10.2-next upstream/release/10.1.0 10.1-next
  • Note: Rebase is smart enough to skip all already accepted changes the new X.(Y+1)-next branch, i.e. git rebase skips all commit that introduce an exact same change
  • Note: Rebase will skip all Errata/Security merge, this is the default git rebase behaviour and that you actually want as all Errata/Security changes you want are already in X.(Y+1)-next branch by definition of a FreeBSD release branch

During the interactive rebase you have in opportunity to:

  • Remove now irrelevant changes
  • Squash (flatten) changes related to same fix/feature implementation in only one commit:
    • Make things easier for future rebases
    • Make history easier to read
    • Cleaner patch for upstream proposal

This is different workflow than the classical SVN vendor model merge workflow, here we want to see our changes always on top of the last release branch:

  • Custom changes will appear clearly
  • Custom changes will be on top the last release version, and be easier to propose them to upstream, and for future rebases

Advantages/Disadvantages

More Usages examples

Note: You might want sometimes to MFC a change from CURRENT to you X.Y-next branch

Checkout local work branch and get last origin changes

$ git checkout 10.2-next
$ git pull --rebase

Get last upstream changes and check the log for the SHA of the commit(s) to cherry-pick

$ git fetch upstream
$ git log upstream/master
  • Note: One may select any branch from which to cherry pick specific commits.

Cherry-pick changes from upstream/master

$ git cherry-pick $SHA
  • Note: Where $SHA is the SHA string of the commit to cherry-pick

Resolve conflicts and check commit merge diff

$ git log -p

Publish cherry-picked upstream changes to origin repository

$ git pull --rebase
$ git push origin HEAD
  • gitworkflow/triangularworkflow.1442247055.txt.gz
  • Last modified: 2015/09/14 16:10
  • by JulienCharbon