Git Triangular Workflow

The main characteristics of this workflow are:

For experimented git users (i.e. users that already fell in every git pitfalls) this workflow is common sense, but might help some to start FreeBSD contributions with a straightforward workflow.

git-47.png

Introduction

This workflow assumes you use multiple repositories, i.e.:

origin repository

Our own personal/corporate 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 workflow rules being

Changes coming from upstream repository are merged

Changes developed in origin repository are rebased

Local Git Repository First Steps

Clone personal FreeBSD git repository (can be empty at first)

    $ 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/
    master

The X.Y-next branches are where changes/fixes are developed. These branches are created from corresponding upstream release branches releng/X.Y/ from upstream repository. master branch is just CURRENT, and used for review creation. See below how they are created.

Create a `X.Y-next` Branch and Publish it

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

Checkout a `X.Y-next` Branch

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

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

Create `master` Branch and Publish it

Get last upstream changes

    $ git fetch upstream

Create new master branch from corresponding upstream/master CURRENT branch

    $ git checkout -t upstream/master

Publish master branch to origin repository

    $ git push origin HEAD

Make and Publish Custom Changes in Origin Repository

Checkout X.Y-next branch and get last origin changes

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

Make 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/Improve performances"

Once tested, rebase on top of last origin repository changes, and publish

    $ 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 in a timely manner

Checkout X.Y-next 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 details

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

Merge last upstream changes from corresponding 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 the result

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

Publish merged upstream changes in origin

    $ git push origin HEAD

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

Create Tag and Publish it

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

Checkout a Tag

    $ 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 your 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

See https://help.github.com/articles/interactive-rebase documentation

Note

Rebase is smart/dumb enough to skip all already accepted included the new X.(Y+1)-next branch

Note

Rebase will skip all Errata/Security merge commits, this is the default behaviour and that you actually want as all Errata/Security changes are already in X.(Y+1)-next branch by definition of a FreeBSD release branch

During the interactive rebase you have in opportunity to:

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:

Advantages/Disadvantages

Advantages

Disadvantages

More Usages Examples

Creating a Review for `CURRENT` from `X.Y-next` branch

Checkout last changes from upstream/master

    $ git fetch upstream
    $ git checkout master
    $ git pull --rebase

Create review branch

    $ git checkout -b feature-foo-review master
    $ git push -u origin HEAD # It creates the base commit for the review

Cherry-pick changes related to "feature foo" from X.Y-next branch

    $ git log origin/10.2-next # Note SHA strings of desired commits
    $ git cherry-pick $SHA1 $SHA2

    $ arc which # Check that commit $SHA1 and $SHA2 will be part of the review
    $ arc diff --create # Create review D1234

Update your Review

If during review changes are required, local commit the desired changes and include them in the review

    $ vim foo/bar.c
    # Hack, test, hack
    $ git add foo/bar.c
    $ git commit -m "Address comments from review D1234"
    $ arc which # Check that all desired commits are part of the review
    $ arc diff --update D1234 

Rebase your Review on more Recent CURRENT

If the review takes a while, you can rebase your changes on top of the current master and update the review.

First get last upstream changes

    $ git checkout master
    $ git pull --rebase

Then rebase your changes on it

    $ git checkout feature-foo-review
    $ git rebase master

And update the review

    $ git push origin master:feature-foo-review # Update the review base commit
    $ arc which # Check that the review includes all desired commit changes, and only them
    $ arc diff --update D1234

Cherry-pick Specific Commits from Upstream

Checkout X.Y-next 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 desired commit(s) to cherry-pick

    $ git fetch upstream
    $ git log upstream/master

Cherry-pick desired 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 result

    $ git log -p

Publish cherry-picked changes to origin repository

    $ git pull --rebase
    $ git push origin HEAD

GitWorkflow/TriangularWorkflow (last edited 2015-09-14T20:34:30+0000 by JulienCharbon)