]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/smaller_tarball'
authorAndre Noll <maan@systemlinux.org>
Sat, 13 Aug 2011 10:21:18 +0000 (12:21 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 13 Aug 2011 10:24:15 +0000 (12:24 +0200)
1  2 
NEWS
configure.ac
web/manual.m4

diff --combined NEWS
index 49747ccb64326c52f5a3e542c73bf4785dd76953,c6c2e4dbd741954bd344d5b240e7ba98851ff7e8..40c30bf9ea19c70095c489d5a6cd41c7c29e9b03
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,24 -2,11 +2,27 @@@
  0.4.8 (to be announced) "nested assignment"
  -------------------------------------------
  
 +Gcrypt support, the overhauled osx writer and regex format specifiers
 +are the highlights of this release.
 +
 +      - support for libgcrypt as a drop-in replacement for openssl.
 +        Run configure --enable-cryptolib=gcrypt to link against
 +        libgcrypt. The two crypto implementations are compatible to
 +        each other, i.e. a para_client executable linked against
 +        gcrypt can connect to para_server linked against libssl
 +        and vice versa.
 +      - Rewrite of the osx writer (output plugin for Mac OS).
        - audiod: The format specifier for receivers, filters and
          writers is now treated as a regular expression. This allows
          to replace 5 lines in the config file (one for each audio
          format) by one single line. See the manual for details.
++      - The *.cmdline.[ch] files are no longer contained in the released
++        tarballs. This reduces the size of the tarballs but requires
++        gengetopt to build the tarball.
        - Compiles cleanly also with llvm/clang.
 +      - Corrupt mp3 files are handled more gracefully.
 +      - sched: Optimized zero timeouts.
 +      - vss timeout cleanups.
  
  --------------------------------------
  0.4.7 (2011-06-01) "infinite rollback"
diff --combined configure.ac
index 79aaee63b3f159e20941f137b4b8d279823f7bf0,cc88cf83d85bd005a11feb8ed72c4741ee5322b9..6415668b50560d6ec89af8ec192544c1c3775735
@@@ -23,6 -23,14 +23,14 @@@ f
  
  AC_C_BIGENDIAN()
  
+ AC_PATH_PROG([gengetopt], [gengetopt])
+ test -z "$gengetopt" && AC_MSG_ERROR(
+       [gengetopt is required to build this package])
+ AC_PATH_PROG([help2man], [help2man])
+ test -z "$help2man" && AC_MSG_ERROR(
+       [help2man is required to build this package])
  AC_PROG_CC
  AC_PROG_CPP
  AC_PROG_INSTALL
@@@ -85,14 -93,14 +93,14 @@@ AC_DEFUN([add_cmdline],[$(for i in $@; 
  
  
  all_errlist_objs="server mp3_afh afh_common vss command net string signal time
 -daemon stat crypt http_send close_on_fork ipc acl afh fade amp_filter
 +daemon stat http_send close_on_fork ipc acl afh fade amp_filter
  dccp_send fd user_list chunk_queue afs aft mood score attribute blob ringbuffer
  playlist sched audiod grab_client filter_common wav_filter compress_filter
  http_recv dccp_recv recv_common write_common file_write audiod_command
  client_common recv stdout filter stdin audioc write client exec send_common ggo
  udp_recv udp_send color fec fecdec_filter prebuffer_filter mm
  server_command_list afs_command_list audiod_command_list bitstream imdct wma_afh
 -wma_common wmadec_filter buffer_tree
 +wma_common wmadec_filter buffer_tree crypt_common
  "
  
  executables="recv filter audioc write client afh audiod"
@@@ -115,9 -123,9 +123,9 @@@ audioc_errlist_objs="audioc string net 
  audioc_ldflags=""
  
  audiod_cmdline_objs="add_cmdline(audiod compress_filter http_recv dccp_recv file_write client amp_filter udp_recv prebuffer_filter)"
 -audiod_errlist_objs="audiod signal string daemon stat net
 +audiod_errlist_objs="audiod signal string daemon stat net crypt_common
        time grab_client filter_common wav_filter compress_filter amp_filter http_recv dccp_recv
 -      recv_common fd sched write_common file_write audiod_command crypt fecdec_filter
 +      recv_common fd sched write_common file_write audiod_command fecdec_filter
        client_common ggo udp_recv color fec prebuffer_filter audiod_command_list
        bitstream imdct wma_common wmadec_filter buffer_tree"
  audiod_ldflags="-lm"
@@@ -129,7 -137,7 +137,7 @@@ afh_ldflags="
  
  server_cmdline_objs="add_cmdline(server)"
  server_errlist_objs="server afh_common mp3_afh vss command net string signal
 -      time daemon crypt http_send close_on_fork mm
 +      time daemon http_send close_on_fork mm crypt_common
        ipc dccp_send fd user_list chunk_queue afs aft mood score attribute
        blob playlist sched acl send_common udp_send color fec
        server_command_list afs_command_list wma_afh wma_common"
@@@ -144,8 -152,8 +152,8 @@@ writers=" file
  default_writer="FILE_WRITE"
  
  client_cmdline_objs="add_cmdline(client)"
 -client_errlist_objs="client net string crypt fd sched stdin stdout time
 -      client_common buffer_tree"
 +client_errlist_objs="client net string fd sched stdin stdout time
 +      client_common buffer_tree crypt_common"
  client_ldflags=""
  
  gui_cmdline_objs="add_cmdline(gui)"
  CPPFLAGS="$OLD_CPPFLAGS"
  LDFLAGS="$OLD_LDFLAGS"
  LIBS="$OLD_LIBS"
 +########################################################################### crypto
 +AC_ARG_ENABLE(cryptolib, [AS_HELP_STRING(--enable-cryptolib=lib, [
 +      Force using crypto library "lib". This package requires either
 +      openssl or libgcrypt being installed. Possible values for "lib"
 +      are thus "openssl" and "gcrypt". If this option is not given,
 +      openssl is tried first. If openssl was not found, gcrypt is
 +      tried next.])])
 +
 +case "$enable_cryptolib" in
 +      "openssl") check_openssl="yes"; check_gcrypt="no";;
 +      "gcrypt") check_openssl="no"; check_gcrypt="yes";;
 +      "") check_openssl="yes"; check_gcrypt="yes";;
 +      *) AC_MSG_ERROR([invalid value "$enable_cryptolib" for --enable-cryptolib]);;
 +esac
  ###################################################################### openssl
 -OLD_CPPFLAGS="$CPPFLAGS"
 -OLD_LD_FLAGS="$LDFLAGS"
 -OLD_LIBS="$LIBS"
 -have_openssl="yes"
 -AC_ARG_WITH(openssl_headers, [AC_HELP_STRING(--with-openssl-headers=dir,
 -      [look for openssl headers also in dir])])
 -if test -n "$with_openssl_headers"; then
 -      openssl_cppflags="-I$with_openssl_headers"
 -      CPPFLAGS="$CPPFLAGS $openssl_cppflags"
 -fi
 -AC_ARG_WITH(openssl_libs, [AC_HELP_STRING(--with-openssl-libs=dir,
 -      [look for openssl libraries also in dir])])
 -if test -n "$with_openssl_libs"; then
 -      openssl_libs="-L$with_openssl_libs"
 -      LDFLAGS="$LDFLAGS $openssl_libs"
 -fi
 -AC_CHECK_HEADER(openssl/ssl.h, [], [have_openssl="no"])
 -AC_CHECK_LIB([crypto], [RAND_bytes], [], [have_openssl="no"])
 -if test "$have_openssl" = "no" -a -z "$with_openssl_headers$with_openssl_libs"; then
 -      # try harder: openssl is sometimes installed in /usr/local/ssl
 -      openssl_cppflags="-I/usr/local/ssl/include"
 -      CPPFLAGS="$CPPFLAGS $openssl_cppflags"
 -      openssl_libs="-L/usr/local/ssl/lib"
 -      LDFLAGS="$LDFLAGS $openssl_libs"
 -      # clear cache
 -      unset ac_cv_header_openssl_ssl_h 2> /dev/null
 -      unset ac_cv_lib_crypto_RAND_bytes 2> /dev/null
 -      AC_CHECK_HEADER(openssl/ssl.h, [have_openssl="yes"], [])
 +if test "$check_openssl" = "yes"; then
 +      OLD_CPPFLAGS="$CPPFLAGS"
 +      OLD_LD_FLAGS="$LDFLAGS"
 +      OLD_LIBS="$LIBS"
 +      have_openssl="yes"
 +      AC_ARG_WITH(openssl_headers, [AC_HELP_STRING(--with-openssl-headers=dir,
 +              [look for openssl headers also in dir])])
 +      if test -n "$with_openssl_headers"; then
 +              openssl_cppflags="-I$with_openssl_headers"
 +              CPPFLAGS="$CPPFLAGS $openssl_cppflags"
 +      fi
 +      AC_ARG_WITH(openssl_libs, [AC_HELP_STRING(--with-openssl-libs=dir,
 +              [look for openssl libraries also in dir])])
 +      if test -n "$with_openssl_libs"; then
 +              openssl_libs="-L$with_openssl_libs"
 +              LDFLAGS="$LDFLAGS $openssl_libs"
 +      fi
 +      AC_CHECK_HEADER(openssl/ssl.h, [], [have_openssl="no"])
 +      AC_CHECK_LIB([crypto], [RAND_bytes], [], [have_openssl="no"])
 +      if test "$have_openssl" = "no" -a -z "$with_openssl_headers$with_openssl_libs"; then
 +              # try harder: openssl is sometimes installed in /usr/local/ssl
 +              openssl_cppflags="-I/usr/local/ssl/include"
 +              CPPFLAGS="$CPPFLAGS $openssl_cppflags"
 +              openssl_libs="-L/usr/local/ssl/lib"
 +              LDFLAGS="$LDFLAGS $openssl_libs"
 +              # clear cache
 +              unset ac_cv_header_openssl_ssl_h 2> /dev/null
 +              unset ac_cv_lib_crypto_RAND_bytes 2> /dev/null
 +              AC_CHECK_HEADER(openssl/ssl.h, [have_openssl="yes"], [])
 +              if test "$have_openssl" = "yes"; then
 +                      AC_CHECK_LIB([crypto], [RAND_bytes], [], [have_openssl="no"])
 +              fi
 +      fi
        if test "$have_openssl" = "yes"; then
 -              AC_CHECK_LIB([crypto], [RAND_bytes], [], [have_openssl="no"])
 +              AC_DEFINE(HAVE_OPENSSL, 1, [define to 1 to turn on openssl support])
 +              AC_SUBST(openssl_cppflags)
 +              openssl_libs="$openssl_libs -lssl -lcrypto"
 +              server_ldflags="$server_ldflags $openssl_libs"
 +              client_ldflags="$client_ldflags $openssl_libs"
 +              audiod_ldflags="$audiod_ldflags $openssl_libs"
 +
 +              all_errlist_objs="$all_errlist_objs crypt"
 +              server_errlist_objs="$server_errlist_objs crypt"
 +              client_errlist_objs="$client_errlist_objs crypt"
 +              audiod_errlist_objs="$audiod_errlist_objs crypt"
 +
 +              check_gcrypt="no"
 +      else
 +              AC_MSG_WARN([openssl libraries not found])
        fi
 -fi
 -if test "$have_openssl" = "yes"; then
 -      AC_DEFINE(HAVE_OPENSSL, 1, [define to 1 to turn on openssl support])
 -      AC_SUBST(openssl_cppflags)
 -      openssl_libs="$openssl_libs -lssl -lcrypto"
 -      server_ldflags="$server_ldflags $openssl_libs"
 -      client_ldflags="$client_ldflags $openssl_libs"
 -      audiod_ldflags="$audiod_ldflags $openssl_libs"
 +      CPPFLAGS="$OLD_CPPFLAGS"
 +      LDFLAGS="$OLD_LDFLAGS"
 +      LIBS="$OLD_LIBS"
  else
 -      AC_MSG_ERROR([openssl libraries not found])
 +      have_openssl="no"
 +fi
 +########################################################################### gcrypt
 +if test "$check_gcrypt" = "yes"; then
 +      OLD_CPPFLAGS="$CPPFLAGS"
 +      OLD_LD_FLAGS="$LDFLAGS"
 +      OLD_LIBS="$LIBS"
 +      have_gcrypt="yes"
 +      AC_ARG_WITH(gcrypt_headers, [AC_HELP_STRING(--with-gcrypt-headers=dir,
 +              [look for gcrypt headers also in dir])])
 +      if test -n "$with_gcrypt_headers"; then
 +              gcrypt_cppflags="-I$with_gcrypt_headers"
 +              CPPFLAGS="$CPPFLAGS $gcrypt_cppflags"
 +      fi
 +      AC_ARG_WITH(gcrypt_libs, [AC_HELP_STRING(--with-gcrypt-libs=dir,
 +              [look for libgcrypt also in dir])])
 +      if test -n "$with_gcrypt_libs"; then
 +              gcrypt_libs="-L$with_gcrypt_libs"
 +              LDFLAGS="$LDFLAGS $gcrypt_libs"
 +      fi
 +      AC_CHECK_HEADER(gcrypt.h, [], [have_gcrypt="no"])
 +      AC_CHECK_LIB([gcrypt], [gcry_randomize], [], [have_gcrypt="no"])
 +      if test "$have_gcrypt" = "yes"; then
 +              AC_DEFINE(HAVE_GCRYPT, 1, [define to 1 to turn on gcrypt support])
 +              AC_SUBST(gcrypt_cppflags)
 +              gcrypt_libs="$gcrypt_libs -lgcrypt"
 +              server_ldflags="$server_ldflags $gcrypt_libs"
 +              client_ldflags="$client_ldflags $gcrypt_libs"
 +              audiod_ldflags="$audiod_ldflags $gcrypt_libs"
 +
 +              all_errlist_objs="$all_errlist_objs gcrypt"
 +              server_errlist_objs="$server_errlist_objs gcrypt"
 +              client_errlist_objs="$client_errlist_objs gcrypt"
 +              audiod_errlist_objs="$audiod_errlist_objs gcrypt"
 +      else
 +              AC_MSG_WARN([gcrypt library not found])
 +      fi
 +      CPPFLAGS="$OLD_CPPFLAGS"
 +      LDFLAGS="$OLD_LDFLAGS"
 +      LIBS="$OLD_LIBS"
 +else
 +      have_gcrypt="no"
 +fi
 +###########################################################################
 +if test "$have_openssl" = "no" -a "$have_gcrypt" = "no"; then
 +      AC_MSG_ERROR([neither openssl nor gcrypt usable])
  fi
 -CPPFLAGS="$OLD_CPPFLAGS"
 -LDFLAGS="$OLD_LDFLAGS"
 -LIBS="$OLD_LIBS"
  ########################################################################### libsocket
  AC_CHECK_LIB([c], [socket],
        [socket_lib=],
@@@ -493,11 -431,11 +501,11 @@@ if test ${have_core_audio} = yes; the
        f="$f1 $f2 $f3 $f4"
  
        all_errlist_objs="$all_errlist_objs osx_write"
 -      audiod_errlist_objs="$audiod_errlist_objs osx_write"
 +      audiod_errlist_objs="$audiod_errlist_objs osx_write ipc"
        audiod_cmdline_objs="$audiod_cmdline_objs osx_write.cmdline"
        audiod_ldflags="$audiod_ldflags $f"
  
 -      write_errlist_objs="$write_errlist_objs osx_write"
 +      write_errlist_objs="$write_errlist_objs osx_write ipc"
        write_cmdline_objs="$write_cmdline_objs osx_write.cmdline"
        write_ldflags="$write_ldflags $f"
        writers="$writers osx"
@@@ -877,7 -815,7 +885,7 @@@ for obj in $all_errlist_objs; d
  done
  AC_DEFINE_UNQUOTED(DEFINE_ERRLIST_OBJECT_ENUM,
        [enum {$SS NUM_SS}],
 -      [list of all objects that use paraslash's error facility]
 +      [list of all objects that use the paraslash error facility]
  )
  
  ################################################################## status items
diff --combined web/manual.m4
index 7163bb7b8d700788795ce23ef8110fb90a1154a5,3e95de375cec50f42d2bb04acb9ff8aaae9c1173..6bddbf11a7f28824d871530812d879e72ac9ec44
@@@ -202,10 -202,9 +202,10 @@@ In any case you'll nee
  
        git clone git://git.tuebingen.mpg.de/osl
  
 -      - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/gcc, gcc). The
 -      EMPH(gnu compiler collection) is usually shipped with the
 -      distro. gcc-3.3 or newer is required.
 +      - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/gcc, gcc) or
 +      XREFERENCE(http://clang.llvm.org, clang). All gcc versions
 +      >= 3.3 are currently supported. Clang version 1.1 or newer
 +      should work as well.
  
        - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/make, gnu make) is
        also shipped with the disto. On BSD systems the gnu make
        scripts which run during compilation require the EMPH(Bourne
        again shell).  It is most likely already installed.
  
 -      - XREFERENCE(http://www.openssl.org/, openssl). The EMPH(Secure
 -      Sockets Layer) library is needed for cryptographic routines
 -      on both the server and the client side. It is usually shipped
 -      with the distro, but you might have to install the "development
 -      package" (called libssl-dev on debian systems) as well.
 +      - XREFERENCE(http://www.openssl.org/, openssl) or
 +      XREFERENCE(ftp://ftp.gnupg.org/gcrypt/libgcrypt/, libgcrypt).
 +      At least one of these two libraries is needed as the backend
 +      for cryptographic routines on both the server and the client
 +      side. Both openssl and libgcrypt are usually shipped with the
 +      distro, but you might have to install the development package
 +      (libssl-dev or libgcrypt-dev on debian systems) as well.
  
+       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/gengetopt/, gengetopt)
+       is needed to generate the C code for the command line parsers
+       of all paraslash executables.
        - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/help2man, help2man)
        is used to create the man pages.
  
@@@ -498,13 -499,12 +502,13 @@@ as follows
  
        - para_client connects to para_server and sends an
        authentication request for a user. It does so by connecting
 -      to para_server, TCP 2990, the control port of para_server.
 +      to TCP port 2990 of the server host. This port is called the
 +      para_server _control port_.
  
        - para_server accepts the connection and forks a child process
 -      which is supposed to handle the connection. The parent process
 -      keeps listening on the control port while the child process
 -      (also called para_server below) continues as follows.
 +      which handles the incoming request. The parent process keeps
 +      listening on the control port while the child process (also
 +      called para_server below) continues as follows.
  
        - para_server loads the RSA public key of that user, fills a
        fixed-length buffer with random bytes, encrypts that buffer
        session key.
  
        - para_client receives the encrypted buffer and decrypts it
 -      using the user's private key, thereby obtaining the challenge
 +      with the user's private key, thereby obtaining the challenge
        buffer and the session key. It sends the SHA1 hash value of
        the challenge back to para_server and stores the session key
        for further use.
        this point on the communication is encrypted using the RC4
        stream cipher with the session key known to both peers.
  
 -paraslash relies on the quality of openssl's cryptographically strong
 -pseudo-random bytes, on the security of the implementation of the
 -openssl RSA and RC4 crypto routines and on the infeasibility to invert
 -the SHA1 function.
 +paraslash relies on the quality of the pseudo-random bytes provided
 +by the crypto library (openssl or libgcrypt), on the security of
 +the implementation of the RSA and RC4 crypto routines and on the
 +infeasibility to invert the SHA1 function.
  
  Neither para_server or para_client create RSA keys on their own. This
  has to be done once for each user as sketched in REFERENCE(Quick start,
@@@ -543,8 -543,8 +547,8 @@@ file, below)
  The user_list file
  ~~~~~~~~~~~~~~~~~~
  
 -At startup para_server reads the user list file which must contain
 -one line per user. The default location of the user list file may be
 +At startup para_server reads the user list file which contains one
 +line per user. The default location of the user list file may be
  changed with the --user_list option.
  
  There should be at least one user in this file. Each user must have
@@@ -611,11 -611,10 +615,11 @@@ known audio files to those which satisf
  maintains tables containing images (e.g. album cover art) and lyrics
  that can be associated with one or more audio files.
  
 -AFS uses libosl, the object storage layer, as the backend library
 -for storing information on audio files, playlists, etc. This library
 -offers functionality similar to a relational database, but is much
 -more lightweight than a full database backend.
 +AFS uses XREFERENCE(http://systemlinux.org/~maan/osl/, libosl), the
 +object storage layer library, as the backend library for storing
 +information on audio files, playlists, etc. This library offers
 +functionality similar to a relational database, but is much more
 +lightweight than a full database backend.
  
  In this chapter we sketch the setup of the REFERENCE(The AFS process,
  AFS process) during server startup and proceed with the description
@@@ -625,7 -624,7 +629,7 @@@ and moods) explains these two audio fil
  in detail and contains pratical examples. The way REFERENCE(File
  renames and content changes, file renames and content changes) are
  detected is discussed briefly before the REFERENCE(Troubleshooting,
 -Troubleshooting) section which concludes the chapter.
 +Troubleshooting) section concludes the chapter.
  
  The AFS process
  ~~~~~~~~~~~~~~~
@@@ -728,7 -727,7 +732,7 @@@ Similarly, the "test" bit can be remove
        para_client setatt test- /path/to/the/audio/file
  
  Instead of a path you may use a shell wildcard pattern. The attribute
 -is applied to all audio files matching that pattern:
 +is applied to all audio files matching this pattern:
  
        para_client setatt test+ '/test/directory/*'
  
@@@ -784,7 -783,7 +788,7 @@@ can be used
  
  Note that the images and lyrics are not interpreted at all, and also
  the playlist and the mood blobs are only investigated when the mood
 -or playlist is activated by using the select command.
 +or playlist is activated with the select command.
  
  *The score table*
  
@@@ -800,9 -799,7 +804,9 @@@ next. While doing so, it computes the n
  last_played and the num_played fields in the audio file table.
  
  The score table is recomputed by the select command which loads a
 -new mood or playlist.
 +mood or playlist. Audio files are chosen for streaming from the rows
 +of the score table on a highest-score-first basis.
 +
  
  Playlists and moods
  ~~~~~~~~~~~~~~~~~~~
@@@ -814,12 -811,17 +818,12 @@@ terms of attributes and other type of i
  audio file table. As an example, a mood can define a filename pattern,
  which is then matched against the names of audio files in the table.
  
 -Selecting a mood or playlist means the generation of a ranking
 -(a score table) for the set of admissible files. Audio files are
 -then selected on a highest-score-first basis. The score table is
 -recomputed at the moment the mood or playlist is selected.
 -
  *Playlists*
  
  Playlists are accommodated in the playlist table of the afs database,
 -using the aforementioned blob format for tables. A new filelist is
 -created using the addpl command, by specifying the full (absolute)
 -paths of all desired audio files, separated by newlines. For example
 +using the aforementioned blob format for tables. A new playlist is
 +created with the addpl command by specifying the full (absolute)
 +paths of all desired audio files, separated by newlines. Example:
  
        find /my/mp3/dir -name "*.mp3" | para addpl my_playlist
  
@@@ -839,7 -841,7 +843,7 @@@ A mood consists of a unique name and it
  a set of *mood lines* containing expressions in terms of attributes
  and other data contained in the database.
  
 -At any time, at most one mood can be *active* which means that
 +At any time at most one mood can be *active* which means that
  para_server is going to select only files from that subset of
  admissible files.
  
@@@ -949,7 -951,7 +953,7 @@@ The year tag is special as its value i
  has no year tag or the content of the year tag is not a number. Such
  audio files never match. Another difference is the special treatment
  if the year tag is a two-digit number. In this case either 1900 or
 -2000 are added to the tag value depending on whether the number is
 +2000 is added to the tag value, depending on whether the number is
  greater than 2000 plus the current year.
  
  
@@@ -1804,11 -1806,6 +1808,6 @@@ branches, below), the git source code m
  paraslash development. It is necessary for cloning the git repository
  and for getting updates.
  
- ftp://ftp.gnu.org/pub/gnu/gengetopt/ (gengetopt). The C code for
- the command line parsers of all paraslash executables is generated
- by gengetopt. The generated C files are shipped in the tarballs but
- are not contained in the git repository.
  ftp://ftp.gnu.org/pub/gnu/m4/ (m4). Some input files for gengetopt
  are generated from templates by the m4 macro processor.
  
@@@ -1885,7 -1882,7 +1884,7 @@@ the tip of topic branches you are inter
  "git log next"). You should be able to safely build on top of them.
  
  However, at times "next" will be rebuilt from the tip of "master" to
 -get rid of merge commits that will never be in "master. The commit
 +get rid of merge commits that will never be in "master". The commit
  that replaces "next" will usually have the identical tree, but it
  will have different ancestry from the tip of "master".