Information about version control --------------------------------- PLplot uses git for version control. The fundamental git documentation we refer to most often is the freely downloadable [Pro Git Book](http://git-scm.com/book). There is excellent advice about commit messages and how to organize commits at as well. In particular, the fundamental advice there is to always include a short description paragraph at the top of your commit message giving a general description of your commit. That description is used throughout git when summarizing commits so it should be kept as short as reasonable (i.e., there is typically just one line in the description paragraph). Installation of git is straightforward as described at In all cases, it is highly recommended that git is run from the command line rather than from a GUI because the git command line is powerful, extremely well documented, and is the standard way most git users (including PLplot developers) use git. Command-line versions of git are readily available on all platforms. The Linux packages for git, the Mac OS X free software repository packages for git, and the Cygwin and MinGW-w64/MSYS2 Windows packages for git all include command-line versions. In addition, the Xcode version of git on Mac OS X and the Git for Windows version of git can both be used from the command line (see and ). Continuing with the git theme that "simpler is better", our general advice is to ignore non-standard extensions to git such as github versions or git-lfs since they are not needed, and use of standard git means there is less to go wrong. In fact, before we formulated this advice one of our developers installed and used git-lfs (from Macports) inadvertently with the result that a .git/hooks/pre-push shell script was run to execute git-lfs before each of his pushes, and he ran into trouble with that complication. He reverted back to the lean git that is also available from Macports by the following measures (which may be useful to others who have inadvertently installed git-lfs): "I did git lfs uninstall and it cleaned up the lines it had added to ~/.gitconfig. I also uninstalled git-lfs from my MacPorts stuff. Then I got a fresh clone." As expected (since git-lfs adds nothing that is truly needed for PLplot git needs) that lean git command-line environment has been working well for him ever since. Local configuration of git -------------------------- That is covered in the Pro Git book referenced above. But the fundamental thing you should do is identify yourself in the way you want to be identified in your commit messages. # To change/set the relevant values use, e.g., git config --global user.name "Alan W. Irwin" git config --global user.email airwin@users.sourceforge.net Workflow -------- PLplot currently uses the rebase git workflow [described here](http://kevinold.com/2013/04/17/my-git-workflow.html). And summarized here: 1. *ALWAYS* develop on a branch: git checkout -b new_branch Develop followed by tests of that development followed by git commit to create commits in new_branch. If you create a commit and realize before you make additional commits that there is an error in the commit, please use the --amend option to the subsequent commit that fixes the error. What this option does is squash the two commits together, i.e., it replace the old commit with the error by the combined old commit and fix. This approach minimizes errors in the commits that will eventually be merged to master (see below), and this cleaner master history will make subsequent use of git-bisect (a killer-app typically used to find which commit first caused a regression) much easier. 2. Updating the master branch: git checkout master git fetch # (optional) review newly downloaded changes git log origin/master git merge --ff-only origin/master Make sure that you are on the master branch before doing the merge. Failure to do so will mean having to undo the merge as merging master into your branch is bad and attempts to push your work back to official repo will be rejected. 3. Updating your working branch so that it is a sequential continuation of the work on the master branch: git checkout new_branch git rebase master Note that there is some possibility for headaches here. If one of the files that you are working on is changed in the master branch you may have to deal with merge conflicts. Unless you really need some new feature in master (and you probably should not if your branch is really a self-contained topic) then it is probably best to do this once just before you want to push your work back to the official repo. Also, git rebase is not suitable if you are right in the middle of work on a topic with a dirty tree with uncommitted changes. For this case use git checkout new_branch # (checkout the dirty tree with uncommitted changes) git stash save # (save that dirty tree to make new_branch clean # i.e., all uncommitted changes disappear). git rebase master # (update that clean branch) git stash pop # (restore your uncommitted changes) # ... keep working.... until you are ready to commit (and ultimately # merge back to master and push). 4. Incorporate changes back into master: git checkout master git fetch # Note, you are now in a race to get your changes pushed before someone # else does so work quickly from now on until that push. # Only if above fetch showed something downloaded git merge --ff-only origin/master git merge --ff-only new_branch At this point you should see a message like "Fast-forward". If instead you see "Merge made by the 'recursive' strategy" this is bad and means that your changes will be rejected when you try to push them to the official repo. You can inspect the history with gitk and possibly collapse the offending commits into a single commit (using git rebase --interactive) that makes the history sequential again. 5. Push changes to the official repo: # Check first: git push --dry-run origin master # Actual Push: git push origin master This is a rebase work flow. The sequential nature of the master branch is enforced by server side hooks and by only allowing fast-forward merges with the merge flag --ff-only. You can make this the default option for your repository using the command: git config merge.ff only This will add these two lines: [merge] ff = only To the .git/config file in your local repository of the PLplot project. Development Collaboration ------------------------- Note one drawback of a rebase workflow like adopted here is care must be used in sharing development branches with others. One such method is to publish an experimental branch using some public repository like those at github and asking others to have a look and make suggestions, as long as everyone else understands that it is a "read only" branch whose series of commits will disappear and be replaced by other commits whenever that branch is rebased on the official master version (which must occur, for example, before it is ff-merged with the master branch). Another method which has no such concerns at all is simply to use patches generated by "git format-patch" to share development branches on the plplot-devel mailing list. Developers who subscribe to that list can easily apply those patches with the "git am" command on some private branch to evaluate them (unless there are explicit file conflicts with the HEAD of master in which case the developer of those series of patches would need to bring them up to date with master by rebasing his private development branch before regenerating the patch series). For those new to git, here is the simple cookbook for using "git format-patch" (but use "git help format-patch" to learn a lot more). 1. Develop your topic on a private branch as indicated above. Suppose you have made 2 commits to that topic branch that you would like to share with others for their evaluation. Then use git format-patch -2 to create two formatted patch files corresponding to your two commits, e.g., 0001-Build-system-Fix-test_python_psc-dependency-issue.patch 0002-Build-system-Implement-version-check-on-libharu-libh.patch Review each of those files to make sure your commit name and e-mail address are the way you like them (see the "git config" command above for changing those). Also make sure your description (see comments on the description paragraph above) is the way you like it for each of the commits. Then store those files in a compressed tarball, e.g., tar zcf my_topic.tar.gz 000*.patch send those compressed results as an e-mail attachment to, e.g., the plplot-devel mailing list; and then cleanup afterward as follows: rm 000*.patch rm my_topic.tar.gz Those receiving such a tarball should unpack it, and then use git am _on a private topic branch_ to commit those changes for further collaboration until the collaborative yet private topic is matured enough to be merged with the master branch and pushed. Updating our wiki pages ----------------------- The definitive markdown source for our wiki pages is located in doc/wiki_source. While working on a topic branch (see advice above) do the following steps: Case I (when you prefer to use your own file editor): * Edit an existing file at doc/wiki_source (or if you are creating a new wiki page edit a new file there). * Use the git diff --word-diff command to evaluate the changes (the --word-diff option is essential to allow humans to isolate the changes in the generally long markdown format lines); * Transmit those changes to SF by cutting and pasting them with ctrl-c and ctrl-v from the git working directory file edit to the SF GUI editor for the wiki page in question. On the SF GUI editor side, the old text that is being replaced can be selected and deleted. * Test the resulting changed wiki page (e.g., check the diff available in the history GUI to make sure there were no cut and paste or deletion failures, check the new links, check the rendering of the updated markdown format looks good). * Commit the markdown source file for the wiki changes on the git topic branch. * Push your commit following the above directions. (END OF CASE I) Case II (when you prefer to use the SF wiki editor): * Click on the SF GUI for the wiki page to edit the markdown source for that page. * Test the resulting changed wiki page (e.g., check the diff available in the history GUI to make sure there were no cut and paste or deletion failures, check the new links, check the rendering of the updated markdown format looks good); * Transmit those changes to the git working directory doc/wiki_source by cutting and pasting them from the SF GUI editor session to a file edit of the appropriate file in that directory using ctrl-c to select and ctrl-v to paste and ordinary file editing capability to delete the text that is being replaced. * Use the git diff --word-diff command to evaluate the changes (the --word-diff option is essential to allow humans to isolate the changes in the generally long markdown format lines); * Commit the markdown source file for the wiki changes on the git topic branch. * Push your commit following the above directions. (END OF CASE II) Configuring the build system ---------------------------- The PLplot build system now requires CMake to configure the build on all build platforms (Linux, Mac OS X, traditional Unix, and Windows). The latest instructions for building PLplot with cmake can be found on the PLplot wiki. http://sourceforge.net/p/plplot/wiki/ Coding standards for PLplot --------------------------- Adherence to coding standards should help make code more portable. Therefore when writing / contributing code for PLplot the following standards should be followed: C: ISO C99 standards with POSIX.1-2001 base specification (required for a number of functions) C++: ISO C++ 1998 standard plus amendments Fortran: Fortran 2003 standard (especially including support for the ISO_C_BINDING module that we use to implement the new fortran binding). To check code conforms to standards it is recommended to try compiling with suitable compiler flags to enforce these standards and to enable compiler warnings to check for dubious code. For gcc / g++ / gfortran the following flags can be used export CFLAGS="-O3 -fvisibility=hidden -std=c99 -D_POSIX_C_SOURCE=200112L -pedantic -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wconversion -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings" export CXXFLAGS="-O3 -fvisibility=hidden -std=c++98 -pedantic -Wall -Wextra" export FFLAGS="-O3 -Wall -Wextra" N.B. adding the options -std=f2003 -pedantic to FFLAGS would normally be used to check compliance with the Fortran 2003 standard, but those gfortran options do not currently work for our new Fortran binding because that compiler generates build errors in that case where the associated message is Error: Fortran 2008: Array of interoperable type at (1) to C_LOC which is nonallocatable and neither assumed size nor explicit size A google check for that error message found where apparently the interoperability concern was that an assumed shape array might not be continuous. But we feel that should not be a concern for this singly dimensioned case, and the NAG compiler (notorious for its ability to check for standards compliance) builds our fortran binding and examples without any errors or warnings. So for now we can only avoid what we believe is this spurious gfortran build error by dropping the -std=f2003 -pedantic options. Which means we cannot check compliance with Fortran 2003 with that compiler and must rely on a different Fortran compiler (NAG) to do that. Some notes and recommendations ------------------------------ - Use C++ style // comments rather than the older /* */ style comments. The only exception to this where a comment is embeded in a line of code, e.g. to comment out a parameter name in a function definition in C++. - To mark function parameters as unused and to suppress at least gcc warnings about these, mark the parameter names with the PL_UNUSED( ) macro. Styling of code --------------- The uncrustify code beautifying program is used to style the source code consistently and in a readable manner. Running the scripts/style_source.sh shell script can be used the check the source code and optionally apply any styling changes required. Use the --help option for this script to find out what options you have to run it. In order for this script to work, you must have the correct version (currently that is version 0.60) of uncrustify installed and on your PATH. You must also have PYTHON and other Unix tools installed. So typically this script is only run on Unix systems (or Unix-like systems such as Cygwin and MinGW-w64/MSYS2). Since this script can potentially make intrusive changes (if you use the --apply option), always run the "git diff" command afterward to review those changes before committing the result. Another important code styling script available on Unix or Unix-like systems is scripts/remove_trailing_blanks.sh which unconditionally removes trailing blanks from essentially all text files in the source tree. Since this script can potentially make intrusive changes, always run the "git diff" command afterward to review the changes before committing the result.