Next: , Previous: , Up: Invoking gnulib-tool   [Contents][Index]

3.13 Integration with Version Control Systems

If a project stores its source files in a version control system (VCS), such as CVS, Subversion, or Git, one needs to decide which files to commit.

In principle, all files created by gnulib-tool, except gnulib-cache.m4, can be treated like generated source files, like for example a parser.c file generated from parser.y. Alternatively, they can be considered source files and updated manually.

Here are the three different approaches in common use. Each has its place, and you should use whichever best suits your particular project and development methods.

  1. In projects which commit all source files, whether generated or not, into their VCS, the gnulib-tool generated files should all be committed. In this case, you should pass the option ‘--no-vc-files’ to gnulib-tool, which avoids alteration of VCS-related files such as .gitignore.

    Gnulib also contains files generated by make (and removed by make clean), using information determined by configure. For a Gnulib source file of the form lib/, the corresponding lib/foo.h is such a make-generated file. These should not be checked into the VCS, but instead added to .gitignore or equivalent.

  2. In projects which customarily omit from their VCS all files that are generated from other source files, none of these files and directories are added into the VCS. As described in Modified imports, there are two ways to keep track of options and module names that are passed to gnulib-tool. The command for restoring the omitted files depends on it:
    • If they are stored in a file other than gnulib-cache.m4, such as, bootstrap, bootstrap.conf, or similar, the restoration command is the entire gnulib-tool ... --import ... invocation with all options and module names.
    • If the project relies on gnulib-tool’s memory of the last used options and module names, then the file gnulib-cache.m4 in the M4 macros directory must be added to the VCS, and the restoration command is:
      $ gnulib-tool --update

      The ‘--update’ option operates much like the ‘--add-import’ option, but it does not offer the possibility to change the way Gnulib is used. Also it does not report in the ChangeLogs the files that it had to add because they were missing.

    Most packages nowadays use the first among these two approaches. Over time, three ways of handling version control have evolved.

    In the cases (A) and (B), a “git submodule” is used to reference the precise commit of the gnulib repository, so that each developer running ‘./bootstrap --pull’ or will get the same version of all gnulib-provided files.

    The alternative is to always follow the newest Gnulib automatically. Note that this can cause breakages at unexpected moments, namely when a broken commit is pushed in Gnulib. It does not happen often, but it does happen.

    • (A) In this approach, the developers use a git submodule manually.

      The location of the submodule can be chosen to fit the package’s needs; here’s how to initially create the submodule in the directory gnulib:

      $ git submodule add -- gnulib

      Thereafter, the developer will run this command to update the submodule to the recorded checkout level:

      $ git submodule update --init gnulib

      Use this sequence to update to a newer version of gnulib:

      $ git submodule update --remote gnulib
      $ git add gnulib
      $ ./bootstrap --bootstrap-sync

      If multiple submodules are used, the following may be useful:

      $ git config alias.syncsub "submodule foreach git pull origin master"
      $ git syncsub
    • (B) In this approach, the build-aux/bootstrap or program (see Programs for developing in Git checkouts) is used to aid a developer in using this setup. You copy this program (and if it’s, its companion files) into your package and place the copy or copies under version control. The program can be customized using bootstrap.conf which you also put under version control.
    • (C) In this approach, you write the and files by hand. is most easily written as a script that invokes

      ./ pull || exit 1

      where is described in Programs for developing in Git checkouts. typically contains an explicit gnulib-tool invocation, followed by

      aclocal -I m4 \
        && autoconf \
        && autoheader && touch \
        && automake --add-missing --copy \
        && rm -rf autom4te.cache \
        || exit $?
  3. Some projects take a “middle road”: they do commit Gnulib source files as in the first approach, but they do not commit other derived files, such as a generated by Automake. This increases the size and complexity of the repository, but can help occasional contributors by not requiring them to have a full Gnulib checkout to do a build, and all developers by ensuring that all developers are working with the same version of Gnulib in the repository. It also supports multiple Gnulib instances within a project. It remains important not to commit the make-generated files, as described above.

Next: Bundling the unit tests of the Gnulib modules, Previous: Handling Gnulib’s own message translations, Up: Invoking gnulib-tool   [Contents][Index]