Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Git Triangular Workflow ====== The main characteristics of this workflow are: * Develop changes on top of %%FreeBSD%% release branch, e.g. ''%%releng/X.Y%%'' * Publish these changes in a personal/corporate git repository for testing and use in production * 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 changes that have not yet been accepted to old ''%%releng/X.Y%%'' branch to new ''%%releng/X.(Y+1)%%'' branch 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. {{gitworkflow/triangularworkflow/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) <code> $ git clone git@github.com:user/freebsd.git $ cd freebsd/ </code> Add %%FreeBSD%% upstream as remote repository and fetch changes <code> $ git remote add upstream git@github.com:freebsd/freebsd.git $ git fetch upstream </code> * **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: <code> 8.3-next/ 8.4-next/ 10.0-next/ 10.1-next/ 10.2-next/ master </code> 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 <code> $ git fetch upstream </code> Create new ''%%X.Y-next%%'' branch from corresponding ''%%upstream/releng/X.Y%%'' release branch <code> $ git checkout -b 10.2-next upstream/releng/10.2 </code> Publish branch to origin repository <code> $ git push -u origin 10.2-next </code> ===== Checkout a X.Y-next Branch ===== If the ''%%X.Y-next%%'' is already present in origin repository: <code> $ git fetch origin $ git checkout -t origin/10.2-next </code> ====== Create master Branch and Publish it ====== Get last upstream changes <code> $ git fetch upstream </code> Create new ''%%master%%'' branch from corresponding ''%%upstream/master%%'' ''%%CURRENT%%'' branch <code> $ git checkout -t upstream/master </code> Publish ''%%master%%'' branch to origin repository <code> $ git push origin HEAD </code> ====== Make and Publish Custom Changes in Origin Repository ====== Checkout ''%%X.Y-next%%'' branch and get last origin changes <code> $ git checkout 10.2-next $ git pull --rebase </code> Make changes and locally commit them <code> $ vim foo/bar.c # Hack, test, hack $ git add foo/bar.c $ git commit -m "[bz#42]: Fix this issue/Improve performances" </code> Once tested, rebase on top of last origin repository changes, and publish <code> $ git pull --rebase $ git push origin HEAD </code> ====== 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 <code> $ git checkout 10.2-next $ git pull --rebase </code> Get last upstream changes and check the log for Errata/Security details <code> $ git fetch upstream $ git log upstream/releng/10.2 </code> Merge last upstream changes from corresponding release branch <code> $ git merge upstream/releng/10.2 -m "Merge Errata/Security from releng/10.2 into 10.2-next" </code> Resolve conflicts if any, than check the result <code> $ git log -p -m --first-parent </code> Publish merged upstream changes in origin <code> $ git push origin HEAD </code> 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 ===== <code> $ git tag -a v10.2.4.0 -m "My FreeBSD Release 10.2.4.0" $ git push --tags </code> ===== Checkout a Tag ===== <code> $ git checkout -t tags/v10.2.4.0 </code> ====== 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%%'' <code> $ git fetch upstream $ git fetch origin $ git checkout 10.1-next $ git pull --rebase $ git checkout 10.2-next $ git pull --rebase </code> Start an interactive rebase for all changes made in ''%%X.Y%%'' to ''%%X.(Y+1)%%'' <code> $ git rebase -i --onto 10.2-next upstream/release/10.1.0 10.1-next </code> * **Note**: See [[/Interactive rebase|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: * Remove now irrelevant changes * Squash 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 * Re-order your changes 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 ====== Advantages/Disadvantages ====== ===== Advantages ===== * Use of last release branch for stability * Custom changes/fixed are used/tested in production before review * No need to wait upstream acceptation before enjoying fixes and improvements * These changes make great candidates for MFC (Merge From Current) once accepted in CURRENT * Keep patches clean over new release branches * The origin repository includes only the branches you are working on/you care about. It is not a full complete fork of the upstream repository * Interface nicely with %%FreeBSD%% reviews (Phabricator/arc) (see below) ===== Disadvantages ===== * Development is not done in CURRENT * Patches are “up-ported” to CURRENT once tested/have matured enough * Patches are in two branches until accepted: * ''%%X.Y-next%%'' (Release branch) * ''%%feature-review%%'' (Branch for upstream review) (see below) ====== More Usages Examples ====== ===== Creating a Review for CURRENT from X.Y-next branch ===== Checkout last changes from ''%%upstream/master%%'' <code> $ git fetch upstream $ git checkout master $ git pull --rebase </code> Create review branch <code> $ git checkout -b feature-foo-review master $ git push -u origin HEAD # It creates the base commit for the review </code> Cherry-pick changes related to "feature foo" from ''%%X.Y-next%%'' branch <code> $ git log origin/10.2-next # Note SHA strings of desired commits $ git cherry-pick $SHA1 $SHA2 </code> and create the review <code> $ arc which # Check that commit $SHA1 and $SHA2 will be part of the review $ arc diff --create # Create review D1234 </code> ==== Update your Review ==== If during review changes are required, local commit the desired changes and include them in the review <code> $ 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 </code> ==== 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 <code> $ git checkout master $ git pull --rebase </code> Then rebase your changes on it <code> $ git checkout feature-foo-review $ git rebase master </code> And update the review <code> $ 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 </code> ===== Cherry-pick Specific Commits from Upstream ===== Note: Sometimes You might want to get a change from ''%%CURRENT%%'' to your ''%%X.Y-next%%'' branch Checkout ''%%X.Y-next%%'' branch and get last origin changes <code> $ git checkout 10.2-next $ git pull --rebase </code> Get last upstream changes and check the log for the SHA of the desired commit(s) to cherry-pick <code> $ git fetch upstream $ git log upstream/master </code> Cherry-pick desired changes from ''%%upstream/master%%'' <code> $ git cherry-pick SHA </code> * **Note**: Where SHA is the SHA string of the commit to cherry-pick Resolve conflicts and check result <code> $ git log -p </code> Publish cherry-picked changes to origin repository <code> $ git pull --rebase $ git push origin HEAD </code> gitworkflow/triangularworkflow.txt Last modified: 2015/09/14 20:34by JulienCharbon