Version 24 (modified by 9 years ago) ( diff ) | ,
---|
Getting Started with Modular Boost Library Maintenance
-
Getting Started with Modular Boost Library Maintenance
- The Big Picture
- Prerequisites
-
Typical maintenance tasks
- Getting ready to work on a library
- Check out the development branch of your library
- Testing locally
- Checking status
-
Fix a simple bug directly on
develop
- Fix a bug using a hot-fix branch
- Start work on a new feature
-
First post-svn conversion merge to
master
- Lightweight library release
- Heavyweight library release
This page briefly sketches the mechanics of maintaining a Boost library using Git and Modular Boost. The intended audience is developers getting started with Git and Modular Boost maintenance of existing Boost libraries.
This page is intended to get you started only; it does not provide in-depth coverage. See links below for that.
The Big Picture
Library maintenance occurs in the context of how Boost repositories are organized. Please study the Modular Boost Overview before continuing, since a Boost developer needs to be familiar with how Boost organizes its repositories.
The examples given on this page follow Boost recommended workflow practices, but keep workflow discussion simple for this introduction. To better understand workflow recommendations and rationale before continuing, feel free to read Modular Boost Library Workflow Overview.
Prerequisites
- A recent release of the Git command line client installed. See Getting Started with Git for the git version required.
- A (free) GitHub account. See Getting Started with GitHub.
- A compiler and development environment installed and working smoothly.
- Modular Boost installed as described in Getting Started with Modular Boost.
b2
in your path. That allows the command line examples given here to work as shown on both Windows and POSIX-like systems.
Typical maintenance tasks
Getting ready to work on a library
The preferred environment for working on a library is to have develop
or some other development branch checked out, while other Boost libraries are as defined by the Boost super-project master
branch. This causes local tests of your library to run against master
for other Boost libraries as last accepted by the Boost super-project.
Thid is a more realistic test environment in than testing against the possibly unstable
develop
branch of other Boost libraries or against themaster
branch of other libraries as of a different point in time than that seen by the super-project. Robert Ramey has advocated this approach to testing for years, and Git and the modularization of Boost via submodules makes this approach easier.
cd modular-boost git checkout master git pull git submodule foreach --recursive "git checkout master; git pull"
Check out the development branch of your library
You can see what branch mylib
is currently on like this:
cd modular-boost/libs/mylib git branch
Then if you need to change the branch to a development branch such as develop
, do this:
cd modular-boost/libs/mylib git checkout develop
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.
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.
If there is any possibility the branch head content in the public upstream repo has changed, you also will want to update content:
cd modular-boost/libs/mylib git pull
From this point on, it is assumed you have already done a cd modular-boost/libs/mylib
.
Testing locally
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:
pushd test b2 popd
Checking status
Before making changes, it is a good idea to check status. Here is what that looks like on Windows; the message you get may vary somewhat:
>git status # On branch develop nothing to commit, working directory clean
Fix a simple bug directly on develop
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.
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:
cd modular-boost/libs/mylib git commit -a -m "my bug fix" git push
There are some significant disadvantages to this simple approach:
- The fix is now made to
develop
but you must remember to merge it to a release branch or directly tomaster
. It is very easy to forget to do that merge, particularly if this is a mature library you are not working with very often. - Users who need the bug fix right away are forced to jump through hoops to retrieve the fix from
develop
.
Putting out a point release solves both of those problems. Read on...
Fix a bug using a hot-fix branch
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.
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.
git checkout master git checkout -b hotfix/complex-boo-boo
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.
Since the bug is complex, it may take some time to fix and may go through several cycles of fixes, tests, and commits.
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
:
git checkout master git merge hotfix/complex-boo-boo git push git checkout develop git merge hotfix/complex-boo-boo git push git branch -d hotfix/complex-boo-boo
Start work on a new feature
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
.
git checkout develop git checkout -b feature/add-checksum-option
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:
git push --set-upstream origin feature/add-checksum-option
Whether or not
--set-upstream origin bugfix/complex-boo-boo
is actually needed depends on thebranch.autosetupmerge
configuration variable that isn't discussed here. If you don't supply--set-upstream origin bugfix/complex-boo-boo
on your firstpush
and it turns out to be needed, you will get an error message explaining that.
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:
git checkout feature/add-checksum-option git merge develop
First post-svn conversion merge to master
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
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.
Begin by navigating to the history for your library on Github, starting with branch master, for example the Config library
can be seen here. Looking down through the commit history we can see
that the last merge (In SVN land) was on October 25th 2013: make a note of that date. Now use the dropdown box to
change the history to point to the develop branch, Config library can be seen here.
As you can see there have been several commits since the date above, the last before that date was on Oct 21st, click on the
commit message for that change to take you to the actual diff for that change, 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
.
Now we'll create a merge to the specific commit, begin by changing your library to the master branch:
git checkout master
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:
git merge --no-ff --no-commit -s ours 67f6b934f161dc5da2039004986a14d9217afae4
You can now use git status
and git diff
to check for modifications, in this case there are none.
Now make the commit:
git commit -am "Create first merge point for Git"
And finish off by pushing your changes to Github
git push
Then navigate to your libraries history again, and check that the merge shows up, our config example is here. You're now ready for "routine" merges to proceed as per Gitflow (or whatever other strategy you wish to use).
Lightweight library release
Small, simple libraries and simple releases just merge develop
into master
, tag master
, and declare victory.
git checkout master git merge --no-ff develop git tag -a 1.56.1
Heavyweight library release
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 Modular Boost Library Workflow Overview and be sure to study the examples given in Vincent Driessen's original blog posting.