gitworkflow:triangularworkflow

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
gitworkflow:triangularworkflow [2015/09/14 15:31] – JulienCharbongitworkflow:triangularworkflow [2015/09/14 20:34] (current) – JulienCharbon
Line 1: Line 1:
 ====== Git Triangular Workflow ====== ====== Git Triangular Workflow ======
  
-This git workflow focuses on:+The main characteristics of this workflow are:
  
-  * Keeping in sync a %%FreeBSD%% release branch, e.g. releng/X.Y +  * Develop changes on top of %%FreeBSD%% release branch, e.g. ''%%releng/X.Y%%'' 
-  * Develop improvements/fixes on top of this release branch and publish them in a personal git repository +  * Publish these changes in a personal/corporate git repository for testing and use in production 
-  * Once these changes have been tested and matured enough, to up-port them on top of HEAD for review+  * 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   * Once review accepted, push them in HEAD
-  * Rebase not yet accepted/too recent changes from releng/X.Y to releng/X.(Y+1) to keep them relevant for future HEAD inclusion+  * 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 ====== ====== Introduction ======
  
-This workflow assumes you use multiple repositories, at least:+This workflow assumes you use multiple repositories, i.e.:
  
-origin repository:: Our own personal repository with full access, e.g. ''%%https://github.com/user/freebsd/%%''+  * **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/%%''+  * **upstream repository**: The official %%FreeBSD%% repository with read-only access, e.g. ''%%https://github.com/freebsd/freebsd/%%''
  
-===== Local Git Repository Configuration =====+  * **Main workflow rules being** 
 +    * Changes coming from ''%%upstream%%'' repository are merged 
 +    * Changes developed in ''%%origin%%'' repository are rebased
  
-  * **Note**: These steps need to be done only once for a same local git repository+====== Local Git Repository First Steps ======
  
-Clone personal %%FreeBSD%% git repository+Clone personal %%FreeBSD%% git repository (can be empty at first)
  
 +<code>
 $ git clone git@github.com:user/freebsd.git $ git clone git@github.com:user/freebsd.git
 $ cd freebsd/ $ cd freebsd/
 +</code>
  
-Add %%FreeBSD%% upstream as remote and fetch changes+Add %%FreeBSD%% upstream as remote repository and fetch changes
  
 +<code>
 $ git remote add upstream git@github.com:freebsd/freebsd.git $ git remote add upstream git@github.com:freebsd/freebsd.git
 $ git fetch upstream $ git fetch upstream
 +</code>
 +
 +  * **Note**: ''%%$ git fetch upstream%%'' command will take roughly 5/10 minutes depending on our internet connection
  
-  * **Note**: ''%%git fetch upstream%%'' command will take roughly 5/10 minutes of download depending on our internet connection+====== Origin Repository Branches ======
  
-===== Repository Hierarchy =====+Origin repository branches will look like:
  
 <code> <code>
Line 41: Line 53:
 10.1-next/ 10.1-next/
 10.2-next/ 10.2-next/
 +master
 </code> </code>
  
-The ''%%X.Y-next%%'' branches are where changes are added. These branches are created from corresponding upstream branches named ''%%releng/X.Y/%%'' from [[/FreeBSD upstream Git repos|https://github.com/freebsd/freebsd]].  See below.+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.
  
-===== Workflows ===== +====== Create a X.Y-next Branch and Publish it ======
- +
-==== Create Release Branch ====+
  
 Get last upstream changes Get last upstream changes
Line 55: Line 66:
 </code> </code>
  
-Create new ''%%X.Y-next%%'' branch from corresponding ''%%upstream/releng/X.Y%%'' branch+Create new ''%%X.Y-next%%'' branch from corresponding ''%%upstream/releng/X.Y%%'' release branch
  
 <code> <code>
Line 61: Line 72:
 </code> </code>
  
-Publish branch to personal repository+Publish branch to origin repository
  
 <code> <code>
Line 67: Line 78:
 </code> </code>
  
-==== Checkout a X.Y-next Branch ====+===== Checkout a X.Y-next Branch =====
  
-If the ''%%X.Y-next%%'' is already existing:+If the ''%%X.Y-next%%'' is already present in origin repository:
  
 <code> <code>
 $ git fetch origin $ git fetch origin
-$ git checkout -t origin/10.0-next+$ git checkout -t origin/10.2-next
 </code> </code>
  
-  * **Note**: Need to do this step only once per ''%%X.Y-next%%'' branch+====== Create master Branch and Publish it ======
  
-==== Merge Errata/Security Patches from Upstream ====+Get last upstream changes
  
-  * **Note**: Security patches are pushed first in corresponding releng branch+<code> 
 +$ git fetch upstream 
 +</code>
  
-Checkout local work branch and get last remote changes+Create new ''%%master%%'' branch from corresponding ''%%upstream/master%%'' ''%%CURRENT%%'' branch
  
 <code> <code>
-$ git checkout 10.1-next+$ 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 $ git pull --rebase
 </code> </code>
  
-Get last upstream changes and check the log+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> <code>
Line 96: Line 150:
 </code> </code>
  
-Merge last changes from upstream release branch+Merge last upstream changes from corresponding release branch
  
 <code> <code>
-$ git merge upstream/releng/10.2 -m "Merge up to p4 from releng/10.2 into 10.2-next"+$ git merge upstream/releng/10.2 -m "Merge Errata/Security from releng/10.2 into 10.2-next"
 </code> </code>
  
-Resolve conflicts if any and check final result diff+Resolve conflicts if any, than check the result
  
 <code> <code>
Line 108: Line 162:
 </code> </code>
  
-Publish merged upstream changes+Publish merged upstream changes in origin
  
 <code> <code>
Line 114: Line 168:
 </code> </code>
  
-Next you can update %%FreeBSD%% release number in ''%%release/Makefile%%'' and create a tag by following [Create a git tag%%](%%wiki#create-a-git-tag) steps+Next you can update %%FreeBSD%% release number in ''%%release/Makefile%%'' and create your own tag for release/testing purpose.  See below.
  
-==== Create Personal Tag and Publish it ====+===== Create Tag and Publish it =====
  
-$ git tag -a v10.2.4.0 -m "Personal %%FreeBSD%% Release 10.2.4.0"+<code> 
 +$ git tag -a v10.2.4.0 -m "My FreeBSD Release 10.2.4.0"
 $ git push --tags $ git push --tags
 +</code>
  
-%%=%%= Checkout a Personal Private Tag ===+===== Checkout a Tag =====
  
-$ git clone git@github.vrsn.com:freebsd/freebsd-vrsn.git +<code>
-$ cd freebsd-vrsn/+
 $ git checkout -t tags/v10.2.4.0 $ git checkout -t tags/v10.2.4.0
 +</code>
  
-==== Fetch and cherry pick specific commits from 'upstream' ====+====== Rebase Custom Changes onto a New Release Branch ======
  
-Checkout local work branch and get last remote changes+Get all origin and upstream repositories changes.  For example to rebase your changes made in ''%%10.1-next%%'' to ''%%10.2-next%%''
  
 <code> <code>
 +$ git fetch upstream
 +$ git fetch origin
 +$ git checkout 10.1-next
 +$ git pull --rebase
 $ git checkout 10.2-next $ git checkout 10.2-next
 $ git pull --rebase $ git pull --rebase
 </code> </code>
  
-Get last upstream changes and check the log for the SHA of the commit(s) to cherry-pick+Start an interactive rebase for all changes made in ''%%X.Y%%'' to ''%%X.(Y+1)%%''
  
 <code> <code>
-$ git fetch upstream +$ git rebase -i --onto 10.2-next upstream/release/10.1.0 10.1-next
-$ git log upstream/master+
 </code> </code>
  
-  * **Note**: One may select any branch from which to cherry pick specific commits.  In this example, we use 'master' which correlates to the upstream HEAD.+  * **Note**: See [[/Interactive rebase|https://help.github.com/articles/interactive-rebase]] documentation
  
-Cherry-pick changes from ''%%upstream/master%%''+  * **Note**: Rebase is smart/dumb enough to skip all already accepted included the new ''%%X.(Y+1)-next%%'' branch
  
-<code> +  * **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
-$ git cherry-pick $SHA +
-</code>+
  
-  * **Note**: Where $SHA is the SHA string of the commit to cherry-pick+During the interactive rebase you have in opportunity to:
  
-Resolve conflicts and check commit merge diff+  * 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
  
-$ git log -p+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
  
-Publish cherry-picked upstream changes to Verisign sources+====== Advantages/Disadvantages ======
  
-$ git pull --rebase +===== Advantages ===== 
-$ git push origin HEAD+ 
 +  * 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 ======
  
-==== Make and Publish Custom Changes ====+===== Creating a Review for CURRENT from X.Y-next branch =====
  
-Checkout local work branch and get last remote changes+Checkout last changes from ''%%upstream/master%%''
  
 <code> <code>
-$ git checkout 10.2-next+$ git fetch upstream 
 +$ git checkout master
 $ git pull --rebase $ git pull --rebase
 </code> </code>
  
-Make source code changes and locally commit them+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> <code>
Line 177: Line 282:
 # Hack, test, hack # Hack, test, hack
 $ git add foo/bar.c $ git add foo/bar.c
-$ git commit -m "[bz#42]: Fix this issue"+$ 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> </code>
  
-Get last remote changes and publish yours+==== 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> <code>
 +$ git checkout master
 $ git pull --rebase $ git pull --rebase
-$ git push origin HEAD 
 </code> </code>
  
-==== Rebase Custom Changes onto a New Release Branch ====+Then rebase your changes on it
  
-Get personal repository changes.  For example to rebase changes made in 10.1 to 10.2+<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> <code>
-$ git fetch upstream 
-$ git fetch origin 
-$ git checkout 10.1-next 
-$ git pull --rebase 
 $ git checkout 10.2-next $ git checkout 10.2-next
 $ git pull --rebase $ git pull --rebase
 </code> </code>
  
-Start interactive rebase changes made in previous branch on top of the new one+Get last upstream changes and check the log for the SHA of the desired commit(s) to cherry-pick
  
 <code> <code>
-$ git rebase -i --onto 10.1-next upstream/release/10.0.0 10.0-next+$ git fetch upstream 
 +$ git log upstream/master
 </code> </code>
  
-  * **Note**: [[/Interactive rebase|https://help.github.com/articles/interactive-rebase]] documentation+Cherry-pick desired changes from ''%%upstream/master%%''
  
-During the interactive rebase you have in opportunity to: +<code> 
-  * Remove already accepted in upstream changes +$ git cherry-pick SHA 
-  * Remove now irrelevant changes +</code>
-  * 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 to propose uptream+
  
-This is different from classical SVN vendor model merge workflow, here we want our changes always on top of the last release: +  * **Note**: Where SHA is the SHA string of the commit to cherry-pick 
-  * Custom changes will appear atomic + 
-  * Custom changes will be on top the last release version: Easier to propose them to upstream, and for future rebases+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.1442244699.txt.gz
  • Last modified: 2015/09/14 15:31
  • by JulienCharbon