Changes between Version 43 and Version 44 of StartModMaint


Ignore:
Timestamp:
Dec 22, 2013, 4:24:08 PM (9 years ago)
Author:
Beman Dawes
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • StartModMaint

    v43 v44  
    3838The {{{git submodule update}}} may switch submodules back to the detached state, depending on the working copy's exact situation.
    3939
    40 The following table, based on actual tests run using git version 1.8.4.msysgit.0, shows the effects on a submodule of the above commands.
     40See {wiki:#Effectsofgitsubmoduleupdate Effects of {{{git submodule update}}}] for details.
     41
     42To get more information about a submodule:
     43
     44{{{
     45cd modular-boost
     46git submodule summary
     47}}}
     48
     49If for some reason you wanted to test against the current head of {{{master}}} for all libraries, disregarding the super-project state, the {{{git submodule update}}} command would be changed to:
     50
     51{{{
     52git submodule foreach --recursive "git checkout master; git pull"
     53}}}
     54
     55=== Check out the development branch of your library ===
     56
     57You can see what branch {{{mylib}}} is currently on like this:
     58
     59{{{
     60cd modular-boost/libs/mylib
     61git branch
     62}}}
     63
     64Then if you need to change the branch to a development branch such as {{{develop}}}, do this:
     65
     66{{{
     67cd modular-boost/libs/mylib
     68git checkout develop
     69}}}
     70
     71You only have to do that once; your local repo working copy will sit on the branch until it is explicitly changed by a command you give.
     72
     73  Of course, you don't have to change the directory before every command, and from here on this tutorial will assume the directory has not been changed since the prior example.
     74
     75If there is any possibility the branch head content in the public upstream repo has changed, you also will want to update content:
     76
     77{{{
     78cd modular-boost/libs/mylib
     79git pull
     80}}}
     81
     82From this point on, it is assumed you have already done a {{{cd modular-boost/libs/mylib}}}.
     83
     84=== Testing locally ===
     85
     86Unless you are 100% sure of the state of your library's regression tests, it is a good idea to run the regression tests before making any changes to the library:
     87
     88{{{
     89pushd test
     90b2
     91popd
     92}}}
     93
     94=== Checking status  ===
     95
     96Before making changes, it is a good idea to check status. Here is what that looks like on Windows; the
     97message you get may vary somewhat:
     98
     99{{{
     100>git status
     101# On branch develop
     102nothing to commit, working directory clean
     103}}}
     104
     105=== Fix a simple bug directly on {{{develop}}} ===
     106
     107For simple bugs, particularly in projects with a single maintainer, it is common practice to fix bugs directly in the {{{develop}}} branch. Creating a test case with your favorite editor, testing the test case, fixing the bug, testing the fix, and then iterating if necessary is no different than with any programming environment.
     108
     109Once the fix is complete, you then commit the fix locally and push from your local repo up to your public boostorg repo on GitHub. These same commands would be used for any Git project, modular or not, so hopefully you are already somewhat familiar with them:
     110
     111{{{
     112cd modular-boost/libs/mylib
     113git commit -a -m "my bug fix"
     114git push
     115}}}
     116
     117There are some significant disadvantages to this simple approach:
     118* The fix is now made to {{{develop}}} but you must remember to merge it to a release branch or directly to {{{master}}}. It is very easy to forget to do that merge, particularly if this is a mature library you are not working with very often.
     119* Users who need the bug fix right away are forced to jump through hoops to retrieve the fix from {{{develop}}}.
     120
     121Putting out a point release solves both of those problems. Read on...
     122
     123=== Fix a bug using a hot-fix branch ===
     124
     125Fixing a bug directly on the {{{develop}}} branch is fine, if that's the library's policy, but if the bug is messy, multiple maintainers are involved, interruptions are expected, or other complexities are present, then it is better practice to work on the bug in a separate branch. And doing that on a hot-fix branch solves the problems mentioned at the end of the prior section.
     126
     127The operational distinction between a bug-fix branch and a hot-fix branch is that a bug-fix branch is branched from {{{develop}}} and then at completion merged back to {{{develop}}}, while a hot-fix branch is branched from {{{master}}} and then at completion is merged to both {{{master}}} and {{{develop}}}. With either approach, the branch is deleted after it has been merged.
     128
     129{{{
     130git checkout master
     131git checkout -b hotfix/complex-boo-boo
     132}}}
     133
     134This creates the branch {{{hotfix/complex-boo-boo}}}, and switches to it. Incidentally, {{{hotfix/}}} is part of the name, not a directory specifier. The new branch is based on branch {{{master}}} because the working copy was on branch {{{master}}} at the time of the branch.
     135
     136Since the bug is complex, it may take some time to fix and may go through several cycles of fixes, tests, and commits.
     137
     138Once the bug is fixed and a final commit is done, then it is time to merge the {{{hotfix/complex-boo-boo}}} branch into {{{master}}} and {{{develop}}}:
     139
     140{{{
     141git checkout master
     142git merge hotfix/complex-boo-boo
     143git push
     144git checkout develop
     145git merge hotfix/complex-boo-boo
     146git push
     147git branch -d hotfix/complex-boo-boo
     148}}}
     149
     150=== Start work on a new feature ===
     151
     152Developers are encouraged to create a (possibly private) branch to work on new features, even simple ones, since development of new features on the {{{develop}}} branch might leave it unstable for longer that expected. Using the Git Flow convention, the branch will be named {{{feature/add-checksum-option}}}.
     153
     154{{{
     155git checkout develop
     156git checkout -b feature/add-checksum-option
     157}}}
     158
     159When you create the branch, or perhaps later, you may decide the branch should be public (i.e. be present in the library's public boostorg repo) so that you can share the branch with others or just to back it up. If so, set that up by running:
     160
     161{{{
     162git push --set-upstream origin feature/add-checksum-option
     163}}}
     164
     165 Whether or not {{{--set-upstream origin bugfix/complex-boo-boo}}} is actually needed depends on the {{{branch.autosetupmerge}}} configuration variable that isn't discussed here. If you don't supply {{{--set-upstream origin bugfix/complex-boo-boo}}} on your first {{{push}}} and it turns out to be needed, you will get an error message explaining that.
     166
     167
     168The usual cycle of coding, testing, commits, and pushes (if public) then begins. If other work needs to be done, a {{{stash}}} or {{{commit}}} may be done to save work-in-progress, and the working copy switched to another branch for awhile. If significant fixes or other enhancements have been made to {{{develop}}} over time, it may be useful to merge {{{develop}}} into the feature branch so that the eventual merge back to {{{develop}}} has less conflicts. Here is how the merge from {{{develop}}} to {{{feature/add-checksum-option}}} is done:
     169
     170{{{
     171git checkout feature/add-checksum-option
     172git merge develop
     173}}}
     174
     175== First post-svn conversion merge to {{{master}}} ==
     176
     177When you are ready to merge the {{{develop}}} branch to {{{master}}} (or better yet a release branch that's branched off {{{master}}}), there's a bit of housekeeping to be done the first time after the conversion from svn so that future merges proceed smoothly.  We're going to create a merge point between
     178the develop and master branches so that Git knows the last point the two branches were in synch.  Once we've done that Git will perform a merge by replaying the commits on develop on top of master, starting from the last known merge: in other words Git will perform the tricky stuff of figuring out what to merge for us.
     179
     180* Navigate to the history for your library on !GitHub, starting with branch master. For example the Config library [https://github.com/boostorg/config/commits/master can be seen here].
     181* Look down through the commit history and make a note of the last merge in svn land. In our example, it was on October 25th 2013.
     182* Use the dropdown box to change the history to point to the develop branch. [https://github.com/boostorg/config/commits/develop Config library can be seen here].
     183* Find the last commit '''before the date noted above'''. Click on the commit message for that commit to go to the actual diff for that change, [https://github.com/boostorg/config/commit/67f6b934f161dc5da2039004986a14d9217afae4 in our example here].  The SHA1 for that commit is shown below and to the right of the commit message, in this case it's {{{67f6b934f161dc5da2039004986a14d9217afae4}}}. Copy that SHA1 to your clipboard.
     184
     185Create a merge to that specific commit. Begin by changing your library to the master branch:
     186
     187{{{
     188git checkout master
     189}}}
     190
     191Now create a merge to the specific commit above; since we don't really want to actually change the master branch we'll use the {{{-s ours}}} option to avoid any conflicts:
     192
     193{{{
     194git merge --no-ff --no-commit -s ours 67f6b934f161dc5da2039004986a14d9217afae4
     195}}}
     196
     197You can now use {{{git status}}} and {{{git diff}}} to check for modifications, in this case there are none. Now make the commit and push to !GitHub:
     198
     199{{{
     200git commit -am "Create first merge point for Git"
     201git push
     202}}}
     203
     204Then navigate to your libraries history again, and check that the merge shows up, [https://github.com/boostorg/config/commits/master our config example is here].
     205You're now ready for "routine" merges to proceed as per Git Flow (or whatever other strategy you wish to use).
     206
     207=== Lightweight library release ===
     208
     209Small, simple libraries and simple releases just merge {{{develop}}} into {{{master}}}, tag {{{master}}}, and declare victory.
     210
     211{{{
     212git checkout master
     213git merge --no-ff develop
     214git tag -a 1.56.1
     215}}}
     216
     217=== Heavyweight library release ===
     218
     219Large, complex libraries, particularly those with multiple developers working in parallel, need to use a release procedure that scales up better than the lightweight procedure. The Git Flow approach is recommended. Find out more at [wiki:StartModWorkflow Modular Boost Library Workflow Overview] and be sure to study the examples given in [http://nvie.com/posts/a-successful-git-branching-model/ Vincent Driessen's original blog posting].
     220
     221== Effects of {{{git submodule update}}}==
     222
     223The following table, based on actual tests run using git version 1.8.4.msysgit.0, shows the effects on a submodule of:
     224
     225{{{
     226cd modular-boost
     227git checkout master
     228git pull
     229git submodule update
     230}}}
    41231
    42232|| '''Submodule Branch''' || '''Submodule Contents''' || '''Submodule relative to super-project''' || '''Effects on Submodule''' ||
     
    60250|| {{{develop}}} || Committed change || Behind || {{{git checkout --detach; git pull}}} ||
    61251
    62 To get more information about submodules:
    63 
    64 {{{
    65 cd modular-boost
    66 git submodule summary
    67 }}}
    68 
    69 If for some reason you wanted to test against the current head of {{{master}}} for all libraries, disregarding the super-project state, the {{{git submodule update}}} command would be changed to:
    70 
    71 {{{
    72 git submodule foreach --recursive "git checkout master; git pull"
    73 }}}
    74 
    75 === Check out the development branch of your library ===
    76 
    77 You can see what branch {{{mylib}}} is currently on like this:
    78 
    79 {{{
    80 cd modular-boost/libs/mylib
    81 git branch
    82 }}}
    83 
    84 Then if you need to change the branch to a development branch such as {{{develop}}}, do this:
    85 
    86 {{{
    87 cd modular-boost/libs/mylib
    88 git checkout develop
    89 }}}
    90 
    91 You only have to do that once; your local repo working copy will sit on the branch until it is explicitly changed by a command you give.
    92 
    93   Of course, you don't have to change the directory before every command, and from here on this tutorial will assume the directory has not been changed since the prior example.
    94 
    95 If there is any possibility the branch head content in the public upstream repo has changed, you also will want to update content:
    96 
    97 {{{
    98 cd modular-boost/libs/mylib
    99 git pull
    100 }}}
    101 
    102 From this point on, it is assumed you have already done a {{{cd modular-boost/libs/mylib}}}.
    103 
    104 === Testing locally ===
    105 
    106 Unless you are 100% sure of the state of your library's regression tests, it is a good idea to run the regression tests before making any changes to the library:
    107 
    108 {{{
    109 pushd test
    110 b2
    111 popd
    112 }}}
    113 
    114 === Checking status  ===
    115 
    116 Before making changes, it is a good idea to check status. Here is what that looks like on Windows; the
    117 message you get may vary somewhat:
    118 
    119 {{{
    120 >git status
    121 # On branch develop
    122 nothing to commit, working directory clean
    123 }}}
    124 
    125 === Fix a simple bug directly on {{{develop}}} ===
    126 
    127 For simple bugs, particularly in projects with a single maintainer, it is common practice to fix bugs directly in the {{{develop}}} branch. Creating a test case with your favorite editor, testing the test case, fixing the bug, testing the fix, and then iterating if necessary is no different than with any programming environment.
    128 
    129 Once the fix is complete, you then commit the fix locally and push from your local repo up to your public boostorg repo on GitHub. These same commands would be used for any Git project, modular or not, so hopefully you are already somewhat familiar with them:
    130 
    131 {{{
    132 cd modular-boost/libs/mylib
    133 git commit -a -m "my bug fix"
    134 git push
    135 }}}
    136 
    137 There are some significant disadvantages to this simple approach:
    138 * The fix is now made to {{{develop}}} but you must remember to merge it to a release branch or directly to {{{master}}}. It is very easy to forget to do that merge, particularly if this is a mature library you are not working with very often.
    139 * Users who need the bug fix right away are forced to jump through hoops to retrieve the fix from {{{develop}}}.
    140 
    141 Putting out a point release solves both of those problems. Read on...
    142 
    143 === Fix a bug using a hot-fix branch ===
    144 
    145 Fixing a bug directly on the {{{develop}}} branch is fine, if that's the library's policy, but if the bug is messy, multiple maintainers are involved, interruptions are expected, or other complexities are present, then it is better practice to work on the bug in a separate branch. And doing that on a hot-fix branch solves the problems mentioned at the end of the prior section.
    146 
    147 The operational distinction between a bug-fix branch and a hot-fix branch is that a bug-fix branch is branched from {{{develop}}} and then at completion merged back to {{{develop}}}, while a hot-fix branch is branched from {{{master}}} and then at completion is merged to both {{{master}}} and {{{develop}}}. With either approach, the branch is deleted after it has been merged.
    148 
    149 {{{
    150 git checkout master
    151 git checkout -b hotfix/complex-boo-boo
    152 }}}
    153 
    154 This creates the branch {{{hotfix/complex-boo-boo}}}, and switches to it. Incidentally, {{{hotfix/}}} is part of the name, not a directory specifier. The new branch is based on branch {{{master}}} because the working copy was on branch {{{master}}} at the time of the branch.
    155 
    156 Since the bug is complex, it may take some time to fix and may go through several cycles of fixes, tests, and commits.
    157 
    158 Once the bug is fixed and a final commit is done, then it is time to merge the {{{hotfix/complex-boo-boo}}} branch into {{{master}}} and {{{develop}}}:
    159 
    160 {{{
    161 git checkout master
    162 git merge hotfix/complex-boo-boo
    163 git push
    164 git checkout develop
    165 git merge hotfix/complex-boo-boo
    166 git push
    167 git branch -d hotfix/complex-boo-boo
    168 }}}
    169 
    170 === Start work on a new feature ===
    171 
    172 Developers are encouraged to create a (possibly private) branch to work on new features, even simple ones, since development of new features on the {{{develop}}} branch might leave it unstable for longer that expected. Using the Git Flow convention, the branch will be named {{{feature/add-checksum-option}}}.
    173 
    174 {{{
    175 git checkout develop
    176 git checkout -b feature/add-checksum-option
    177 }}}
    178 
    179 When you create the branch, or perhaps later, you may decide the branch should be public (i.e. be present in the library's public boostorg repo) so that you can share the branch with others or just to back it up. If so, set that up by running:
    180 
    181 {{{
    182 git push --set-upstream origin feature/add-checksum-option
    183 }}}
    184 
    185  Whether or not {{{--set-upstream origin bugfix/complex-boo-boo}}} is actually needed depends on the {{{branch.autosetupmerge}}} configuration variable that isn't discussed here. If you don't supply {{{--set-upstream origin bugfix/complex-boo-boo}}} on your first {{{push}}} and it turns out to be needed, you will get an error message explaining that.
    186 
    187 
    188 The usual cycle of coding, testing, commits, and pushes (if public) then begins. If other work needs to be done, a {{{stash}}} or {{{commit}}} may be done to save work-in-progress, and the working copy switched to another branch for awhile. If significant fixes or other enhancements have been made to {{{develop}}} over time, it may be useful to merge {{{develop}}} into the feature branch so that the eventual merge back to {{{develop}}} has less conflicts. Here is how the merge from {{{develop}}} to {{{feature/add-checksum-option}}} is done:
    189 
    190 {{{
    191 git checkout feature/add-checksum-option
    192 git merge develop
    193 }}}
    194 
    195 == First post-svn conversion merge to {{{master}}} ==
    196 
    197 When you are ready to merge the {{{develop}}} branch to {{{master}}} (or better yet a release branch that's branched off {{{master}}}), there's a bit of housekeeping to be done the first time after the conversion from svn so that future merges proceed smoothly.  We're going to create a merge point between
    198 the develop and master branches so that Git knows the last point the two branches were in synch.  Once we've done that Git will perform a merge by replaying the commits on develop on top of master, starting from the last known merge: in other words Git will perform the tricky stuff of figuring out what to merge for us.
    199 
    200 * Navigate to the history for your library on !GitHub, starting with branch master. For example the Config library [https://github.com/boostorg/config/commits/master can be seen here].
    201 * Look down through the commit history and make a note of the last merge in svn land. In our example, it was on October 25th 2013.
    202 * Use the dropdown box to change the history to point to the develop branch. [https://github.com/boostorg/config/commits/develop Config library can be seen here].
    203 * Find the last commit '''before the date noted above'''. Click on the commit message for that commit to go to the actual diff for that change, [https://github.com/boostorg/config/commit/67f6b934f161dc5da2039004986a14d9217afae4 in our example here].  The SHA1 for that commit is shown below and to the right of the commit message, in this case it's {{{67f6b934f161dc5da2039004986a14d9217afae4}}}. Copy that SHA1 to your clipboard.
    204 
    205 Create a merge to that specific commit. Begin by changing your library to the master branch:
    206 
    207 {{{
    208 git checkout master
    209 }}}
    210 
    211 Now create a merge to the specific commit above; since we don't really want to actually change the master branch we'll use the {{{-s ours}}} option to avoid any conflicts:
    212 
    213 {{{
    214 git merge --no-ff --no-commit -s ours 67f6b934f161dc5da2039004986a14d9217afae4
    215 }}}
    216 
    217 You can now use {{{git status}}} and {{{git diff}}} to check for modifications, in this case there are none. Now make the commit and push to !GitHub:
    218 
    219 {{{
    220 git commit -am "Create first merge point for Git"
    221 git push
    222 }}}
    223 
    224 Then navigate to your libraries history again, and check that the merge shows up, [https://github.com/boostorg/config/commits/master our config example is here].
    225 You're now ready for "routine" merges to proceed as per Git Flow (or whatever other strategy you wish to use).
    226 
    227 === Lightweight library release ===
    228 
    229 Small, simple libraries and simple releases just merge {{{develop}}} into {{{master}}}, tag {{{master}}}, and declare victory.
    230 
    231 {{{
    232 git checkout master
    233 git merge --no-ff develop
    234 git tag -a 1.56.1
    235 }}}
    236 
    237 === Heavyweight library release ===
    238 
    239 Large, complex libraries, particularly those with multiple developers working in parallel, need to use a release procedure that scales up better than the lightweight procedure. The Git Flow approach is recommended. Find out more at [wiki:StartModWorkflow Modular Boost Library Workflow Overview] and be sure to study the examples given in [http://nvie.com/posts/a-successful-git-branching-model/ Vincent Driessen's original blog posting].
    240252
    241253== Acknowledgements ==