help://All
help://All.sum
help://topics
help://topic
help://command
help://commands
All(sum)                    BitKeeper User's Manual                   All(sum)

NAME
  All - summary of all commands and topics

DESCRIPTION
  This  category  contains  an alphabetical listing of all BitKeeper com-
  mands.

COMMANDS
  bk Basics-Overview - BitKeeper basics to help get a new user started
  bk Howto - BitKeeper HOWTO guides
  bk Howto-BAM - configuring the Binary Asset Management (BAM) subsystem
  bk Howto-bkd - howto: configuring the BitKeeper daemon
  bk Howto-developer - howto: working with BitKeeper repositories
  bk Howto-setup - howto: setting up a BitKeeper repository
  bk abort - abort a failed pull or push
  bk admin - administer BitKeeper files
  bk alias - manage aliases for lists of components
  bk annotate - provide annotated listings of one or more source files
  bk attach - attach a component repository to a product repository
  bk backups - guide to doing backups of BitKeeper repositories
  bk bam - BAM utility routines
  bk base64 - RFC 1341 base64 encoding and decoding
  bk bin - show binary installation directory
  bk bisect - quickly find a changeset that introduced a bug
  bk - BitKeeper configuration management system front end
  bk bkd - the BitKeeper daemon
  bk c2r - convert changeset revision to file revision
  bk cat - concatenate and display file contents
  bk changes - show changeset history
  bk check - check repository for consistency
  bk checksum - check and/or fix BitKeeper per file checksums
  bk chmod - change the mode of a file and save it
  bk citool - BitKeeper graphical check-in tool
  bk clean - removes unmodified files
  bk clone - create a new copy of a package
  bk cmdlog - show the log of commands executed in this repository
  bk collapse - combine recent changesets into a single unit of work
  bk comments - change checkin comments
  bk commit - commit deltas to a changeset
  bk comps - list the components belonging to a product
  bk config - show repository configuration information
  bk config-etc - configuring BitKeeper
  bk config-gui - configuration for BitKeeper graphical tools
  bk conflicts - list unresolved files which contain conflicts
  bk cp - create a copy of a file preserving its revision history
  bk credits - License info for software included with BitKeeper
  bk cset - manage changesets
  bk csetprune - shrink a repository by removing files
  bk csets - run changes or csettool on last set of incoming changes
  bk csettool - BitKeeper graphical changeset browser
  bk debugtool - tool for use in remote command line debugging
  bk delta - check in modified files
  bk describe - generate a tag-based release name
  bk detach - create a stand-alone clone of a component repository
  bk diff - show differences in revision controlled files
  bk difftool - BitKeeper graphical differences viewer
  bk edit - check out a file for editing
  bk editor - automatically check out BitKeeper files when using $EDITOR
  bk emacs - info on how to use emacs' vc-mode
  bk export - export a patch or version of a BitKeeper repository
  bk extras - list extra files not under revision control
  bk fast-export - export the repository in a format compatible with git
  bk fast-import - import a new repository using git's fast-export format
  bk features - display features used or known
  bk files - demo program to show file name expansion
  bk filetypes - summary of BitKeeper file types
  bk findkey - look for keys in files
  bk findmerge - show where two revisions where merged
  bk fixtool - fix up pending changes
  bk flags - show a listing of files and their BitKeeper flags
  bk fm3tool - BitKeeper three-way merge tool
  bk fmtool - BitKeeper side-by-side merge tool
  bk gate - set or show the gate status of a nested collection
  bk gca - show the greatest common ancestor
  bk get - check out BitKeeper files
  bk gethost - display machine name
  bk getuser - display user name
  bk gfiles - generate lists of BitKeeper controlled files
  bk glob - demo program to show glob pattern expansion
  bk gone - mark a file (key) as gone
  bk grep - search some/all revisions of one or more files for a pattern
  bk help - get help for BitKeeper commands
  bk helptool - graphical front-end to the BitKeeper help system
  bk here - list or change the set of populated repositories
  bk populate - add one or more components to a nested collection
  bk unpopulate - remove one or more components to a nested collection
  bk history - guide to viewing changes to files and/or repositories
  bk id - display the identity of a package or repository
  bk ignore - ignore shell glob patterns
  bk import - import files or changes into a BitKeeper package
  bk initscripts - sample script for starting the BitKeeper daemon
  bk isascii - check that a file is ascii
  bk key2path - convert BitKeeper keys to pathnames
  bk key2rev - convert BitKeeper keys to revisions
  bk keywords - list of RCS and SCCS keywords
  bk latest - run command using the latest version of bk
  bk level - set or show the level of the repository
  bk lock - lock a repository or show lockers
  bk log - print file revision history and/or metadata
  bk makepatch - creates BitKeeper patches
  bk merge - three-way text based file merge
  bk merge-binaries - help on merging binary conflicts
  bk mv - rename file[s]
  bk names - put BitKeeper files where they should be
  bk new - add a file to the repository
  bk newroot - change the identity of a repository
  bk obscure - obscure BitKeeper file comments and contents
  bk parent - manage repository parent pointer[s]
  bk partition - transform a single repository into a nested collection
  bk patch - apply a diff file to an original
  bk path - show the path that BK uses for all subprocesses
  perlretut - Perl regular expressions tutorial
  bk pending - list deltas which need to be in a changeset
  bk port - pull changes from a different nested collection or standalone
  bk portal - set or show the portal status of a nested collection
  bk prompt - prompt a user with a message
  bk pull - update a repository from its parent[s]
  bk push - send local changes to parent repository
  bk pwd - print directory name
  bk r2c - convert file revision to ChangeSet revision
  bk range - demo program to show ranges & dates
  bk receive - receive a BitKeeper patch
  bk regex - demo program to show regular expressions in BitKeeper
  bk relink - recreate broken hard links
  bk remerge - redo the last merge
  bk renames - list file renames contained in one or more changesets
  bk renametool - graphical tool for finding renames
  bk renumber - regenerate the revision history numbers
  bk repocheck - check repository for consistency
  bk repogca - show greatest common ancestor across a set of repositories
  bk repos - command description
  bk repotype - display repository type
  bk resolve - merge and/or apply new work after a pull
  bk resolving - help on resolving conflicts
  bk revtool - BitKeeper graphical history browser
  bk rm - remove BitKeeper file[s]
  bk rmdir - remove a BitKeeper directory
  bk rmgone - remove files having keys in the gone file
  bk root - print the path name to the root of the repository
  bk rset - list files in a cset or the difference between two csets
  bk sane - check for various BitKeeper requirements
  bk sccslog - list deltas sorted by date across all files
  bk send - send a BitKeeper patch
  bk sendbug - file a bug report
  bk service - manage a bkd as a Windows service
  bk set - set operations
  bk setup - create a new BitKeeper package
  bk setuptool - graphical front-end to the BitKeeper setup command
  bk sfio - BitKeeper file archiver
  bk smerge - smart text-based 3-way file merge
  bk status - show repository status
  bk stripdel - strip deltas out of an s.file
  bk superset - check to see if the parent is ahead of the current repos- itory
  bk support - send a support request
  bk tag - tag the BitKeeper repository with a symbolic name
  bk tags - list tagged changesets
  bk takepatch - apply a BitKeeper patch
  bk templates - predefined templates for comments
  bk terms - definitions of BitKeeper terms
  bk triggers - using BitKeeper event triggers
  bk undo - Undo a changeset or set of changesets
  bk undos - convert DOS files to UNIX files
  bk unedit - destroy any unchecked in changes to specified files
  bk uninstall - uninstall BitKeeper
  bk unlock - remove BitKeeper repository locks
  bk unpull - remove changesets added by bk pull
  bk unrm - resurrect a removed BitKeeper file
  bk untag - delete the symbolic namd in the BitKeeper repository
  bk unwrap - unwrap patches
  bk upgrade - upgrade to, or check for, new versions of BitKeeper
  bk url - methods of accessing BitKeeper repositories
  bk version - print BitKeeper version
  bk what - look for SCCS what strings
  bk wrap - using BitKeeper wrappers
  bk xflags - check or fix BitKeeper flags
  bk zone - print BitKeeper's view of the timezone

BitKeeper Inc                                                         All(sum)
$
help://Overview
help://Overview.sum
Overview(sum)               BitKeeper User's Manual              Overview(sum)

NAME
  Overview - summary of the Overview category

DESCRIPTION
  The  overview  section contains Howto's  for  getting started  quickly,
  definitions  of  BitKeeper  terms,  and explanations of how or  why  to
  do common procedures.

COMMANDS
  bk Basics-Overview - BitKeeper basics to help get a new user started
  bk Howto - BitKeeper HOWTO guides
  bk Howto-BAM - configuring the Binary Asset Management (BAM) subsystem
  bk Howto-bkd - howto: configuring the BitKeeper daemon
  bk Howto-developer - howto: working with BitKeeper repositories
  bk Howto-setup - howto: setting up a BitKeeper repository
  bk backups - guide to doing backups of BitKeeper repositories
  bk config-etc - configuring BitKeeper
  bk config-gui - configuration for BitKeeper graphical tools
  bk filetypes - summary of BitKeeper file types
  bk history - guide to viewing changes to files and/or repositories
  bk initscripts - sample script for starting the BitKeeper daemon
  bk keywords - list of RCS and SCCS keywords
  bk merge-binaries - help on merging binary conflicts
  bk range - demo program to show ranges & dates
  bk resolving - help on resolving conflicts
  bk terms - definitions of BitKeeper terms
  bk url - methods of accessing BitKeeper repositories

BitKeeper Inc                                                    Overview(sum)
$
help://Common
help://Common.sum
Common(sum)                 BitKeeper User's Manual                Common(sum)

NAME
  Common - summary of the Common category

DESCRIPTION
  The Common section contains the most commonly used BitKeeper commands.

COMMANDS
  bk changes - show changeset history
  bk citool - BitKeeper graphical check-in tool
  bk clean - removes unmodified files
  bk clone - create a new copy of a package
  bk diff - show differences in revision controlled files
  bk difftool - BitKeeper graphical differences viewer
  bk edit - check out a file for editing
  bk get - check out BitKeeper files
  bk help - get help for BitKeeper commands
  bk mv - rename file[s]
  bk new - add a file to the repository
  bk pull - update a repository from its parent[s]
  bk push - send local changes to parent repository
  bk revtool - BitKeeper graphical history browser
  bk rm - remove BitKeeper file[s]
  bk unpull - remove changesets added by bk pull
  bk unrm - resurrect a removed BitKeeper file
  bk version - print BitKeeper version

BitKeeper Inc                                                      Common(sum)
$
help://Repository
help://Repository.sum
Repository(sum)             BitKeeper User's Manual            Repository(sum)

NAME
  Repository - summary of the Repository category

DESCRIPTION
  The Repository category contains all repository related commands.

COMMANDS
  bk abort - abort a failed pull or push
  bk backups - guide to doing backups of BitKeeper repositories
  bk - BitKeeper configuration management system front end
  bk bkd - the BitKeeper daemon
  bk changes - show changeset history
  bk check - check repository for consistency
  bk citool - BitKeeper graphical check-in tool
  bk clone - create a new copy of a package
  bk cmdlog - show the log of commands executed in this repository
  bk collapse - combine recent changesets into a single unit of work
  bk commit - commit deltas to a changeset
  bk conflicts - list unresolved files which contain conflicts
  bk cset - manage changesets
  bk csets - run changes or csettool on last set of incoming changes
  bk csettool - BitKeeper graphical changeset browser
  bk difftool - BitKeeper graphical differences viewer
  bk files - demo program to show file name expansion
  bk fixtool - fix up pending changes
  bk glob - demo program to show glob pattern expansion
  bk history - guide to viewing changes to files and/or repositories
  bk id - display the identity of a package or repository
  bk import - import files or changes into a BitKeeper package
  bk level - set or show the level of the repository
  bk lock - lock a repository or show lockers
  bk makepatch - creates BitKeeper patches
  bk merge - three-way text based file merge
  bk merge-binaries - help on merging binary conflicts
  bk parent - manage repository parent pointer[s]
  bk pending - list deltas which need to be in a changeset
  bk pull - update a repository from its parent[s]
  bk push - send local changes to parent repository
  bk relink - recreate broken hard links
  bk repocheck - check repository for consistency
  bk resolve - merge and/or apply new work after a pull
  bk resolving - help on resolving conflicts
  bk revtool - BitKeeper graphical history browser
  bk rm - remove BitKeeper file[s]
  bk rmgone - remove files having keys in the gone file
  bk service - manage a bkd as a Windows service
  bk setup - create a new BitKeeper package
  bk setuptool - graphical front-end to the BitKeeper setup command
  bk sfio - BitKeeper file archiver
  bk status - show repository status
  bk superset - check to see if the parent is ahead of the current repos- itory
  bk tag - tag the BitKeeper repository with a symbolic name
  bk tags - list tagged changesets
  bk takepatch - apply a BitKeeper patch
  bk templates - predefined templates for comments
  bk triggers - using BitKeeper event triggers
  bk undo - Undo a changeset or set of changesets
  bk unlock - remove BitKeeper repository locks
  bk unpull - remove changesets added by bk pull
  bk untag - delete the symbolic namd in the BitKeeper repository
  bk url - methods of accessing BitKeeper repositories

BitKeeper Inc                                                  Repository(sum)
$
help://GUI-tools
help://GUI-tools.sum
GUI-tools(sum)              BitKeeper User's Manual             GUI-tools(sum)

NAME
  GUI-tools - summary of the GUI-tools category

DESCRIPTION
  This  section contains the GUI tools and the guide for how to personal-
  ize your gui tool look and feel.

COMMANDS
  bk citool - BitKeeper graphical check-in tool
  bk config-gui - configuration for BitKeeper graphical tools
  bk csettool - BitKeeper graphical changeset browser
  bk difftool - BitKeeper graphical differences viewer
  bk fm3tool - BitKeeper three-way merge tool
  bk fmtool - BitKeeper side-by-side merge tool
  bk helptool - graphical front-end to the BitKeeper help system
  bk renametool - graphical tool for finding renames
  bk revtool - BitKeeper graphical history browser
  bk setuptool - graphical front-end to the BitKeeper setup command

BitKeeper Inc                                                   GUI-tools(sum)
$
help://File
help://File.sum
File(sum)                   BitKeeper User's Manual                  File(sum)

NAME
  File - summary of the File category

DESCRIPTION
  The  file  category  contains  all  commands related to files.  Viewing
  files, checking out/in files, finding status or history on files, etc.

COMMANDS
  bk annotate - provide annotated listings of one or more source files
  bk cat - concatenate and display file contents
  bk chmod - change the mode of a file and save it
  bk clean - removes unmodified files
  bk comments - change checkin comments
  bk cp - create a copy of a file preserving its revision history
  bk delta - check in modified files
  bk diff - show differences in revision controlled files
  bk edit - check out a file for editing
  bk extras - list extra files not under revision control
  bk files - demo program to show file name expansion
  bk filetypes - summary of BitKeeper file types
  bk fixtool - fix up pending changes
  bk fmtool - BitKeeper side-by-side merge tool
  bk get - check out BitKeeper files
  bk gfiles - generate lists of BitKeeper controlled files
  bk glob - demo program to show glob pattern expansion
  bk grep - search some/all revisions of one or more files for a pattern
  bk log - print file revision history and/or metadata
  bk merge - three-way text based file merge
  bk mv - rename file[s]
  bk new - add a file to the repository
  bk prompt - prompt a user with a message
  bk range - demo program to show ranges & dates
  bk receive - receive a BitKeeper patch
  bk remerge - redo the last merge
  bk rmdir - remove a BitKeeper directory
  bk sccslog - list deltas sorted by date across all files
  bk send - send a BitKeeper patch
  bk stripdel - strip deltas out of an s.file
  bk unedit - destroy any unchecked in changes to specified files
  bk unlock - remove BitKeeper repository locks
  bk unrm - resurrect a removed BitKeeper file
  bk unwrap - unwrap patches
  bk what - look for SCCS what strings
  bk wrap - using BitKeeper wrappers
  bk xflags - check or fix BitKeeper flags

BitKeeper Inc                                                        File(sum)
$
help://Nested
help://Nested.sum
Nested(sum)                 BitKeeper User's Manual                Nested(sum)

NAME
  Nested - summary of the Nested category

DESCRIPTION
  The  nested  category  contains commands that are specific to BitKeeper
  Nested Collections (think submodules that work).   These  are  commands
  that only work on Nested Collections; most of the repository level com-
  mands are nested aware.

COMMANDS
  bk alias - manage aliases for lists of components
  bk attach - attach a component repository to a product repository
  bk comps - list the components belonging to a product
  bk detach - create a stand-alone clone of a component repository
  bk gate - set or show the gate status of a nested collection
  bk here - list or change the set of populated repositories
  bk populate - add one or more components to a nested collection
  bk unpopulate - remove one or more components to a nested collection
  bk partition - transform a single repository into a nested collection
  bk port - pull changes from a different nested collection or standalone
  bk portal - set or show the portal status of a nested collection
  bk setup - create a new BitKeeper package

BitKeeper Inc                                                      Nested(sum)
$
help://Admin
help://Admin.sum
Admin(sum)                  BitKeeper User's Manual                 Admin(sum)

NAME
  Admin - summary of the Admin category

DESCRIPTION
  The  admin category contains commands used for system administration of
  BitKeeper and informational pages for doing configuration.

COMMANDS
  bk admin - administer BitKeeper files
  bk bkd - the BitKeeper daemon
  bk checksum - check and/or fix BitKeeper per file checksums
  bk config - show repository configuration information
  bk config-etc - configuring BitKeeper
  bk config-gui - configuration for BitKeeper graphical tools
  bk cset - manage changesets
  bk csetprune - shrink a repository by removing files
  bk flags - show a listing of files and their BitKeeper flags
  bk gone - mark a file (key) as gone
  bk id - display the identity of a package or repository
  bk ignore - ignore shell glob patterns
  bk initscripts - sample script for starting the BitKeeper daemon
  bk newroot - change the identity of a repository
  bk root - print the path name to the root of the repository
  bk sane - check for various BitKeeper requirements
  bk sendbug - file a bug report
  bk service - manage a bkd as a Windows service
  bk support - send a support request
  bk version - print BitKeeper version

BitKeeper Inc                                                       Admin(sum)
$
help://Compat
help://Compat.sum
Compat(sum)                 BitKeeper User's Manual                Compat(sum)

NAME
  Compat - summary of the Compat category

DESCRIPTION
  The  compat  category  is  a catch all for editor configuration, how to
  export a patch, licenses of third party software.

COMMANDS
  bk credits - License info for software included with BitKeeper
  bk editor - automatically check out BitKeeper files when using $EDITOR
  bk emacs - info on how to use emacs' vc-mode
  bk export - export a patch or version of a BitKeeper repository

BitKeeper Inc                                                      Compat(sum)
$
help://Utility
help://Utility.sum
Utility(sum)                BitKeeper User's Manual               Utility(sum)

NAME
  Utility - summary of the Utility category

DESCRIPTION
  The  utility  category is a catch all for smaller commands that are not
  really admin or any other category.

COMMANDS
  bk bam - BAM utility routines
  bk base64 - RFC 1341 base64 encoding and decoding
  bk bin - show binary installation directory
  bk bisect - quickly find a changeset that introduced a bug
  bk c2r - convert changeset revision to file revision
  bk describe - generate a tag-based release name
  bk fast-export - export the repository in a format compatible with git
  bk fast-import - import a new repository using git's fast-export format
  bk features - display features used or known
  bk findkey - look for keys in files
  bk gca - show the greatest common ancestor
  bk gethost - display machine name
  bk getuser - display user name
  bk isascii - check that a file is ascii
  bk key2path - convert BitKeeper keys to pathnames
  bk key2rev - convert BitKeeper keys to revisions
  bk latest - run command using the latest version of bk
  bk names - put BitKeeper files where they should be
  bk obscure - obscure BitKeeper file comments and contents
  bk patch - apply a diff file to an original
  bk path - show the path that BK uses for all subprocesses
  bk pwd - print directory name
  bk r2c - convert file revision to ChangeSet revision
  bk regex - demo program to show regular expressions in BitKeeper
  bk renames - list file renames contained in one or more changesets
  bk renumber - regenerate the revision history numbers
  bk repogca - show greatest common ancestor across a set of repositories
  bk repos - command description
  bk repotype - display repository type
  bk rset - list files in a cset or the difference between two csets
  bk set - set operations
  bk smerge - smart text-based 3-way file merge
  bk undos - convert DOS files to UNIX files
  bk uninstall - uninstall BitKeeper
  bk upgrade - upgrade to, or check for, new versions of BitKeeper
  bk zone - print BitKeeper's view of the timezone

BitKeeper Inc                                                     Utility(sum)
$
help://Basics-Overview
help://Basics-Overview.1
help://bk-Basics-Overview
help://bk-Basics-Overview.1
Basics-Overview(none)       BitKeeper User's Manual      Basics-Overview(none)

NAME
       bk Basics-Overview - BitKeeper basics to help get a new user started

DESCRIPTION
       This  section explains how to make changes to files under revision con-
       trol.  If you have not created a package, then see the  bk  help  setup
       section.

       Note  that  BitKeeper  supports  both the traditional SCCS commands for
       checking in/out files ("admin -i", delta, get) as well as the RCS  com-
       mands (ci, co).  The delta/get are the preferred interfaces.

       As  an  example,  go  to  the  directory  where  you would like to make
       changes:

           $ cd ~/mypackage/src

       If you are starting a new package, then create new files with any  edi-
       tor  and  check  them in.  The initial check in for a file that already
       exists will look like this:

           $ bk new coolStuff.c

       If you want to modify an existing file, you can do this:

           $ bk edit coolStuff.c

       Or, if you have multiple files in the directory, you can do the follow-
       ing to place all files into a state where they can be modified:

           $ bk edit

       If you want to lock the  entire  tree,  including  subdirectories,  try
       this:

           $ bk -U edit

       Locking  the entire directory is useful when applying patches that will
       access many files in a tree.

       Once you are finished making changes to files, you  can  check  in  the
       files as follows:

           $ bk delta file1 file2 file3

       However, we recommend using the graphical checkin tool which is invoked
       with the following command:

           $ bk citool

       bk citool will help you check in both new, modified, and pending files.

DOCUMENTATION
       Each  command  in  BitKeeper has command-specific help.  You can access
       individual help topics by typing:

           $ bk help <command>      # e.g., "bk help get"

       There are also a number of other topics that describe various areas  in
       detail. Try bk help for a listing of help topics.

SEE ALSO
       bk help citool, bk help delta, bk help edit, bk help get, bk help help,
       bk help new

CATEGORY
       Overview

BitKeeper Inc                         1E1                Basics-Overview(none)
$
help://Howto
help://Howto.1
help://bk-Howto
help://bk-Howto.1
help://General/Quickstart
help://quickstart
HOWTO(none)                 BitKeeper User's Manual                HOWTO(none)

NAME
       bk Howto - BitKeeper HOWTO guides

DESCRIPTION
       Howto guides are recipes for accomplishing common tasks with BitKeeper.
       The  guides  contain  little  or  no  explanations.   Each  command has
       detailed help which you can see by running bk help <command>.

       Project leads should read the bk help Howto-setup and bk help Howto-bkd
       sections.  Developers who just want to use  an  existing  package  only
       need to read
       bk help Howto-developer.

SEE ALSO
       bk help Howto-bkd, bk help Howto-developer, bk help Howto-setup

CATEGORY
       Overview

BitKeeper Inc                         1E1                          HOWTO(none)
$
help://Howto-BAM
help://Howto-BAM.1
help://bk-Howto-BAM
help://bk-Howto-BAM.1
help://bam-howto
help://bam-HOWTO
help://BAM-HOWTO
help://howto-bam
help://Howto-bam
help://HOWTO-BAM
Howto-BAM(none)             BitKeeper User's Manual            Howto-BAM(none)

NAME
       bk Howto-BAM - configuring the Binary Asset Management (BAM) subsystem

OVERVIEW
       Binary  Asset  Management,  or  BAM, is a storage management system for
       versioning larger binary assets, such as tool chains,  libraries,  pho-
       tos, music, videos, etc.

       The  BAM system is a hybrid, combining the best of the traditional cen-
       tralized models with advantages of the distributed model  developed  by
       BitKeeper.   When  BAM  is  enabled,  and a BAM server is set, then BAM
       files in BitKeeper repositories are passed  by  reference  rather  than
       copied.  BAM files appear to be the same as regular BitKeeper files but
       they  contain  no  data, only a pointer which names the data.  The data
       typically resides in the BAM server and is fetched on demand as needed.

       What this means to a user is that a 20GB repository full of  BAM  files
       can  be cloned in a few seconds and if the user needs to work on only a
       small portion of the data, only that data needs to be fetched from  the
       BAM server.

CONFIGURATION
       In  order to have larger binaries be stored in BAM format, the configu-
       ration file (BitKeeper/etc/config) will need to have BAM enabled:

           BAM: on

       In order to fetch BAM data on demand a server must be configured:

           $ bk bam server bk://MyBigBox/MyRepo

       Note that the BAM server is per repository construct that is  inherited
       on clone, much like the repository level is inherited on clone.

CONVERTING REPOS
       If you have a repository that contains larger binaries (minimum checked
       out size of 64KB in revision 1.1), then you may do a conversion to BAM.

       The  conversion  should  be   done  in  a  clone because the conversion
       changes the identity of the repository, i.e., the converted  repository
       will  no  longer  be able to synchronize with the unconverted reposito-
       ries.  Note that while the conversion does change the package identity,
       it is idempotent so other repositories may also do the  conversion  and
       they will end up with the same package identity and be able to synchro-
       nize.

       The  conversion  process  will  add  a "BAM:on" variable to your config
       file.  If you wish to minimize the number  of  those  changesets,  turn
       that  variable  on  in  your  main tree and tell your team to pull that
       changeset before converting.

       The conversion process tends to be longer in projects with more change-
       sets and files (for example, the MySQL 5.2 tree with 51,000  changesets
       and 14,000 files took 5 minutes on a 2Ghz Opteron running Linux).

       The conversion process is simple:

           bk clone my_repo my_repo.BAM
           cd my_repo.BAM
           bk bam convert

USAGE
       Once  the  repository is converted, usage is as it was in the past, you
       clone, pull, push, etc., as normal.  In order to check  out  BAM  files
       the  BAM  server  listed in the config file must be accessible.  At the
       end of a "bk -U get" command you may see lines like:

           Fetching 18 BAM files from bk://MyBigBox/MyRepo...
           BitKeeper/BAM/62/62af0d9c.d1 (5.41M of 6.29M)

       followed by the normal check out messages for the associated files.

CHECKOUT
       There is a BAM_checkout configuration variable which is specific to BAM
       files.  If this variable is not set then BAM  files  use  the  checkout
       configuration  variable.   For  large collections of large files parti-
       tioned by directories, the BitKeeper support team  suggests  BAM_check-
       out:last as the best setting.  That setting will not pull BAM data into
       a  clone  until a user requests an edit or a checkout.  After that, the
       file will remain in whatever mode it was, even across deltas.

SEE ALSO
       bk help Howto, bk help bam, bk help newroot

CATEGORY
       Overview

BitKeeper Inc                         1E1                      Howto-BAM(none)
$
help://Howto-bkd
help://Howto-bkd.1
help://bk-Howto-bkd
help://bk-Howto-bkd.1
help://qs_admin
HOWTO-bkd(none)             BitKeeper User's Manual            HOWTO-bkd(none)

NAME
       bk Howto-bkd - howto: configuring the BitKeeper daemon

DESCRIPTION
       Here are examples how to configure the bk daemon for both read-only and
       read-write  modes.   We show how to export all repositories on a system
       in both read-write and read-only mode and we show how to export only  a
       specific repository in read-write and read-only mode.

           # Configure BitKeeper daemon for read-only
           # access for all repositories
           bk bkd -d -xpush

           # Configure BitKeeper daemon for read-write
           # access for all repositories
           bk bkd -d

           # Access a specific repository when multiple
           # ones are being exported
           bk clone bk://host.domain/some/dir/master ~/my_tree

           # Configure a specific BitKeeper repository
           # for read-write access
           cd /master/repository
           bk bkd -d -p6666 -xcd

           # Configure a specific BitKeeper repository
           # for read-only access
           cd /master/repository
           bk bkd -d -p4444 -xcd -xpush

           # Access a repository bound to a specific port
           bk clone bk://host.domain:6666 ~/my_tree

       With  the  BK/Web  feature, you can use a web browser to access the bkd
       web interface.  For example, to access the bkd above listening on  port
       6666, you can use the URL:

           http://host.domain:6666/

SEE ALSO
       bk help bkd, bk help Howto

CATEGORY
       Overview

BitKeeper Inc                         1E1                      HOWTO-bkd(none)
$
help://Howto-developer
help://Howto-developer.1
help://bk-Howto-developer
help://bk-Howto-developer.1
help://qs_developer
help://qs_dev
HOWTO-developer(none)       BitKeeper User's Manual      HOWTO-developer(none)

NAME
       bk Howto-developer - howto: working with BitKeeper repositories

DESCRIPTION
       Here  is  an example sequence of commands used to create a new package,
       import files into the package, create a clone of the package for  modi-
       fications,  do  some  work  in the clone, pull new work from the master
       tree down, merge, and then push the work back up.

           # Create a clone on your development machine.
           # The destination directory should not exist.
           bk clone bk://host.domain:6666/project ~/myproject

           # Do some work.
           cd ~/myproject
           bk vi index.cgi

           # Check it in and create a changeset.
           bk citool

           # Pull any new work down from the work tree.
           # This example assumes that someone else also changed
           # "index.cgi" and their changes overlapped the local changes.
           # The pull command will say that there are
           # overlapping changes and will not apply the new work.
           bk pull

           # Resolve the conflicts.  This step is only necessary if pull
           # said there were conflicts which could not be automerged.
           bk resolve

           # push the merge and the local changes back up.
           bk push

SEE ALSO
       bk help Howto

CATEGORY
       Overview

BitKeeper Inc                         1E1                HOWTO-developer(none)
$
help://Howto-setup
help://Howto-setup.1
help://bk-Howto-setup
help://bk-Howto-setup.1
help://qs_setup
HOWTO-setup(none)           BitKeeper User's Manual          HOWTO-setup(none)

NAME
       bk Howto-setup - howto: setting up a BitKeeper repository

DESCRIPTION
       Here  are  examples on how to setup the initial repository, import from
       plain files, a CVS repository, and/or an RCS repository.

       In order to do an import, the destination repository  needs  to  exist.
       bk setuptool is used when creating the first instance of a repository.

           # Setup initial repository
           cd ~/projects
           bk setuptool test_package

           # Import of plain files from a tar archive.
           # In order to do an import, the destination
           # repository needs to exist.  Notice that we put the
           # package in subdirectory, this is useful.
           mkdir /tmp/gcc
           cd /tmp/gcc
           tar zxf /tmp/gcc-2.95.2.tgz
           bk import -tplain /tmp/gcc ~/projects/test_package

           # Import of a CVS tree which resides in /tmp/mycvsproject.
           bk import -tCVS /tmp/mycvsproject ~/projects/test_package

           # Import of a RCS tree which resides in /tmp/myrcsproject.
           bk import -tRCS /tmp/myrcsproject ~/projects/test_package

SEE ALSO
       bk help Howto

CATEGORY
       Overview

BitKeeper Inc                         1E1                    HOWTO-setup(none)
$
help://abort
help://abort.1
help://bk-abort
help://bk-abort.1
bk abort(none)              BitKeeper User's Manual             bk abort(none)

NAME
       bk abort - abort a failed pull or push

SYNOPSIS
       bk abort [-f] [<repository_root>]
       bk abort [-S]

DESCRIPTION
       The  abort command can be used to clean up a failed update of a reposi-
       tory so that you can try the update  again.   Updates  sometimes  fail,
       leaving the PENDING and RESYNC directories behind.  Since the existence
       of  the RESYNC directory acts as a global repository lock, you probably
       don't want to leave it there for an extended period of time.

       If the update (i.e., a bk pull or bk push) failed and there has been no
       manual resolve work done yet, there is no harm in aborting  and  trying
       again.   If manual resolution has been done, it may be worth the effort
       to figure out what went wrong and try to fix it.

OPTIONS
       -f  Do not prompt for confirmation, just do it.

       -S  In a nested repository, limit the abort to this  component.   Typi-
           cally used to clean up after a port command.

FILES
       PENDING This  directory,  found at the root of your repository, is used
               to hold incoming data while it is transferred.
       RESYNC  This directory, found at the root of your repository,  is  used
               to  hold  copies  of your revision control files while they are
               being merged.

BUGS
       Abort should go look to see if you have done any merging and refuse  to
       abort without -f if you have.

SEE ALSO
       bk help pull, bk help push, bk help resolve

CATEGORY
       Repository

BitKeeper Inc                         1E1                       bk abort(none)
$
help://admin
help://admin.1
help://bk-admin
help://bk-admin.1
bk admin(none)              BitKeeper User's Manual             bk admin(none)

NAME
       bk admin - administer BitKeeper files

SYNOPSIS
       bk admin options [<file> ... | -]

DESCRIPTION
       The  bk admin command is used to administer BitKeeper files.  There are
       options for changing per file features, modifying file metadata,  veri-
       fying  file  checksum and metadata, changing the file compression mode,
       and/or recalculating the file checksum.

OPTIONS
       -C[<id>]    set or remove the changeset file string in  the  1.0  delta
                   (very rarely used, not recommended).  The string is used to
                   associate  the  file  with a particular repository idea and
                   usually the same as the output of bk id.
       -D          remove the delta changeset marks (rarely  used--not  recom-
                   mended).
       -f<flag>    set a per file flag.  Many of the flags may be set automat-
                   ically  upon  file  creation by adding an entry to the Bit-
                   Keeper/etc/config file.  See bk help config-etc for  infor-
                   mation  on  how  to  do so.  The possible values for <flag>
                   are:

                   BITKEEPER    mark the file as a BitKeeper file (very rarely
                                used, not recommended)
                   EOLN_NATIVE  use the operating system's native  end-of-line
                                termination  (i.e.,  \r\n on Windows and \n on
                                all other platforms.)  EOLN_NATIVE is  set  to
                                "on" by default.
                   EOLN_UNIX    use  the  UNIX  end-of-line termination (i.e.,
                                \n) on all platforms.
                   EOLN_WINDOWS use the Windows end-of-line termination (i.e.,
                                \r\n) on all platforms.
                   EXPAND1      expand keywords in first  line  that  contains
                                keywords  only  (printf conflicts) (May be set
                                in BitKeeper/etc/config).
                   NOMERGE      do not attempt to automerge this  file;  treat
                                it  as  if  it  were  a binary file and always
                                force a choice between the  local  and  remote
                                versions of the file.
                   RCS          expand  RCS  keywords,  i.e.,  $keyword$  etc.
                                (May be set in BitKeeper/etc/config).
                   SCCS         expand SCCS keywords, i.e., %K% etc.  (Setting
                                this  in  BitKeeper/etc/config  applies   this
                                behavior to all subsequently created files; it
                                does  not  affect existing files! You must use
                                bk admin to explicitly on existing files.)
       -F<flag>    delete flag <flag>, reverting to default behavior.
       -h          check s.file structure in general, but limited to ATT  SCCS
                   features.
       -hh         as above, but also check BitKeeper specific (in addition to
                   ATT SCCS) features.
       -hhh        as above, but also check time stamps.
       -i[<file>]  read initial text from <file> (default stdin).
       -q          run quietly.
       -y<comment> make  <comment>  be  the  checkin  comment  for the initial
                   checkin (only valid with -i).
       -z          recalculate file checksum.
       -Z<alg>     compress stored s.file with <alg>.  Compression  is  on  by
                   default because the space savings are substantial and there
                   is little or no performance difference.  The default may be
                   set in BitKeeper/etc/config.  <alg> may be:

                   gzip        like gzip(1)
                   none        no compression

BUGS
       This  command  does way too much and is likely to be split
       apart.  Do not depend on these options for scripts.

SEE ALSO
       bk help check, bk help checksum, bk help  chmod,  bk  help
       delta, bk help cset, bk help get, bk help id, bk help new,
       bk help log, bk help keywords, bk help config-etc

CATEGORY
       Admin

BitKeeper Inc                         1E1                       bk admin(none)
$
help://alias
help://alias.1
help://bk-alias
help://bk-alias.1
help://aliases
bk alias(none)              BitKeeper User's Manual             bk alias(none)

NAME
       bk alias - manage aliases for lists of components

SYNOPSIS
       bk alias [add|rm|set|new] [<options>] <name> [<component> ...]

   CREATING AN ALIAS
       bk alias new [-C] <name> <component> ...
       bk alias set [-C] <name> <component> ...

   ADDING COMPONENTS TO AN ALIAS
       bk alias add [-C] <name> <component> ...

   REMOVING AN ALIAS
       bk alias rm [-C] <name>

   REMOVING COMPONENTS FROM AN ALIAS
       bk alias rm [-C] <name> <component> ...

   REPLACING AN ALIAS
       bk alias set [-C] <name> <component> ...

   LIST ALL ALIASES
       bk alias [-r<rev>] [-hm] [-k] [-v]

   SHOW AN ALIAS
       bk alias [-r<rev>] [-hm] [-k] [-v] <name>

DESCRIPTION
       The  bk  alias  command  is  used  to  create,  modify, remove, or list
       aliases.  An alias is a symbolic name that resolves to a list of  other
       aliases  or  root keys for one or more components (aka sub-repositories
       in a product).

       Alias names are similar to C identifiers and must  match  this  regular
       expression:

           [A-Za-z][A-Za-z0-9_]*

       When creating, or adding to, an alias, how the components are specified
       and expanded is as follows:

       ./gcc    Any path that names a component means just that one component.
                The  path is relative to the current working directory; if the
                current working directory is not at the root  of  the  product
                then the sub-path to the current working directory is prefixed
                automatically.   The prefixed path is matched against the list
                of attached and committed components, i.e., specifying a  path
                to  a newly created but unattached component will result in an
                error.
       <key>    A root key of a component is the same as specifying  the  path
                to that component.
       COMPILER Any  name  without a leading "./" is taken as another alias to
                be expanded recursively.

       When adding a component to an alias, if the alias does not exist it  is
       automatically created in the aliases file.

       When modifying an alias the command line can include '-' instead of the
       arguments  and  the  list of aliases to add or remove will be read from
       standard input instead.

PRE-DEFINED OR RESERVED ALIASES
       There are a number of predefined aliases.  Predefined aliases  may  not
       be modified and they may not be used as part of a user defined alias.

       .        This  context sensitive alias means the current repository, be
                it the product or a component.
       ALL      This alias means all components (as well as the product).   If
                you  try  and  expand ALL and there are missing components the
                expansion will fail.
       PRODUCT  This alias always means the product.
       THERE    This alias means all components and the product that are  cur-
                rently  present  in the nested collection.  If you do not care
                what the other side has, you just want to replicate it, then

                    $ bk clone -sTHERE bk://good-stuff/some-repo

       HERE     This is the same as THERE but it makes more sense for commands
                like so:

                    $ bk clone -sHERE . bk://good-stuff/have-mine

       add      Reserved name, conflicts with the "bk alias add" command.
       rm       Reserved name, conflicts with the "bk alias rm" command.
       set      Reserved name, conflicts with the "bk alias set" command.
       new      Reserved name, conflicts with the "bk alias new" command.

       The predefined aliases ALL, HERE, THERE, PRODUCT, are case insensitive,
       i.e., "here" and "HERE" mean the same thing.  In all  other  cases  the
       names are case sensitive.

OPTIONS
       -@<URL> When  changing  an  alias leads to changing what components are
               here, include <URL> in the list of places to look.
       -C      Normally, modifying the aliases database results in a changeset
               committing that change.  This  option  suppresses  the  commit.
               Use  this  option when you wish to combine the alias event with
               other changes to the product.
       -h      (here) Used when showing aliases; causes only aliases that  are
               fully present to be listed.
       -k      (keys)  Used when showing aliases; causes individual components
               to be listed by their rootkeys instead of the current pathname,
               which is the default output.
       -m      (missing) Used when showing aliases; causes only  aliases  that
               are not fully present to be listed.
       -r<rev> Used  when  showing aliases; causes the aliases to be listed as
               of an older revision of the BitKeeper/etc/aliases file.
       -v      Used when showing aliases; causes aliases  to  be  expanded  to
               show  contents  using an indented list.  Adding more -v options
               expands to more levels.

EXAMPLES
       To create an alias that points to a named list of components:

           $ bk alias new COMPILER ./cmd/gcc ./cmd/as ./cmd/ld ./cmd/nm

       or, if you wish to type less:

           $ cd cmd
           $ bk alias new COMPILER ./gcc ./as ./ld ./nm

       To create a higher level alias that includes the debugger:

           $ bk alias new DEV-TOOLS ./gdb COMPILER

       List all aliases:

           $ bk alias
           COMPILER
           DEV-TOOLS

       Show an alias that contains another:

           $ bk alias DEV-TOOLS
           COMPILER
           ./cmd/gdb

       Expand an alias into paths:

           $ bk comps -sDEV-TOOLS
           ./cmd/as
           ./cmd/gcc
           ./cmd/gdb
           ./cmd/ld
           ./cmd/nm

       To remove a component from an alias:

           $ bk alias rm COMPILER ./cmd/nm

FILES
       The  aliases  database  is  a   flat   text   file   stored   in   Bit-
       Keeper/etc/aliases.   Any  components  that are specified as a path are
       stored internally as their root keys so that the alias will expand cor-
       rectly even if the specified component[s] is/are moved.

SEE ALSO
       bk help clone, bk help comps, bk help glob, bk help id, bk  help  popu-
       late

CATEGORY
       Nested

BitKeeper Inc                         1E1                       bk alias(none)
$
help://annotate
help://annotate.1
help://bk-annotate
help://bk-annotate.1
help://blame
help://sccscat
help://bk-sccscat
help://sccscat.1
help://bk-sccscat.1
bk annotate(none)           BitKeeper User's Manual          bk annotate(none)

NAME
       bk annotate - provide annotated listings of one or more source files

SYNOPSIS
       bk annotate [options] [<file> ... | -]

DESCRIPTION
       BitKeeper  annotations add an extra level of information, such as date,
       author, etc., when viewing file contents.  Annotated listings are  use-
       ful  for  deeper  understanding of your source base, i.e., when you are
       tracking down bugs.

       BitKeeper has two kinds of annotations: annotations of a specific  ver-
       sion  of  a  file,  and annotations of all (or some) versions of a file
       (the second form is unique to BitKeeper).

       By default, the bk annotate command will display a specific version  of
       a  file  with  annotations.   The  default  version of file is the most
       recent version; the "-r" option may be used to specify  an  alternative
       version.   The default annotations are the revision in which the change
       was made and the user who made that change.  Selecting any  annotations
       overrides all of the default annotations.

       An  alternate  form  of  the bk annotate command may be used to show or
       annotate either all lines added by all versions or just the lines added
       by one or more versions (in the latter case, the whole file is not dis-
       played, instead, only the lines which  were  added  in  that  range  of
       changes  are displayed.)  The "-R" option turns on this form of annota-
       tion.  Each version of a line is grouped closely with other versions of
       that line.  This can be useful for determining when a  particular  fea-
       ture was added or modified.  This form of annotation has no annotations
       by  default;  the desired annotations must be specified.  If no annota-
       tions are specified then the selected lines are shown  without  annota-
       tions.

OPTIONS
       -A<5dnpru> Align  annotations  in  a  human  readable form.  The set of
                  annotations will be followed by a vertical bar and  a  space
                  before  the  data  from  each line of the file starts.  Each
                  annotation is aligned in a column.  The  option  argument[s]
                  turn  on  one  or more annotations as a prefix to each line.
                  The order of annotations is fixed (no matter what order  you
                  specify them) and is the same as the order listed below:
                  p      Prefix  each line with the pathname of the file rela-
                         tive to the current working directory.  The  name  is
                         always  the  current  name of the file even if it has
                         been renamed.
                  d      Prefix each line with the date of last modification.
                  u      Prefix each line with the name of the user  who  last
                         modified it.
                  r      Prefix  each line with the revision of the last modi-
                         fication.
                  5      Prefix each line with the MD5 key of the last modifi-
                         cation.
                  n      Prefix each line with its line number.
       -a<5dnpru> Similar to "-A" but without the alignment  (each  annotation
                  is followed by a tab).  The order of fields is fixed and is:
                  pathname, date, user, revision, md5key, line number.
       -c<dates>  annotate  only  the  lines  added  by the specified range of
                  dates.  See bk range for information on specifying dates.
       -k         do not expand RCS or SCCS keywords.  This option is  implied
                  by "-c" and "-R".
       -r<rev>    annotate all lines in this version of the file.
       -R[<rev>]  annotate  only the lines added by the specified revision (or
                  range of  revisions).   If  <rev>  is  not  specified,  that
                  implies  all revisions (i.e., "..").  The difference between
                  this option and the previous option is that in this case  bk
                  annotate shows only those lines added by the specified revi-
                  sion[s],  but  in  the "-r" case, the entire contents of the
                  specified version is annotated.
       -w[<rev>]  Change the format  of  the  "r"  annotation  from  "rev"  to
                  "rev-d<rev>"  in the case where the line is deleted from the
                  rev passed as the argument,  or  "rev-x<rev>"  in  the  case
                  where  the  line  has  been excluded.  If no rev argument is
                  given, the tip revision is used.

EXAMPLES
       Annotate the latest revision of a file:

           $ bk annotate foo.c

       Annotate the lines added in the latest revision of that file

           $ bk annotate -R+ foo.c

       Annotate all lines in all versions of that file

           $ bk annotate -R foo.c

       Annotate all lines added to all files in the current directory  between
       June 1 of 2010 and July 31 of 2010:

           $ bk annotate -c2010/06..2010/07

       To annotate all lines added between two tagged releases:

           bk -U annotate -Rbk-4.6..bk-5.0

NOTES
       In previous versions of BitKeeper, the "-c" option was used to select a
       single  revision  and annotate all lines in that revision.  You can now
       get the same effect as the old:

           bk annotate -c2000 foo.c

       with the more complicated (this assumes bash is your shell):

           bk annotate -r$(bk prs -1 -hnd:REV: -c..2000 foo.c) foo.c

SEE ALSO
       bk help get, bk help grep, bk help range, bk help revtool

CATEGORY
       File

BitKeeper Inc                         1E1                    bk annotate(none)
$
help://attach
help://attach.1
help://bk-attach
help://bk-attach.1
bk attach(none)             BitKeeper User's Manual            bk attach(none)

NAME
       bk attach - attach a component repository to a product repository

SYNOPSIS
       bk attach [-qC] [-E<e>=<v>] [-r<rev>] <from> [<component>]

DESCRIPTION
       The  bk attach command is a form of bk clone used to attach a component
       repository to a product repository that is the portal.   The  specified
       repository  is  cloned and becomes a component within the product. This
       command must be run from within the product that is the portal for this
       nested collection.

OPTIONS
       -C            Do not commit the component to the  product.   Use
                     this  option  when  you wish to combine the attach
                     event with other changes to the product.
       -E<env>=<val> Export an environment variable to the bkd  running
                     in  the  remote  BitKeeper  repository.  Typically
                     used to pass information to remote triggers.  Only
                     variables with the prefix BKU_ are allowed.
       -q            Run quietly.
       -r<rev>       Clone the repository  up  to  and  including  cset
                     <rev>.  A changeset number or changeset key can be
                     used to specify <rev>.

SEE ALSO
       bk  help clone, bk help detach, bk help port, bk help portal, bk
       help setup

CATEGORY
       Nested

BitKeeper Inc                         1E1                      bk attach(none)
$
help://backups
help://backups.1
help://bk-backups
help://bk-backups.1
help://backup
bk backups(none)            BitKeeper User's Manual           bk backups(none)

NAME
       bk backups - guide to doing backups of BitKeeper repositories

DESCRIPTION
       BitKeeper  repositories  with  no pending files can be safely backed up
       with any backup tool, such as tar or dump, etc.  To see  if  there  are
       any pending files, run

           bk pending

       No output indicates no pending files.

WARNING
       If the repository has pending files (files which are checked in but not
       yet committed to a changeset), then saving and restoring the repository
       should  be  done  carefully.   Problems  can arise if the repository is
       restored multiple times and the same pending deltas  are  committed  to
       different  changesets.   In other words, the following will cause prob-
       lems:

           cd REPO
           bk edit foo.c
           echo "I am a pending delta not yet committed" >> foo.c
           bk delta -yPENDING foo.c
           cd ..
           cp -r REPO COPY
           cd REPO
           bk commit
           cd ../COPY
           bk commit

       Why is it a problem?  Because the two commits both created a changeset,
       and the changesets are different.  This means that the  same  delta  to
       foo.c  now  belongs  to two different changesets.  It is not fatal when
       this happens, but it may make it difficult to roll  backwards  to  this
       point.

SUGGESTION
       If  what you want is a copy of the repository, use bk clone to copy it,
       not tar, cp, or some other file by file copy.

SEE ALSO
       bk help pending, bk help gfiles, bk help status

CATEGORY
       Overview
       Repository

BitKeeper Inc                         1E1                     bk backups(none)
$
help://bam
help://bam.1
help://bk-bam
help://bk-bam.1
help://BAM
bk bam(none)                BitKeeper User's Manual               bk bam(none)

NAME
       bk bam - BAM utility routines

SYNOPSIS
       bk bam check [-Fq]
       bk bam clean [-an]
       bk bam convert [<size>]
       bk bam pull [-aq] [<URL>]
       bk bam push [-q] [<URL>]
       bk bam reattach [-q] <->
       bk bam reload
       bk bam repair [-q] [-@<URL>]
       bk bam server [-flqrs] [<URL>]

DESCRIPTION
       BitKeeper  Binary  Asset Management (BAM) is a subfeature that provides
       support for large binary files, such as tool  chains,  cell  libraries,
       game  data,  etc.   BAM differs from traditional binary storage in that
       the data does not need to be replicated in all clones, it may be lazily
       fetched on demand from a BAM server.

       The bk bam command is a utility command which provides  interfaces  for
       checking  integrity  of  BAM files, removing "orphaned" BAM files, con-
       verting old binary files to BAM files, fetching BAM files from the  BAM
       server,  pushing  local BAM files to the BAM server, or repairing a BAM
       pool.  In general, the convert or pull interfaces are most likely to be
       useful, the others are typically used debugging.

       In any operation with a "-q" option, that option means to run  quietly.
       The operations supported are:

       check    Check  that  the  BAM files are present and are not corrupted.
                If the "-F" option is included, then the corruption  check  is
                skipped.  Any files which are not found locally are looked for
                in  the  BAM server.  Note: currently there is no way to check
                for corruption remotely.
       clean    Remove any BAM files that are not referenced by any  delta  in
                the  repository.   If  the "-a" option is included, then flush
                local BAM files which are copies from the BAM server.  If  the
                "-n"  option is included, then just say what would be done but
                do not do it.
                NOTE: this command should never be run in a BAM  server  since
                the server may have BAM files referenced only by clients.
       convert  Convert  all  files  from  traditional  binary encoding to BAM
                encoding.  Only files greater than a  certain  size  are  con-
                verted  since  small files perform better with the traditional
                encoding.  The  size,  which  defaults  to  64K,  is  compared
                against  the  initial version of each binary file, and if that
                version is greater than the size the file is converted.   Note
                that  the  conversion  may be run more than once, but the size
                used can only decrease, it may not increase.
       pull     This interface is used to transfer any BAM data that is  miss-
                ing  from  the  current repository or its BAM server.  This is
                useful to request any missing BAM data after  switching  to  a
                new  BAM  server.   With the -a option the local BAM server is
                ignored, so all BAM data will  be  requested.   Normally,  the
                local  BAM  pool  contains  only  those  files which have been
                either checked out locally or created locally, i.e.,  the  BAM
                pool is sparse.  This command may be useful to populate a lap-
                top  clone with all revisions for disconnected operation or to
                set up a new BAM server.
       push     This interface is used to populate a BAM server with  any  BAM
                files  which  have  been  created  locally but not sent to the
                server.  In general, this command is not  needed  because  the
                BAM server is automatically updated if the local BAM files are
                either cloned or pulled to another repo.
       reattach Used to try and reinsert data into the BAM directory.  If your
                disk  crashed  and some files were lost from the BAM directory
                (which bk bam check -F will tell you) and you believe you have
                that data, you can tell bk bam reattach to put it back.
                For each file specified on standard input, see if the hash  of
                the  file  matches  one of the missing files.  If so, reinsert
                that file.
       reload   The BAM pool has an on disk binary index that is used for fast
                lookups stored in:

                    BitKeeper/BAM/<repo-rootkey>/index.db

                The data is also stored in a text format index:

                    BitKeeper/BAM/<repo-rootkey>/BAM.index

                Should the binary index get corrupted,  it  may  be  recreated
                running this command.
       repair   Similar  to bk bam check except that it will attempt to repair
                any corrupted data.  By default, it will look for good data in
                the BAM server, but you may specify a different location  with
                [-@<URL>] (which may be repeated).
       server   Used to report or, with the optional <URL>, set the BAM server
                from  which  BAM  data will be fetched.  If the "-r" option is
                set then the current server URL  is  deleted.   When  the  BAM
                server  is  changed, this command will automatically query the
                new server and transfer any BAM data it is  missing  from  the
                old  BAM  server.   This  query and transfer may be suppressed
                with the "-s" option.  Use the "-f" option to  force  changing
                or  removing  the BAM server setting if the repository is cur-
                rently defined as a BAM server.  The "-l"  option  causes  the
                existing  BAM  server URL to be printed for scripts.  And "-q"
                can be used to  suppress  status  messages  when  the  URL  is
                changed.

SEE ALSO
       bk help Howto-BAM

CATEGORY
       Utility

BitKeeper Inc                         1D1                         bk bam(none)
$
help://base64
help://base64.1
help://bk-base64
help://bk-base64.1
bk base64(none)             BitKeeper User's Manual            bk base64(none)

NAME
       bk base64 - RFC 1341 base64 encoding and decoding

SYNOPSIS
       bk base64 [-d]

DESCRIPTION
       The  bk  base64  command  is  a filter that encodes arbitrary data from
       stdin to a ASCII format that only uses the characters A-Z, a-z, 0-9, /,
       +, = and newline to encode the data.  This data can easily  be  emailed
       without being mangled.  If the -d option is passed then the encoding is
       unpacked to the original data.

OPTIONS
       -d  Decode base64 data to the original byte stream.

SEE ALSO
       bk help crypto, bk help unwrap, bk help wrap

CATEGORY
       Utility

BitKeeper Inc                         1E1                      bk base64(none)
$
help://bin
help://bin.1
help://bk-bin
help://bk-bin.1
bk bin(none)                BitKeeper User's Manual               bk bin(none)

NAME
       bk bin - show binary installation directory

SYNOPSIS
       bk bin

DESCRIPTION
       Returns the full path to the directory containing the BitKeeper instal-
       lation.

       To read all command documentation in a single file do:

           vi `bk bin`/bkhelp.txt

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk bin(none)
$
help://bisect
help://bisect.1
help://bk-bisect
help://bk-bisect.1
bk bisect(none)             BitKeeper User's Manual            bk bisect(none)

NAME
       bk bisect - quickly find a changeset that introduced a bug

SYNOPSIS
       bk bisect --cmd=<prog> -r<revs> [<opts>]
       bk bisect --cmd=<prog> --search[=<unit>] [<opts>]

DESCRIPTION
       The bisect command is used to find the changeset that introduced a bug.

       The normal usage is to specify a range to search and bk bisect will run
       a  binary  search  over  the changeset graph, looking for the changeset
       that caused the bug.

       You must supply a program (usually a shell script)  that  implements  a
       test that demonstrates the presence (or absence) of the bug, and passes
       status  back  through  the exit status.  It typically builds the source
       code and runs a test that looks for the bug (there are examples below).
       Note: the program is run at the root of  the  repository,  if  you  are
       looking  for some problem in a subdirectory remember to change directo-
       ries before running your test.

       The repository where bisect is run will be cloned to a  temporary  copy
       (see  --dir below) and the test program will be run at the root of this
       repository clone.

       If you do not know the range  to  search,  see  the  "--search"  option
       below.

OPTIONS
       --cmd=<prog> <prog>  is  a  program (usually a shell script) that tests
                    for the bug.

                    The program tells bisect where to search next via its exit
                    code:

                    0    An exit of 0 means that the bug was not  present,  so
                         continue  the  search  forward  on the descendants of
                         this changeset.
                    1    An exit of 1 means the bug was present,  so  continue
                         the  search backward on the ancestors of this change-
                         set.
                    2    An exit of 2 means the test  could  not  be  run  and
                         bisect  should  skip  this  revision and continue the
                         search.
                    3    An exit of 3 means abort the search immediately.

       --dir=<dir>  Use the specified directory  as  location  of  the  cloned
                    repository  in which tests are run.  Ideally you want this
                    to be a local disk (SSD is best).  The default is

                        `bk root -P`/BitKeeper/tmp/bisect

       --keys       Print MD5KEYS instead of  dates  as  the  prefix  to  each
                    changeset searched.
       -r<range>    Specify    the    changesets   to   be   searched,   i.e.,
                    "1.100..1.500".  This is frequently a pair of tags such as
                    "-rbk-5.0..bk-6.0".  If you want to search from a  rev  to
                    the  tip  then  say "-rbk-6.0..".  Mutually exclusive with
                    "--search".
       -s<alias>    When searching a nested collection  limit  the  search  to
                    changesets  that  modify  one  or  more  of the components
                    implied by  <alias>.   If  this  option  is  repeated  the
                    implied subset is the union of all specified aliases.
       --search[=<unit>]
                    Sometimes you have no idea where the bug was introduced so
                    specifying  a  range  is not an option.  Use "--search" to
                    tell bk bisect to search for  a  good  starting  changeset
                    that  does  not contain the bug.  By default it does expo-
                    nentially increasing probes in units of one  month  (tries
                    one  month  backwards,  then two months, then four months,
                    etc.)  The optional one-letter <unit> can be used to over-
                    ride the default unit of months (M)  to  search  by  years
                    (Y),  weeks  (W), days (d) or  hours (h).  Mutually exclu-
                    sive with "-r".
       --validate[=<both|stop|none>]
                    The most common user error when using bk bisect is provid-
                    ing a program that does not actually  find  the  bug.   To
                    prevent  this  error,  bk bisect validates by default that
                    the user provided program returns 0 at the  start  of  the
                    range and 1 at the end of the range (which is what --vali-
                    date=<both> does).

                    The full set of options are:

                    both  validate  both  endpoints  of the range (this is the
                          default).
                    start Validate that the bug is  present  in  the  starting
                          endpoint only.
                    stop  Validate  that  the  bug  is present in the stopping
                          endpoint only.
                    none  Do not validate the endpoints  before  starting  the
                          bisect search.

EXIT STATUS
       bk bisect returns exit status:

       0   if it finds a match
       1   if no matches were found
       2   if an error occurred

EXAMPLES
       This command is used when you have a test case which demonstrates a bug
       but you don't know where the bug was introduced.

           $ bk bisect --cmd=build-and-test --search

       and  BitKeeper  will  clone  the repository into the working directory.
       The test case will build the tree (if needed), run the test,  and  then
       exit as described above.

       This is a contrived example because you could do this much more cheaply
       with bk annotate and bk r2c, but suppose you wanted to figure out which
       changeset  added  the  string "THE STRING" to a file called "the-file".
       The test program would not need to build anything, it just  looks  like
       this:

           #!/bin/sh

           bk get -q the-file || exit 3 # skip if we can't get the-file

           # grep -q exits 0 if a match is found
           grep -q "THE STRING" the-file
           if [ $? = 0 ]
           then # still there, look in ancestors
                exit 1
           else # not there, look in descendants
                exit 0
           fi

       Here  is another example looking for when the string was removed (again
       contrived because you can do this much faster using bk  revtool).   The
       changeset listed will be the one that removed the string:

           #!/bin/sh

           # We run at the root but we're looking in a subdir
           bk grep -q '^fixDates(' src/slib.c
           if [ $? = 0 ]
           then    # found it
                   exit 0
           else    # not there
                   exit 1
           fi

LIMITATIONS
       Bisect  works on the basis that there is a single changeset that is the
       answer.  If the bug was introduced more than once then only one of  the
       changesets is reported.

       When  using  the  "--search"  option,  there is a bias towards the more
       recent work so if the changesets that introduced  the  bug  are  widely
       spaced  in time then it is likely the more recent one will be reported.
       If they are close together then it could be either  changeset  that  is
       reported.

SEE ALSO
       bk help range

CATEGORY
       Utility

BitKeeper Inc                     2012/01/07                   bk bisect(none)
$
help://bk
help://bk.1
help://bk-bk
help://bk-bk.1
bk(none)                    BitKeeper User's Manual                   bk(none)

NAME
       bk - BitKeeper configuration management system front end

SYNOPSIS
       bk [-A|U|e|r] [-s<alias>] [options] <command> [<options>]

DESCRIPTION
       bk is the front end to all BitKeeper commands.

       If  you are looking for instructions on how to get started, try running
       the test drive at http://www.bitkeeper.com/Test.html.

OPTIONS
       Only the global options are documented here.  To see  command  specific
       options  consult the documentation for the command in question (bk help
       <command>).

       -@[<url>]     Run the command in the specified repository  rather  than
                     locally.   If  <url>  is not specified, then use the par-
                     ent[s] of the current repository.  If there are  multiple
                     parents,  incoming and/or outgoing, use all of those par-
                     ents.  You can use the construct -@@<file> to  specify  a
                     file  containing a list of repository URLs, one per line;
                     the command is run in each of the remote repositories.

                     The -r[<dir>] option works as expected, running the  com-
                     mand recursively over all of the implied files.  If spec-
                     ified,  <dir>  must be relative to the root of the remote
                     repository.

                     If "-" is the last argument, then the standard  input  is
                     read and buffered.  Each remote command receives the same
                     input.

       -A
       --all-files   Starting  at the current working directory, run <command>
                     on all files in the entire repository or  nested  collec-
                     tion.   In a standalone repository this option is similar
                     to -r.  For example, to search all files in a nested col-
                     lection:

                         $ bk -A grep 'the string I want to find'

                     See -s below for ways to limit the set of files processed
                     in a nested collection.

       --config=<key:val>
                     Override one value in the configuration for this  command
                     only.

       --cd=<dir>    Change to <dir> before running the command.

       -e
       --each-repo   This  is a nested collection iterator that runs <command>
                     in each of the populated components and then the product.
                     For example, to see the full path to  the  root  of  each
                     repository in a nested collection:

                         $ bk -e pwd

                     See  -s  below  for ways to limit the set of repositories
                     processed in a nested collection.

       --headers     For remote commands (-@) or for nested collection  itera-
                     tors, this option causes the output from running the com-
                     mand in each repository to prefixed with a header:

                         #### <repo-url or location> ####

       -P            Change  directories to the root of the product repository
                     before running <command>.  Same as  -R  in  a  non-nested
                     collection.

       -R            Change  directories  to the root of the repository before
                     running <command>.

       -r[<dir>]     Starting at <dir>, or the repository root  if  <dir>  was
                     not  specified,  apply <command> recursively to <dir> and
                     all subdirectories.  This works by generating a  list  of
                     files  and  passing  them  to  <command>  on the standard
                     input.  This option differs from -A in that it is limited
                     to the current repository only, so if you are in a compo-
                     nent it will list only files belonging to that component.

       -s<alias>
       --subset=<a>  This option restricts the files (-A/-U)  or  repositories
                     (-e)  processed  to  those  belonging  to  the  specified
                     alias[es].  The option may be repeated to specify  multi-
                     ple  aliases, the alias may be a component, and the alias
                     may be negated.  To search everywhere except the product:

                         $ bk -U -s^PRODUCT grep some_string

                     This option must be combined  with  one  of:  -A,  --all-
                     files, -e, --each-repo, -U, --user-files.

                     In a standalone repository this option has no effect.

       -U
       --user-files  Starting  at the current working directory, run <command>
                     on all user files in the entire repository or nested col-
                     lection.  User files means everything except deleted  and
                     BitKeeper  metadata  files.   In  a standalone repository
                     this option is similar to -Ur.  For example, to check out
                     your collection:

                         $ bk -U get

                     To see all unchecked in changes:

                         $ bk -cU diff

                     See -s above for ways to limit the set of files processed
                     in a nested collection.

       -1acGpx -^G   One or more of these options may be used  in  combination
                     with "-A", "-r", or "-U" to limit the set of files passed
                     to <command>.

                     -1   Only  examine  the current (or named) directory.  Do
                          not go into subdirectories.
                     -G   List files only if they are checked out ("gotten").
                     -^G  List files only if they are not  checked  out  ("not
                          gotten").
                     -a   Examine   all   files,   even   if  listed  in  Bit-
                          Keeper/etc/ignore.
                     -c   List changed files (locked and modified).  See EXAM-
                          PLES below for a typical usage.
                     -p   List files with pending deltas.
                     -x   List files which have  no  revision  control  files.
                          See EXAMPLES below for a typical usage.
                     --gfiles-opts=<opts>
                          This  long  option  may  be  used  to pass any valid
                          option to sfiles.  The format must include the lead-
                          ing - or -- for each option and each option must  be
                          separated by a space like so:

                              --gfiles-opts='-c --cold'

EXIT STATUS
       Unless  otherwise documented, all BitKeeper commands return exit status
       0 on success and greater than 0 on failure.

EXAMPLES
       The following commands are equivalent:

             bk -A get
             bk -R gfiles | bk -R get -
             cd `bk root`; bk gfiles | bk get -

       An example usage for generating a  patch  of  all  new  and/or  changed
       files:

           $ bk -cxU diff -Nu

SEE ALSO
       bk help gfiles

CATEGORY
       Repository

BitKeeper Inc                         1E1                             bk(none)
$
help://bkd
help://bkd.1
help://bk-bkd
help://bk-bkd.1
help://anonymous
help://deamon
help://daemon
help://demon
help://security
help://secure
help://bkweb
help://bk/web
bk bkd(none)                BitKeeper User's Manual               bk bkd(none)

NAME
       bk bkd - the BitKeeper daemon

SYNOPSIS
       bk bkd [<options>]

DESCRIPTION
       The  BitKeeper  daemon, bkd, is used to synchronize and query reposito-
       ries.  It is typically run in one of the following ways:

       =>  automatically started when accessing a remote repository  via  rsh,
           ssh, HTTP, and/or the file system;
       =>  automatically started via ssh as a login shell;
       =>  manually started as a long running stand-alone daemon;
       =>  automatically started as a long running service at boot time.

       The  method used usually depends on how the remote repository is named.
       See bk help url for details on the naming syntax.

       The stand-alone daemon method has no security, other than  the  ability
       to  run  in read-only mode and/or the ability to limit chdir.  If secu-
       rity is a requirement, use ssh to access the  daemon.   See  below  for
       information on configuring the daemon as a login shell.

ANONYMOUS ACCESS
       The  most  common use of the stand-alone daemon is for anonymous access
       to a repository.  To provide read-only, anonymous access, you can run:

           bk bkd -d -xpush

       This will allow anyone to read (but not write) all repositories  at  or
       below the directory in which the bkd was started.

       If  you  want to export a single repository, pick a port number, and do
       this:

           cd /home/bk/linux-2.6
           bk bkd -d -p5555 -xcd -xpush

       This says to run in daemon mode, bind to port 5555,  and  disallow  the
       "cd"  and "push" commands.  By disallowing the "cd" command, the daemon
       at port 5555 is tied to the repository in the current working directory
       (bkd needs to be run at the root of the  repository).   By  disallowing
       the "push" command, the repository is protected from updates.

       Clients can get to this repository by using the BK URLs of

           bk://host.domain:5555
           http://host.domain:5555

       i.e.,

           $ bk clone bk://host.domain:5555 my_tree

       These  HTTP  URLs  allow access through most firewalls.  BitKeeper sup-
       ports accessing repositories through HTTP proxies, including  authenti-
       cated proxies.

SECURED ACCESS VIA SSH
       Secure access is provided via ssh.  There two ways to invoke ssh:

       a)  [<user>@]<host>:<pathname>
       b)  ssh://[<user>@]<host>[:<port>][/<pathname>]

       Using either form, ssh will be called to run bk bkd on the remote host.
       When the client command completes, the ssh connection is broken and the
       bkd daemon goes away.

   BKD LOGIN SHELL
       To add security when using ssh, run the bk bkd as the login shell.

       On  Red Hat Linux, the following steps are necessary to add a BitKeeper
       daemon login shell: create a simple shell script,  call  it  bkd_login,
       put  it  someplace  like /usr/libexec/bitkeeper/bkd_login, add the full
       path to the script in /etc/shells, and add a user  with  that  path  as
       their shell.

       An example bkd_login shell script:

           #!/bin/sh
           exec bk bkd -C -xcd

       Note:  using  the  bkd as a login shell when accessing the system using
       rsh is unsupported and is known not to work due to a long standing  rsh
       bug.

BK/WEB
       The  bkd is a self-contained HTTP server which provides the BK/Web fea-
       ture of BitKeeper.

       To access the BK/Web interface, use a web browser to go to the URL:

           http://<host>:<port>/

       where <port> is the port on which the bkd is listening  (see  the  "-p"
       option, below).

WINDOWS BASED BKD
       It  is possible to install a one or more bkd's as Windows services, see
       bk help service.

OPTIONS
       -C                This option provides a slightly more secure  mode  of
                         operation  in  that  the  bkd  will  refuse to change
                         directories up out of the directory in which  it  was
                         started.
       -d                Run as a daemon, typically in the background (but see
                         the next option).
       -D                Debug mode, do not fork and run in the background.
       -h                For all outgoing bk push, bk pull, and bk clone oper-
                         ations, wrap command responses in HTTP protocol.  Use
                         when bk bkd is called from a CGI script.
       -l<log>           Log  accesses  in  <log>;  if <log> is not specified,
                         then log to stderr.
       -P<pfile>         Write the pid of daemon process  into  this  file  at
                         startup.
       -p<addr>:[<port>]
       -p<port>          Specify  an  alternative  address  and/or  port.   By
                         default, the bkd allows connection requests from  any
                         host on port 0x3962 (aka 14690).  If <addr> is speci-
                         fied, the bkd will bind to that address, limiting the
                         hosts  which are allowed to connect.  The most common
                         usage is to bind to localhost (127.0.0.1) which means
                         that any local process  may  connect  but  no  remote
                         processes  may  connect.   Note:  When  specifying an
                         address, the trailing colon  is  required  even  when
                         <port> is omitted.  This option implies "-d".
       -i<cmd>           Include  <cmd>  from  the by default excluded command
                         list.
       -S                Run in "symlinks are allowed"  safe  mode.   This  is
                         similar  to  -C,  with the addition of allowing paths
                         that are symlinks under the bkd root and  resolve  to
                         outside  of  the bkd root.  This is useful to be able
                         to run this sequence of commands:

                             mkdir /repos
                             ln -s /mnt/disk1/repos/myrepo /repos/myrepo
                             cd /repos
                             bk bkd -S
                             cd $HOME
                             bk clone bk://machine/myrepo

                         Note: a user could check in a  symlink  to  anywhere,
                         then  push their repo to the master, then follow that
                         symlink.  This option  is  useful  for  organizations
                         where that is acceptable.
       -U                Run  in "unsafe" mode.  Any non-interactive BitKeeper
                         command may be run remotely.  The bkd runs  the  com-
                         mand at the request of a remote BitKeeper client.  If
                         the  client  does  not  have access to the machine on
                         which the bkd is running then this option allows  far
                         more  access  than  is usually prudent.  On the other
                         hand, if the client has remote  login  privileges  to
                         the machine (or if the client is on the same machine)
                         then  there  is  no security issue with allowing this
                         feature.  Accordingly, this option is turned on auto-
                         matically for any bkd started by the client  via  the
                         file://,  rsh://,  or ssh:// access methods.  If your
                         environment is secured then running a long lived  bkd
                         with  this option provides more BitKeeper functional-
                         ity to your users.
       -x<cmd>           Exclude <cmd> from the  allowed  command  list.   The
                         list of commands which may be excluded currently are:
                         abort,  cd,  check,  clone, get, httpget, pull, push,
                         pwd, rclone, rootkey, status, synckeys, and version.

EXAMPLES
       We use the following in /var/bitkeeper/repositories to  provide  anony-
       mous read only access to some BitKeeper repositories:

           #---------------------- cut here --------------------------
           nobody /home/bk/bk-3.2.x -C -xpush -p3200
           nobody /home/bk/bk-3.3.x -C -xpush -p3300
           #---------------------- cut here --------------------------

       The  following init script is known to work on Red Hat Linux based sys-
       tems.  The init script shown can be generated with a

           $ bk getmsg bitkeeper.init
           #---------------------- cut here --------------------------
           #!/bin/sh
           #
           # chkconfig: 2345 24 84
           # description: BitKeeper server

           # Source networking configuration.
           if [ -f /etc/sysconfig/network ]
           then . /etc/sysconfig/network

                # Check that networking is up.
                [ ${NETWORKING} = "no" ] && exit 0
           fi
           [ -x /usr/bin/bk ] || exit 0
           VAR=/var/bitkeeper

           case "$1" in
               start_msg) echo "Start BitKeeper daemons"
                     ;;
               stop_msg)  echo "Stop BitKeeper daemons"
                     ;;
               restart)   $0 stop
                          $0 start
                     ;;
               start)     cd $VAR || exit 1
                     test -f repositories || {
                          echo Nothing advertised
                          exit 0
                     }
                     while read user dir opts
                     do   (
                          cd $dir || exit 1
                          F=`basename $dir`
                          CMD="bk bkd -d $opts -l$VAR/log.$F -P$VAR/pid.$F"
                          su -c "$CMD" $user 2>> $VAR/errors
                          echo Started $CMD in $dir
                          )
                     done < repositories
                     ;;

               stop)
                     cd $VAR || exit 1
                     echo Shutting down BitKeeper daemons
                     for i in pid.*
                     do   kill `cat $i`
                          rm $i
                     done
                     ;;

               status)    cd $VAR || exit 1
                     for i in pid.*
                     do   echo This pid should be running: `cat $i`
                     done
                     ps -axf | grep bkd

                     ;;

               *)         echo "Usage: bitkeeper {start|stop}"
                     exit 1
                     ;;
           esac

           exit 0
           #---------------------- cut here --------------------------

BUGS/NOTES
       Needs ssh to provide access controlled, authenticated users.  One could
       argue that this is code reuse rather than a bug.

       BitKeeper does not ship ssh since it is widely available.

       On Windows the bkd service does not work when started  from  a  network
       drive.

       On  Windows  the bkd service does not work when started from a subst'ed
       drive.

SEE ALSO
       bk help parent, bk help service, bk help url, bk help Howto-bkd

CATEGORY
       Repository
       Admin

BitKeeper Inc                         1E1                         bk bkd(none)
$
help://c2r
help://c2r.1
help://bk-c2r
help://bk-c2r.1
bk c2r(none)                BitKeeper User's Manual               bk c2r(none)

NAME
       bk c2r - convert changeset revision to file revision

SYNOPSIS
       bk c2r -r<cset_rev> <file>

DESCRIPTION
       This  command  takes a changeset revision and a filename and prints the
       latest revision in the file that is part of that changeset.

EXAMPLE
       Suppose that revision 1.5 of foo.c was made in changeset 1.1234.

           $ bk c2r -r1.1234 foo.c
           1.5
           $ bk log -r1.5 foo.c
           foo.c 1.5
             2009-07-07 11:20:27-07:00 wscoot@desk.bitkeeper.com +4 -3
             Include system.h.

       This command is the inverse of bk r2c, which goes  from  a  file  to  a
       changeset  revision.   This  goes the other way, from changeset to file
       revision.  This command is here for completeness only, you can get  the
       same effect in a single step like so:

           $ bk log -r@1.1234 foo.c
           foo.c 1.5
             2009-07-07 11:20:27-07:00 wscoot@desk.bitkeeper.com +4 -3
             Include system.h.

SEE ALSO
       bk help r2c

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk c2r(none)
$
help://cat
help://cat.1
help://bk-cat
help://bk-cat.1
bk cat(none)                BitKeeper User's Manual               bk cat(none)

NAME
       bk cat - concatenate and display file contents

SYNOPSIS
       bk cat <file> [<file> ...]

DESCRIPTION
       bk cat is used to send one or more files to the standard output.  It is
       used  when a file's contents are wanted but the caller does not know if
       the file is or is not under revision control or is or  is  not  checked
       out.

       bk  cat  differs  from the standard UNIX cat command in two ways: a) it
       does not support any of the UNIX cat options, and b) if a file is spec-
       ified which does not exist, but a corresponding sfile does  exist,  the
       most recent version of sfile is sent to standard output.

       The following shell script emulates the bk cat command:

           for i in "$@"
           do       if [ -f $i ]
                    then    cat $i
                    else    # ignore error messages
                            bk get -kp $i 2>/dev/null
                    fi
           done

CATEGORY
       File

BitKeeper Inc                         1E1                         bk cat(none)
$
help://changes
help://changes.1
help://bk-changes
help://bk-changes.1
bk changes(none)            BitKeeper User's Manual           bk changes(none)

NAME
       bk changes - show changeset history

SYNOPSIS
       bk changes [<options>] [-r<revs> | -]
       bk changes [<options>] <repo> [<repo> ...]
       bk changes -L [<options>] [<repo> ...]
       bk changes -R [<options>] [<repo> ...]
       bk changes -L -R [<options>] [<repo> ...]

DESCRIPTION
       The changes command is used to get an overview of the changes made to a
       repository.   There  are  options  to search for particular changesets,
       view only tagged changesets, limit the search  to  a  particular  user,
       view  only  local changes, view only remote changes, view changes rela-
       tive to a set of repositories, etc.

       =>  The first form shown above shows changes in the  local  repository.
           If  the  last argument is a "-" then the revisions to be listed are
           specified, as keys, tags, and/or revisions, on stdin.
       =>  The second form shown above shows changes in the named repository.
       =>  The third form shown above lists changes found in the local reposi-
           tory but not in the remote repository.  If the remote repository is
           not specified, the  outgoing  parent[s]  of  the  local  repository
           is/are  used,  i.e.,  the  listing  is what would be sent on a push
           (when used with "-a").
       =>  The fourth form shown above  lists  changes  found  in  the  remote
           repository  but not in the local repository.  If the remote reposi-
           tory is not specified, the incoming parent[s] of the local  reposi-
           tory  is/are used, i.e., the listing is what would be received on a
           pull (when used with "-a").
       =>  The fifth form shown above  lists  changes  unique  to  either  the
           remote  or  the  local  repository.   The  local changes are listed
           first, then the remote changes, and both sets  of  changes  have  a
           title line to separate them.

       In all but the second form, the changes command must be run from within
       a  repository,  and  that  repository is the local repository while the
       named repository is the remote repository.   All  the  other  selection
       options are applied to the list of local or remote only changesets.

       The  changesets  to  be listed may be limited to a revision, a range of
       revisions, the last (or first) N changesets, or a list of revisions  on
       stdin.   The  default is all revisions.  Specifying revisions is incom-
       patible with the "-R/-L" options.

OPTIONS
       -<n>             A numeric argument that limits the number  of  change-
                        sets printed.

       -/<str>/[igt]    List  only those changesets whose comments contain the
                        string <str>.  <str> may be a regular  expression,  or
                        if the <g> option is specified, a glob.  If there is a
                        trailing "i" then ignore case in the search.  If there
                        is a trailing "t" then search only in tag names.  Yes,
                        it  would  be  nice if this worked on (meta)data other
                        than the comments but as of now it does not.

       -a               List all deltas, including tag deltas.  The default is
                        to list the tag name on the changeset implied  by  the
                        tag.   Implies  "-e".   An  additional "-e" after this
                        option will turn off the listing of  the  empty  merge
                        deltas  (the "-e" option is inverted from its previous
                        value each time the option is seen).

       --begin=<script> The dspec v2 language (see bk help dspec, in  particu-
                        lar  the  examples) is awk like and has begin/end sec-
                        tions.  This option allows you to specify the body  of
                        a  begin section (if the file also has a begin section
                        then both are  run;  order  is  undefined).   A  begin
                        script  is  typically  used with an on disk dspec file
                        that has been written in a way  to  do  one  thing  by
                        default and another if a variable is set to non-zero.

       -c<dates>        Specifies the changesets to be listed as a date range,
                        i.e.,  "-c-6W.."   lists  the  last  6  weeks worth of
                        changes.

       -D               When showing local or remote only  changes  and  there
                        are  multiple  local  or remote repositories specified
                        (or implied via the parent pointer[s]), there  may  be
                        duplicate  changesets  which  are present in more than
                        one repository.  If this option is specified, then the
                        duplicates are filtered out such that  the  changesets
                        listed  are  a  unique set.  This option combined with
                        "-aL" or "-aR" is used to answer the questions:  "What
                        is  only  in  this  repository  relative to all of the
                        specified repositories?" or "What is only  in  one  or
                        more  of the remote repositories but not in this local
                        repository?" respectively.

       -d<dspec>        Override the default dspec, allows for arbitrary  out-
                        put formats.

       --dspecf=<file>  Like -d but read the dspec from a file.

       -e               Show  empty  merge  changesets.  By default, these are
                        not shown.

       -f               print the changes in forward (oldest to newest) order.
                        The default is backwards in time, i.e., most recent to
                        least recent order.

       --html           Produce html as output.   May  not  be  combined  with
                        "-d".

       -i<pat>          Include  information  only  from  changesets involving
                        files matching <pat> pattern (see below).

       -k               Produce a list of matching changeset keys, usually for
                        scripts.  Equivalent to "-Dnd:KEY:".

       -L               List only those changesets which  are  unique  to  the
                        local repository.  Requires either a BK url or a valid
                        repository  parent.   Will  not  report tags, or empty
                        merges.  Use with "-a" to see tags and  empty  merges,
                        i.e.,  everything  which  would be sent back with a bk
                        push.

       --lattice        Restrict  the  changesets  to  those  on  the  lattice
                        between  the two range endpoints.  Unlike a range, the
                        lower bound is included in the  output.   Empty  merge
                        nodes are included (unlike the default output).

       --longest        Restrict  the  changesets to those on the longest line
                        between the two range endpoints.  Unlike a range,  the
                        lower  bound  is  included in the output.  Empty merge
                        nodes are included (unlike the default output).

       -m               Do not show any merge changesets, empty or not.

       -n               add a newline to each printed record (sometimes useful
                        with "-d").

       -q               When listing local/remote changes from  multiple  par-
                        ents  (or  remote repositories) do not print the loca-
                        tion of  the  remote  repositories.   This  option  is
                        implied by "-D".

       -r<revs>         Specifies the changesets to be listed, i.e., 1.100..

       -R               List  only  those  changesets  which are unique to the
                        remote repository, Requires either a BK url or a valid
                        repository parent.  Will not  report  tags,  or  empty
                        merges.   Use  with "-a" to see tags and empty merges,
                        i.e., everything which would be brought over with a bk
                        pull.

       --oneline        Print a summary of every cset in a single line. It  is
                        an alias for: bk changes -nd'$if(:CHANGESET: && !:COM-
                        PONENT_V:){:MD5KEY: $first(:C:)}$else{  :DPN:}'

       --short          With  the  system supplied dspecs, this will limit the
                        file/commit comments to only the first line  (it  does
                        so  by  setting the $9 dspec variable to 1, the system
                        supplied dspecs use that to change their output).

       --sparse-ok      When using include/exclude patterns  (-i/-x)  and  the
                        patterns  could match in a component that is not popu-
                        lated, BitKeeper will refuse to perform the search and
                        print an error. This option allows searching in sparse
                        products (with some components not populated)  without
                        erroring.

       -S
       --standalone     When used in a nested collection, treat the repository
                        as if it were detached rather than as part of the col-
                        lection.   Pathnames  will  be printed relative to the
                        repository root, revisions are based on the repository
                        changeset, not the product changeset (if in  a  compo-
                        nent),  pending  changesets,  if  any,  will be listed
                        (again, if in a component).  See product  notes  below
                        for examples.

       -t
       --tags           Only  list changesets which are currently tagged.  Use
                        -tt (or --all-tags) to list all changesets which  have
                        ever  been  tagged,  annotated  with the tag's current
                        state.

       -T               Sort the deltas in a changeset  in  time  order.   The
                        default  is to sort by current file name.  This option
                        only affects verbose ("-v") output.

       -u<user>         Only list changesets created by <user>.   This  option
                        may  appear multiple times in which case the changeset
                        is listed if it matches any of the specified users.

       -U<user>         Only list changesets created  by  someone  other  than
                        <user>.   This  option  may  appear  multiple times in
                        which case the changeset is not listed if  it  matches
                        any of the specified users.

       -v               Shows  individual  file  change  history  as  well  as
                        changeset history.

       -vv              Same as "-v" except that each file's change history is
                        followed by unified diffs for that change  (using  the
                        :DIFFS_UP: keyword).

       -x<pat>          Exclude  information  from changesets involving
                        files matching <pat> pattern (see below).

INCLUDE/EXCLUDE PROCESSING
       Include and/or  exclude  patterns  are  used  to  control  which
       changesets  are  selected  for  printing.  There may be multiple
       include and/or exclude patterns.  The patterns are a  file  glob
       as  used by bk ignore.  Patterns are matched against the partial
       pathname from the root of the repository.  If the partial  path-
       name  matches  any of the exclude patterns then the changeset is
       skipped.  If there are one or more include patterns but the par-
       tial pathname does not match any of the  include  patterns  then
       the  changeset  is skipped.  Exclude processing takes precedence
       over include processing.

       When reporting information there can be ambiguity  as  to  which
       name  is  used for include/exclude processing because some files
       may have been  moved  since  the  changeset  in  question.   The
       include/exclude processing always applies to the file name as it
       was  as  of the changeset in question.  For example, suppose you
       have a file that is currently deleted but at  the  time  of  the
       changeset  was  in  src/foo.c.  If you told the system to report
       src/* then the file will be in the set.

PRODUCT USAGE
       This command has been extended to handle nested  collections  of
       repositories.

       The  default  behavior  is  identical  to  that of a traditional
       standalone repository, the changesets of the product are listed.
       The various options behave as expected, the command  treats  the
       entire  collection as one large repository so a -v will show the
       product's changesets  and  files  as  well  as  the  component's
       changesets and files.

   SINGLE REPOSITORY
       There are times when you may want to treat a repository as if it
       were  detached  from  the nested collection, i.e., just show the
       history of this component and nothing else.  An example of  that
       might be to see what changes are available to be ported out:

           $ bk changes --standalone -L <URL>

       That  form  of  changes  is  restricted to just that repository;
       pathnames revert back to repository root relative  (rather  than
       product  root  relative),  revisions are based on the repository
       changeset, not the product's changeset, and all changesets, even
       those that are not committed to the product, are listed.

   EXAMPLES
       The most common uses are listed below:

       List only product changesets:

           $ bk changes

       Convert a product changeset to a key:

           $ bk changes -r1.1234 -nd:KEY:

       List the product changesets and component changesets as well  as
       files from both:

           $ bk changes -v

       same as previous but include diffs:

           $ bk changes -vv

       List only the changes in a component:

           $ cd src/component
           $ bk changes --standalone

EXAMPLES
       Sample output:

           ChangeSet@1.607, 2000-02-21 14:05:25-08:00, awc@bitkeeper.com
             update citool to use the "bk unedit" interface.

           ChangeSet@1.606, 2000-02-21 13:35:21-08:00, awc@bitkeeper.com
             Allow BitKeeper to be installed in an alternate directory.
             The install directory is computed from the $PATH variable and
             the bk symlink.

           ChangeSet@1.605, 2000-02-20 01:32:19-08:00, lm@bitkeeper.com
             Fix a diagnostic in pull.
             An aborted attempt at key compression.

BUGS
       Consider this query in a nested collection:

           bk changes -i'source_component/*' -x'test_component/*'

       The  expectation  is  that  you  would  only get changesets that
       touched the source component if they did not touch the test com-
       ponent.  As of now, the include will win whether the test compo-
       nent was or was not changed.

SEE ALSO
       bk help commit, bk help glob, bk help pending, bk help  log,  bk
       help  pcre,  bk  help pull, bk help push, bk help range, bk help
       revtool, bk help sccslog, bk help set

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                     bk changes(none)
$
help://check
help://check.1
help://bk-check
help://bk-check.1
bk check(none)              BitKeeper User's Manual             bk check(none)

NAME
       bk check - check repository for consistency

SYNOPSIS
       bk -r check [-acdefgpRvw]

DESCRIPTION
       Check  is used to make sure that a repository is in a consistent state.
       A repository contains files, each of which may have multiple  versions.
       Groups  of  versions  are  called  changesets  (csets).   Each  cset is
       recorded in the ChangeSet file.  The ChangeSet file points at  the  set
       of  deltas  in  the  set of files.  There are no back pointers, but the
       files do record the point at which each cset occurs (there can be  mul-
       tiple  deltas  in  a  file  all of which belong to one cset; the marker
       records the cset boundary).

       Since csets propagate between repositories, it is  important  that  the
       ChangeSet  file is correct.  bk check is used to make sure that nothing
       has gone wrong (and if it has, it gives you a rough idea of how to  fix
       it).

       Currently, the following are checked:

       =>  for  each  file specified, make sure that deltas marked as recorded
           in the ChangeSet file are recorded in the ChangeSet file.
       =>  for each file specified and for each delta of that  file  which  is
           recorded  in the ChangeSet file, make sure that the delta exists in
           the file.
       =>  for each file specified, make sure that the file has no  unresolved
           branches.
       =>  make  sure  that  every  delta recorded in ChangeSet file is in the
           repository (only with -a).

       While you can specify a list of files instead of using "bk -r"  to  get
       all of them, this is not recommended.

OPTIONS
       -a   Ensures  that  the ChangeSet file and the repository agree on what
            files are in the repository; also ensures that the  ChangeSet  and
            other  files  agree  on  where  they are in the repository history
            timeline.
       -c   Check file and the per delta checksums.  Note that only  the  most
            recent  delta's  checksum is checked, see bk checksum to check all
            of the checksums.
       -d   Provide more details about what is wrong.  Mainly for debugging.
       -e   Check for end of line (eoln) inconsistencies in text files.  Typi-
            cally used with the "-a" option.  This will  check  to  make  sure
            that:
            =>  the  state of the EOLN_NATIVE flag in each sfile is consistent
                with what is set in  the  BitKeeper/etc/config  file  (see  bk
                admin).
            =>  a bk file on a win32 operating system that has the EOLN_NATIVE
                flag set has the expected line termination: \r\n
            =>  a file on a UNIX operating system has the expected line termi-
                nation: \n
            =>  a  file  that  does  not  have the EOLN_NATIVE flag is has the
                expected line termination: \n
       -f   Fix any fixable errors.  This  option  will  renumber  incorrectly
            numbered  revisions,  put  incorrectly  located  files  where they
            belong, reconstruct corrupted xflags  metadata,  and  add  missing
            changeset  backpointers.   This  option  is  on  by default if the
            auto_fix config option is set.
       -ff  Fix any fixable errors which have destructive fixes.  This  option
            will  remove  any old line-of-development (LOD) information except
            the 1.x LOD.
       -g   List each missing file as the file's identifier (root key), but do
            not produce any other output.  Typically used as input to  the  bk
            gone command.
       -gg  List  each missing delta key, but do not produce any other output.
            Typically used as input to the bk gone command.
       -ggg List both missing files and missing  deltas.   Typically  used  as
            input to the bk gone command.
       -p   List deltas which are in more than one changeset.
       -R   Only do checks which make sense in the RESYNC dir.
       -v   Be  more verbose.  Each "-v" adds additional verbosity.  With just
            one, bk check will display a progress bar.   With  two,  bk  check
            will  list  each file which is OK.  More than two is for debugging
            only.  Without the "-v" option, there is no output if the  reposi-
            tory is OK; there is only output if things are broken.
       -w   List files which are writable but not locked.

SEE ALSO
       bk  help  admin, bk help checksum, bk help config-etc, bk help gone, bk
       help log, bk help xflags

CATEGORY
       Repository

BitKeeper Inc                         1E1                       bk check(none)
$
help://checksum
help://checksum.1
help://bk-checksum
help://bk-checksum.1
bk checksum(none)           BitKeeper User's Manual          bk checksum(none)

NAME
       bk checksum - check and/or fix BitKeeper per file checksums

SYNOPSIS
       bk checksum [-s[<offset>]] [-fv] [-r<rev>] [<file> ... | -]

DESCRIPTION
       BitKeeper has more integrity checksums than the original SCCS had (SCCS
       had  one  over the whole s.file).  BitKeeper maintains a checksum which
       is compatible with SCCS and also a set of new checksums, one per delta.
       This command is typically used to check and/or regenerate the per delta
       checksums.  Without any options, the default behavior is to just  check
       each checksum warn about any checksums that are missing or incorrect.

       This command may also be used to print a list of checksums of arbitrary
       data, see the -s option.

WARNING
       The  per delta checksums are part of the delta keys which are contained
       in the ChangeSet file.  These keys are part of the metadata which  Bit-
       Keeper  uses  to  group  deltas  into changesets.  If the checksums are
       changed, the checksums in the ChangeSet file  must  be  correspondingly
       changed,  and  the  process  repeated  for each copy of the repository.
       Needless to say, we do not encourage the use of this command  with  the
       -f option unless you are very sure of what you are doing.

OPTIONS
       -f         fix any missing or incorrect checksums.
       -r<rev>    Limit  checks  to one revision.  Faster than checking
                  the whole file if the problem delta is known.
       -s[<off>]  generate and print the SCCS  style  16  bit  unsigned
                  checksum  starting  at offset off.  If off is 8, then
                  this generates the same  checksum  as  the  per  file
                  checksum.  If there are no file arguments, reads data
                  from  stdin  (note:  differs from other options which
                  obey the normal BitKeeper file expansion rules).
       --safe-fix Only do fixes which do not alter the  deltakey.   The
                  fix removes an unneeded merge parent.
       -v         be verbose.

SEE ALSO
       bk help check

WARNINGS
       Do  not depend on per file checksums being SCCS compatible, Bit-
       Keeper is likely to move to a CRC in a future release.

CATEGORY
       Admin

BitKeeper Inc                         1E1                    bk checksum(none)
$
help://chmod
help://chmod.1
help://bk-chmod
help://bk-chmod.1
bk chmod(none)              BitKeeper User's Manual             bk chmod(none)

NAME
       bk chmod - change the mode of a file and save it

SYNOPSIS
       bk chmod [<ugoa>]+<rwxs> <file> [<file> ...]
       bk chmod [<ugoa>]-<rwxs> <file> [<file> ...]
       bk chmod [<ugoa>]=<rwxs> <file> [<file> ...]
       bk chmod <octal> <file> [<file> ...]

DESCRIPTION
       The chmod command changes the stored file modes (permissions) for files
       in the repository.  File modes are normally whatever modes were present
       on  the  file was when it was checked in to BitKeeper.  When changes to
       the file mode need to be made, the bk chmod command is used  to  record
       the new modes.

       The syntax is one of

       [<ugoa>]+<rwxs>  A  symbolic  way  of adding permissions.  <ugoa> indi-
                        cates the users to which the permissions apply, a com-
                        bination of one or more  of  the  following:  "u"  for
                        user,  "g"  for group, "o" for other, and "a" for all.
                        If none are specified  the  default  is  "a".   <rwxs>
                        indicates  the permission to add, a combination of one
                        or more of the following: "r" for read, "w" for write,
                        "x" for execute, "s" for setuid or setgid depending on
                        <ugoa>.
       [<ugoa>]-<rwxs>  A symbolic way of removing permissions.  As above.
       [<ugoa>]=<rwxs>  A symbolic way of setting permissions absolutely.   As
                        above.
       <octal>          A  4  digit  octal  number wherein 04000 means setuid,
                        02000 means setgid, and in the following three  digits
                        4 means read permission, 2 means write permission, and
                        1 means execute permission.  The last three digits are
                        for user, group, other permissions respectively.  This
                        form  sets  the mode absolutely, it is not relative to
                        the previously recorded mode.

NOTES
       Setuid and setgid are not recommended since Windows  does  not  support
       that concept.  Similarly, group/other is also unsupported on Windows.

       Write  permission  is  somewhat  pointless  since BitKeeper will remove
       write permission if the file is checked out unlocked and add write per-
       mission if the file is checked out with a lock.

SEE ALSO
       bk help log

CATEGORY
       File

BitKeeper Inc                         1E1                       bk chmod(none)
$
help://citool
help://citool.1
help://bk-citool
help://bk-citool.1
bk citool(none)             BitKeeper User's Manual            bk citool(none)

NAME
       bk citool - BitKeeper graphical check-in tool

SYNOPSIS
       bk citool [<dir> | <file_list> | --no-extras  | -s<alias>]

DESCRIPTION
       The  citool  application  is a graphical interface for checking in new,
       modified, and pending files.  When called  with  no  arguments,  citool
       examines the current repository for files requiring checkin.  If called
       with  --no-extras,  citool  will  look only for modified and/or pending
       files (a performance win repositories in checkout:get or  checkout:none
       mode).   If  called  with  -s<alias> in a nested collection citool will
       restrict the repositories searched to those implied by <alias>.  Other-
       wise, citool will look in the list of arguments for files  or  directo-
       ries.  The arguments are processed by bk gfiles, and have to follow the
       restrictions imposed by bk gfiles.

       bk  citool  has three main windows that are positioned vertically.  The
       top window contains the list of files that  can  be  checked  in  to  a
       changeset.   The  middle window is used for entering comments about the
       selected file while the bottom window displays different things depend-
       ing on whether viewing a modified file or a  file  not  under  revision
       control.  For modified files, the differences between the modified file
       and its parent are shown and for  new  files,  the  file  contents  are
       shown.

       Along the upper right side of the upper two windows are a group of but-
       tons. Some of the buttons have different purposes depending on what the
       user  is  doing.   For example, the "Checkin/Commit" button becomes the
       "Commit" button when there are comments for the ChangeSet file.  Other-
       wise, the button is the "Checkin" button which signifies that the files
       will be checked in, but no ChangeSet will be created.  The Checkin fea-
       ture is useful when checkpointing files to save state when you know you
       want to make changes that may break things.  Other times  you  want  to
       checkpoint  when  you've created distinct new work and want to get back
       to it in the future.

       Typical usage is to move to each file, add comments, and  repeat  until
       done.   When  all  files  are  commented  and  a comment exists for the
       ChangeSet file, the "commit" button is pressed to make the changes part
       of a ChangeSet.  bk citool's default behavior is to exit after the com-
       mit finishes. However, the ci.rescan configuration option forces citool
       to rescan the repository for files that still need to  be  added  to  a
       changeset.  This  feature is useful when modifying files that should be
       in separate changesets. For example, if you modify five files and three
       of those files form a logical unit of work, you can start  citool,  add
       the  three  files  to a changeset and then commit. After committing the
       files to a changeset, citool  returns  so  that  you  can  comment  the
       remaining files and add them to a new changeset. Basically, this option
       prevents  the  user  from restarting citool multiple times if all files
       are not added to a changeset.

       You can move around within the file list by clicking on a file name  or
       using  the  keyboard  accelerators  Control-n (next file) and Control-p
       (previous file).  You may add comments, move  around,  come  back,  and
       update  the  comments.  The comments are not applied to the files until
       "[Commit]" is clicked.

       The question mark icon to the left of the file name denotes files  that
       are  not under revision control. To add the new files to the changeset,
       click on the question mark icon or use the Control-t  key  to  add  the
       file  to  the current changeset.  Clicking on the question mark changes
       the icon to a check mark, indicating that the file will be part of  the
       cset.

       Some  of the new files might be files that you do not wish to put under
       revision control and having them visible clutters up the  file  window.
       When a new file is highlighted, the "Ignore" button is activated on the
       button  bar  menu.  If you click the "ignore" button, the selected file
       will be added to the BitKeeper/etc/ignore file so that when  citool  is
       run  again,  the  selected file will not be shown.  If you accidentally
       click "ignore" on a file that you want, click  the  "Unignore"  button.
       The  BitKeeper/etc/ignore  file  is  not updated until the changeset is
       committed. The ignore file is a revision controlled file like any other
       BitKeeper file and can be edited with a text  editor  if  you  want  to
       remove  or add files to the ignore list.  The entries that are selected
       to be ignored are not added to the ignore file until the  changeset  is
       committed.

       At  times,  you might wish to exclude files from a changeset. For exam-
       ple, if you are working on a file and have made changes to it  (changes
       can  be  committed  and  in  the  pending  state), but don't want these
       changes to propagate when you push your work to another repository.  To
       exclude files from the changeset, use the left mouse button to click on
       the  file-type icon.  If the file can be excluded, the icon will change
       to a red X. If you try to exclude a pending file while a modified  ver-
       sion of the file exists, both the pending and the modified file will be
       excluded.  It  is  possible to exclude the modified file, while keeping
       the pending file in an included state.

       When you move to a file, the differences for this file are shown in the
       bottom window.  When entering comments, it is normal to want to  scroll
       the  differences  window (assuming that the differences are larger than
       the window).  While this can be done using the mouse and the scrollbar,
       the following keyboard accelerators will work at all times,  even  when
       typing in the comments window:

COMMENT TEMPLATES
       bk  citool  supports the ability to define a system-wide template to be
       used for the ChangeSet comments. This file is documented in the bk tem-
       plates man page.

       If a template exists it will be loaded into the ChangeSet  comments  if
       there  are  no  pre-existing  comments.  The  comments may be edited as
       usual; if the comments are not modified they  will  be  treated  as  if
       there are no comments. That is, if the ChangeSet comments are identical
       to the template no changeset will be created, as is the case when there
       are no comments in the window and you press the "checkin" button.

KEYBOARD BINDINGS
       Home            Scroll to the start of the differences
       End             Scroll to the end of the differences
       PageUp          Scroll the differences up 1 screen
       PageDown        Scroll the differences down 1 screen
       #BKMOD#-c       Copy  the  selected  text in the comments window to the
                       clipboard.
       #BKMOD#-v       Paste the contents of the  clipboard  to  the  comments
                       window.
       #BKMOD#-x       Cut  the  selected  text  in the comments window to the
                       clipboard.
       #BKMOD#-Shift-x Delete the contents of the  comments  window  and  save
                       them in the citool pasteboard.
       #BKMOD#-Shift-v Paste  the  contents  of the citool pasteboard into the
                       comments window, completely replacing any existing com-
                       ments, and advance to the next file.
       Middle-Button   On Unix, this will paste the X11 selection buffer  into
                       the comments window.
       Control-n       Go to the next file
       Control-p       Go to the previous file
       Control-l       Rerun the diffs in case an external program has changed
                       the file.
       Control-t       Toggle   include/exclude  state  and/or  add/don't  add
                       state.  See the  text  about  include/exclude  and  new
                       files.
       Control-Shift-t Toggle all new files into or out off the changeset.
       Control-Enter   Do the commit. Same as clicking on the "Commit" button.
       #BKMOD#-q       Same as clicking the "[Quit]" button.
       Control-b       Scroll the differences up 1 screen
       Control-f       Scroll the differences down 1 screen
       Control-u       Scroll the differences up 1/2 screen
       Control-d       Scroll the differences down 1/2 screen
       Control-e       Scroll the differences down 1 line
       Control-y       Scroll the differences up 1 line

EDITING THE COMMENTS
       The  comments  window  is  a standard TK text widget with word and line
       erase added.  Moving around is done with the arrow keys,  backspace  to
       delete  the  previous  character, Control-w (or Alt-w) to erase a word,
       and Alt-u to erase a line.

BUTTONS
       There are a series of buttons on the right.  They perform the following
       functions:

       [Cut comments]    deletes the contents of the  current  comment  window
                         and saves them in the clipboard.
       [Paste comments]  paste the contents of the clipboard into the comments
                         window,  completely  replacing any existing comments,
                         and advance to the next file.
       [Commit]          displays all comments in the differences  window  and
                         asks if you want to commit.
       [Edit]            a  pull down menu, giving you the choice of running a
                         simple TK based editor or your $EDITOR on the current
                         file.  Saving the file in the editor  will  overwrite
                         the  current  file.  The pull down also has an option
                         to pop you into bk fmtool on the checked  in  version
                         and  the  current  version of the file.  You may then
                         select the changes  you  do  not  want  to  keep  and
                         "merge" the two versions to a new version, which will
                         replace the current file.
       [History]         starts up revtool on the current file
       [Diff tool]       starts  up  difftool on the previous/current versions
                         of the file.
       [Discard]         destroys the changes made to  the  current  file,  in
                         other words, throws away the differences.
       [Ignore]          When  a  new file is selected, the ignore button will
                         add the selected  file  to  the  BitKeeper/etc/ignore
                         file.
       [Unignore]        When  a  new  file  is  selected and is in the ignore
                         state, the "Unignore" button  prevents  the  selected
                         file  from  being  added  to the BitKeeper/etc/ignore
                         file.
       [Help]            Starts up the BitKeeper help tool and  displays  this
                         help.
       [Quit]            Quits.   If  you  have  provided  comments, this will
                         prompt you to save your comments or discard you  com-
                         ments.

LOCKING
       If  the repository is locked, and you try to bk commit, the commit will
       fail.  You can wait for the lock to go away and  then  try  the  commit
       again;  it  should  succeed.   If the lock is an invalid one (left over
       from an old remote update), then you can switch to another  window  and
       unlock the repository.   After it is unlocked, the commit should work.

SEE ALSO
       bk  help  config-gui, bk help delta, bk help fmtool, bk help ignore, bk
       help gfiles, bk help templates

CATEGORY
       Common
       GUI-tools
       Repository

BitKeeper Inc                         1E1                      bk citool(none)
$
help://clean
help://clean.1
help://bk-clean
help://bk-clean.1
bk clean(none)              BitKeeper User's Manual             bk clean(none)

NAME
       bk clean - removes unmodified files

SYNOPSIS
       bk clean [-pqv] [<file> ... | -]

DESCRIPTION
       The  bk clean command is used to remove (clean) all unmodified, checked
       out files from the current directory, regardless of  whether  they  are
       checked-out in a locked or unlocked state.

       If  there  are  files which are both locked and modified, bk clean will
       refuse to delete them and will instead list them as needing a check-in.

OPTIONS
       -p  Prints diffs for all modified files. The diffs are printed  in  the
           least readable diff format; you may prefer to use

               bk -cr diff -up

       -q  Run quietly.
       -v  Run verbosely.

SEE ALSO
       bk help diff, bk help unedit

CATEGORY
       Common
       File

BitKeeper Inc                         1E1                       bk clean(none)
$
help://clone
help://clone.1
help://bk-clone
help://bk-clone.1
help://lclone
bk clone(none)              BitKeeper User's Manual             bk clone(none)

NAME
       bk clone - create a new copy of a package

SYNOPSIS
       bk clone [-q] [-r<rev>] [-s<alias>] [<more opts>] <from> [<to>]

DESCRIPTION
       The  clone command copies from the <from> repository and creates a copy
       at <to>.  If <to> is not specified then the basename of <from>  is  the
       implied  destination.   This  works  for  fully and partially specified
       pathnames as well as BitKeeper URLs.  See bk help url for further  nam-
       ing information.

       If  <bam_url> is specified, it tells the destination repository what to
       use as a BAM server.  Normally a new repository inherits the BAM server
       URL from the source repository.  This argument is required when cloning
       a BAM server to a BKD.

       If <rev> is specified, the cloned repository will include only  change-
       sets up to and including <rev>.

       When cloning a product, the set of components to populate is defined by
       the  -s  option.   If  -s is not specified on the command line then the
       alias in the clone_default  config  is  used.   Without  clone_default,
       -sALL is used as a default.

       The  cloned  repository  remembers from which repository it was cloned.
       The <from> repository is known as the "parent," while the newly  cloned
       repository is known as the "child."

       Subsequent  updates  to  the  child  can  be  done  by running bk pull.
       Changes made in the child can be pushed back into the parent by running
       bk push.

NOTE
       Only completed changesets are cloned.  Any pending deltas  are  removed
       from the child before the clone completes.

       On  recent  (2014)  versions of Ubuntu (and other Linux distributions),
       the use of hardlinks has been curtailed for  security  reasons.   Clone
       will   fall   back  to  using  copies,  see  http://man7.org/linux/man-
       pages/man5/proc.5.html  and  search  for  protected_hardlinks.    Using
       copies  instead of links is slower and takes more disk space so you may
       want to disable this security feature if all of your users are trusted.

OPTIONS
       -@<base_url>      Use a local repository as a baseline for the clone so
                         that only the changes need to be transferred  from  a
                         remote location.
       -B<url>           Set  the  BAM  server url to <url> in the destination
                         repository.
       --checkout=<mode> Override any previous setting for the checkout  mode.
                         Valid values for <mode> are none, get, or edit.  Note
                         that  this mode becomes "sticky" in that the checkout
                         mode will  added  to  `bk root`/BitKeeper/log/config.
                         If  no  other  config  overrides that, then this mode
                         will "stick" for subsequent updates.
       --downgrade       By default, new clones will use the same storage for-
                         mat as the repository  being  cloned.   This  options
                         forces the new clone to use the older, backwards com-
                         patible format (at the cost of lower performance).
       -E<env>=<val>     Export  an environment variable to the bkd running in
                         the remote BitKeeper repository.  Typically  used  to
                         pass  information to remote triggers.  Only variables
                         with the prefix BKU_ are allowed.
       --identical       When cloning a product, have  the  set  of  populated
                         aliases  be identical to the repository where the tip
                         ChangeSet was created.  This option  is  incompatible
                         with -s.
       -j<jobs>          Set  the  level  of parallelism for the unpacking and
                         checking out of files.
       --no-hardlinks    Clone nomally uses hard links whenever it can.   This
                         option  will  prevent this and is useful to create an
                         archive of a repository that copies every file.
       --parents         Instead of setting the parent to the <from> url,  use
                         <from's>  parents.   Useful  when  you  want  to pull
                         from/push to the same places as <from>.
       -q                Run quietly.
       -r<rev>           Clone the repository up to and including cset  <rev>.
                         A  changeset  number  or changeset key can be used to
                         specify <rev>.  See bk help terms for  more  informa-
                         tion.
       -s<alias>         When  cloning  a product, limit the components to the
                         subset  implied  by  <alias>.   If  this  option   is
                         repeated the implied subset is the union of all spec-
                         ified  components.   <alias> may be a component or an
                         alias for a set of components.   The  option  -sTHERE
                         can  be use to make the destination of the clone have
                         the same components populated as the source.
       --upgrade         By default, new clones will use the same storage for-
                         mat as the  repository  being  cloned.   This  option
                         forces the new clone to upgrade to the latest storage
                         format.  In bk-6.0, the storage format was changed to
                         support higher performance.

SEE ALSO
       bk  help alias, bk help bam, bk help bkd, bk help parent, bk help pull,
       bk help push, bk help relink, bk help terms, bk help triggers, bk  help
       url

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                       bk clone(none)
$
help://cmdlog
help://cmdlog.1
help://bk-cmdlog
help://bk-cmdlog.1
bk cmdlog(none)             BitKeeper User's Manual            bk cmdlog(none)

NAME
       bk cmdlog - show the log of commands executed in this repository

SYNOPSIS
       bk cmdlog [-S] [-a] [-v] [-c<cutoff>] [pattern]
       bk cmdlog [-r] [-c<cutoff>] [pattern]

DESCRIPTION
       List the history of repository level commands run in repository of cur-
       rent  directory.  Repository level commands are bk clone, bk commit, bk
       export, bk pull, and bk push.

       Commands are listed in least recent to most recent order.

OPTIONS
       -a         List history of all commands run in the repository, not just
                  repository level commands.
       -c<cutoff> List commands which happened during the date range specified
                  by <cutoff>.
       -r         List command start and stops with relative  times.   Implies
                  -a.
       -v         Each  line  of output is prefixed with userid, timestamp and
                  BK version.  Combined with  the  -a  option,  everything  is
                  listed, including commands run by BK itself.

                  Additionally,  in a nested collection, each output line will
                  list the component name in brackets, ie. [component]
       -S
       --standalone
                  When used in a nested collection, only process the  log  for
                  the current component.
       pattern    Limit the output to lines matching (regexp) pattern.

EXIT STATUS
       bk cmdlog returns exit status 0.

NOTES
       The  two  command logs are maintained by BitKeeper in the BitKeeper/log
       directory.  repo_log contains all repository level commands ever run in
       that repository.  cmd_log contains recent commands run in that  reposi-
       tory.

       In  the cmd_log file, commands are logged at the time they start and at
       the time they finish.  By default, cmdlog output is limited to the lat-
       ter.  Using the -av options, both the start and finish of  commands  is
       listed (as well as other events such as trigger launches).

       The  relative  times displayed by the -r option are only printed if the
       bk version logged those times.  Earlier versions of BitKeeper  did  not
       log this data so it will not appear in the output.

       When  using the -r option, the relative time is in seconds and relative
       to the first user level command (for example, the start of  a  bk  pull
       would  be 0 seconds, all the subordinate logs will be relative to that.
       The final entry will represent the run time of the pull command).

SEE ALSO
       bk help range

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk cmdlog(none)
$
help://collapse
help://collapse.1
help://bk-collapse
help://bk-collapse.1
help://uncommit
help://fix
help://rebase
bk collapse(none)           BitKeeper User's Manual          bk collapse(none)

NAME
       bk collapse - combine recent changesets into a single unit of work

SYNOPSIS
       bk collapse [-lqS] -e [-a<rev>] [-@[<url>]]

DESCRIPTION
       bk collapse allows you to combine (collapse) the most recent successive
       changesets  made in a repository.  You typically use this when complet-
       ing a develop-review-test-debug-fix cycle to combine  a  changeset  and
       all  its  bug-fix and review-generated changesets into a single logical
       unit of work.  In this usage, you specify a revision with "-a",  speci-
       fying that all changesets since that revision be collapsed.

       Note:  Currently, the "-e" option is required; the modifications intro-
       duced by the changesets to be collapsed are  applied  to  the  affected
       files, which are left as locked, modified files in the repository.  You
       must  subsequently  use  bk  citool  or bk delta/commit to commit these
       edits as a single changeset.  bk collapse preserves  all  checkin  com-
       ments  for individual files and for the collapsed changesets; bk citool
       then uses these saved checkin comments to populate the comments  fields
       for all affected files and the ChangeSet file.

       You  can  use  bk  collapse without the "-a" option immediately after a
       checkin if you realize that the change was not done or  was  incorrect.
       You can do this "uncommit" on the most recent changeset only if you are
       positive  that  there  are  no  other copies of this changeset in other
       repositories.

       The checkin comments are preserved if you use bk  citool  to  make  the
       subsequent checkin.

       The -l option to bk collapse saves a list of the md5keys of all change-
       sets  that  have  been  replaced  by  the  this  command  in  the  Bit-
       Keeper/etc/collapsed file.  Later bk pull examines this file to prevent
       the uncollapsed csets from being pulled into the  repository  with  the
       collapsed versions.

       bk  collapse  saves  a  backup patch in BitKeeper/tmp/collapse.patch in
       case it turns out that the collapse was the wrong idea.

OPTIONS
       -@[<url>]     If the current repository is a  strict  superset  of  the
                     repository  at url then collapse will replace all change-
                     sets not in url with a single collapsed cset.  If url  is
                     omitted  then  the  current  repositories  parent is used
                     instead.
       -a<rev>       Collapse all changesets that occurred after <rev>.
       -e            Leave the resulting changes as  locked,  modified  files;
                     you  must  run bk citool or bk delta/commit to create the
                     final changeset.
       -l            Record the csetkeys of the changesets being  replaced  in
                     the BitKeeper/etc/collapsed file.
       -S
       --standalone  Just  collapse the current component.  This has no effect
                     in a traditional standalone repository, but in  a  nested
                     collection,  it  collapses just the current component and
                     not the entire collection.
       --no-save     when fixing the entire changeset the normal  behavior  is
                     to  save a backup patch of all the csets being removed in
                     BitKeeper/tmp/collapse.patch  in  case   something   goes
                     wrong.   This option disables this safety net for a minor
                     performance gain.
       -q            suppress most messages

EXAMPLES
       Fix a problem in the latest cset.

           $ bk collapse -e
           $ bk citool

       Collapse all csets not in my parent into a single cset.

           $ bk collapse -e@
           $ bk citool

SEE ALSO
       bk help citool, bk help commit, bk help delta, bk help  edit,  bk  help
       makepatch, bk help stripdel, bk help undo

CATEGORY
       Repository

BitKeeper Inc                         1E1                    bk collapse(none)
$
help://comments
help://comments.1
help://bk-comments
help://bk-comments.1
help://comment
bk comments(none)           BitKeeper User's Manual          bk comments(none)

NAME
       bk comments - change checkin comments

SYNOPSIS
       bk comments [-p] [-C<cset>] [-r<rev>] [<file> ... | -]
       bk comments [-C<cset>] [-r<rev>] [-y<cmt>] [-Y<file>] [<file> ... | -]

DESCRIPTION
       The bk comments command changes the stored comments for a revision con-
       trolled file.  The comments may be specified on the command line, or if
       they  are  not,  you  will be placed in your editor to type in the com-
       ments.

       If given "-" for a file argument, bk comments reads a list of files and
       comments to be edited from stdin.  The format looks like this:

           ### Comments for file.c|1.23
           this is a sample comment
           ### Comments for file2.h|1.2.3.4
           these are
           other comments

OPTIONS
       -r<rev>     Change  the  comments  for  the  specified  revision.   The
                   default is the most recent revision.
       -y<comment> Use <comment> as the new comment for all files.
       -Y<file>    Use  the  contents  of  <file>  as  the new comment for all
                   files.
       -C<rev>     Edit all the file comments on the  requested  changeset  at
                   once.  May not be combined with "-r".
       -p          Generate  the  list  of all comments in the files requested
                   and write them to stdout.  This file can be edited and then
                   later fed into "bk comments -" on stdin to change the  com-
                   ments.

       If  no files to edit is given on the command line then "-C+" is assumed
       and the comments for the files in the last changeset are edited.

BUGS
       Nota bene: if the deltas being  commented  have  been  committed  to  a
       changeset  and  have  been  pulled  out of this repository, the comment
       changes will not propagate on the next bk pull.  It  is  strongly  sug-
       gested  that  you  use  this  only on uncommitted deltas which have not
       been pulled or cloned.  In the future, we will add a way  of  enforcing
       this.

SEE ALSO
       bk help log, bk help sccslog

CATEGORY
       File

BitKeeper Inc                         1E1                    bk comments(none)
$
help://commit
help://commit.1
help://bk-commit
help://bk-commit.1
help://changeset
help://changesets
bk commit(none)             BitKeeper User's Manual            bk commit(none)

NAME
       bk commit - commit deltas to a changeset

SYNOPSIS
       bk  commit  [-cfq] [-l<file>] [--tag=tag<>] [-sALIAS<>] [-S] [-Y<file>]
       [-]
       bk commit [-cfq] [-l<file>] [-y<comment>] [-]

DESCRIPTION
       This command commits work to a changeset, creating a logical  group  of
       changes which can span multiple files and/or multiple deltas within one
       or more files.

       If  the  command line does not have a trailing dash then bk commit will
       search the repository for any files which are in "pending" state, i.e.,
       have deltas which do not yet belong to a changeset, and groups  all  of
       them  into a changeset.  If the trailing dash is present, then the com-
       mand takes the list of files to commit from the  standard  input;  each
       line of input must be of the format:

           <sfile>|<rev>

       where  <sfile>  is an sfile name as described in bk filetypes and <rev>
       is a file revision number, such as 1.1 or 1.2. Example: SCCS/s.foo|1.2.
       This is the same format produced by "bk  gfiles  -pA"  and  "bk  gfiles
       -pC".

       Note: <rev> specifies the most recent change to commit; all uncommitted
       changes prior to <rev> are also included.

       You  can  see what will be added to a changeset when you commit by run-
       ning:

           $ bk pending

       All revisions which you have checked in will become part of  a  change-
       set.  As part of the commit step, you will be prompted for comments (if
       none  were provided on the command line).  The comments should describe
       the logical change that you have made; these comments are what will  be
       displayed by bk changes.

       If  no  comments are provided and there is a BitKeeper/templates/commit
       file present in the repository, then the default comments are the  con-
       tents of that file.

       Note:  using bk citool is the preferred way to commit. Not only will bk
       citool help with checking in files, it will also create a changeset  if
       you enter ChangeSet comments.

       Note:  using  the  default comments on an import is not advisable.  The
       default comments contain information about each  file  and  can  create
       very  large  comment entries in the ChangeSet file.  The ChangeSet file
       is the center of activity in BitKeeper,  and  having  an  unnecessarily
       large one will not help performance.

OPTIONS
       -c            Use comments saved by a previous run of citool, fix, col-
                     lapse,  etc.   It  is an error if there are no saved com-
                     ments.
       --ci          Check in any edited files as part of the commit.
       -f            Don't run interactively; do the commit with  the  default
                     comments.  Ignores the commit template, if any.
       -l<file>      Get  the  list of files to commit from <file>.  Each line
                     of this file must use the <sfile>|<rev> format  described
                     above.
       -q            Run quietly.
       -sALIAS       Commit  all pending files in the given aliases as well as
                     the PRODUCT.  Use -sPRODUCT if the top  level  commit  is
                     not wanted.
       -S
       --standalone  Commit only in the current repository.
       --tag=<tag>   Tag the tree with <tag> at the same time as the commit.
       -Y<file>      Get check-in comment for changeset from <file>.
       -y<comment>   Set check-in comment of changeset to <comment>.

SEE ALSO
       bk  help  changes,  bk help citool, bk help import, bk help pending, bk
       help gfiles, bk help status, bk help tag, bk help templates

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk commit(none)
$
help://comps
help://comps.1
help://bk-comps
help://bk-comps.1
bk comps(none)              BitKeeper User's Manual             bk comps(none)

NAME
       bk comps - list the components belonging to a product

SYNOPSIS
       bk comps [-hmk] [-s<alias>]

DESCRIPTION
       The bk comps command is used to list all repositories that are attached
       to the product.

       The  normal  output  is all components attached to the product, whether
       present or not.  The options can be used to restrict the output depend-
       ing on if the components are currently populated or not.

OPTIONS
       -h        Only list components currently populated, or "here".
       -k        Instead of the default relative paths from the product  root,
                 list the root keys for each component.
       -m        Only list components not currently populated, or "missing".
       -s<alias> List all components that belong to <alias>.

SEE ALSO
       bk help alias, bk help attach, bk help here

CATEGORY
       Nested

BitKeeper Inc                         1E1                       bk comps(none)
$
help://config
help://config.1
help://bk-config
help://bk-config.1
bk config(none)             BitKeeper User's Manual            bk config(none)

NAME
       bk config - show repository configuration information

SYNOPSIS
       bk config [-v]

DESCRIPTION
       The bk config command displays configuration information, consisting of
       key-value pairs, associated with a BitKeeper repository.

       Repository  configuration  information is searched for in the following
       places, in order:

       `bk root`/BitKeeper/etc/config     This repository's config file
       `bk root -P`/BitKeeper/etc/config  Product repository config file
       `bk dotbk`/config                  Personal config file
       /etc/BitKeeper/etc/config          Per-machine config file
       `bk bin`/config                    Per-installation config file
       `bk root`/BitKeeper/log/config     This repository's config file
       `bk root -P`/BitKeeper/log/config  Product repository config file
       $BK_CONFIG                         Environment variable

       The  BitKeeper/etc/config  file  is  version   controlled,   the   Bit-
       Keeper/log/config  file  is  not.   Having  two gives you a way to have
       repository specific values that do not propagate.

       For each key-value pair, the first instance of a  key  found  is  used.
       You  can  override  an  earlier  value  with a later value, however, by
       appending an exclamation point to the value (not the key):

           checkout: get!

       If multiple instances of a key  value  are  found  with  this  trailing
       exclamation point, the last such value found is used.

       The  BK_CONFIG environment variable may contain a list of <key>:<value>
       pairs separated by semicolons.  For example:

           BK_CONFIG=key1:value1;key2:value2;key3:value3

       For each repository, the various sources of configuration data  collec-
       tively must specify values for at least the following keys:

           description:
           email:

       (See "CONFIG FILE ENTRIES" in bk help config-etc for allowed values.)

       You  can  specify  a  default config file to make setup easier and more
       consistent for every repository on the system by creating a template in
       `bk dotbk`/config.template, /etc/BitKeeper/etc/config.template, or  `bk
       bin`/config.template.  If any of those files exists, bk setup automati-
       cally  uses the keys in the first one found as the BitKeeper/etc/config
       file.  See bk help setup for more information.

OPTIONS
       -v  Displays the location of all config key-value pairs in the  current
           configuration.   This  allows you to determine which config file is
           controlling each item in your configuration.  Items  that  are  not
           being  used because they are preceded or overridden by other values
           are shown with a leading pound sign  (`#').   This  is  useful  for
           debugging your configuration.

EXAMPLES
       Suppose  a  user  is trying to determine why his keywords are not being
       expanded as desired, even though he has put it in $BK_CONFIG.  "bk con-
       fig -v" shows that the his personal config file value for "keyword"  is
       taking precedence over that in $BK_CONFIG.

           $ bk config -v
           /repos/fred/testrepo/BitKeeper/etc/config:
           #    autofix:        no
                description:    Fred's Test repository
           #    keyword:        sccs

           /home/fred/.bk/config:
                keyword:        rcs!

           /etc/BitKeeper/etc/config:

           /usr/local/bitkeeper/config:

           $BK_CONFIG:
                autofix:        yes!
           #    keyword:        sccs

       The  output also shows that the autofix value in $BK_CONFIG is overrid-
       ing the corresponding value in the repository config file  because  the
       exclamation mark is appended.

SEE ALSO
       bk help config-etc, bk help config-gui

CATEGORY
       Admin

BitKeeper Inc                         1E1                      bk config(none)
$
help://config-etc
help://config-etc.1
help://bk-config-etc
help://bk-config-etc.1
help://configuration
help://user preferences
help://repository preferences
bk config-etc(none)         BitKeeper User's Manual        bk config-etc(none)

NAME
       bk config-etc - configuring BitKeeper

DESCRIPTION
       BitKeeper  config  files  contain  repository configuration information
       including project description, licensing information, user preferences,
       BK/Web preferences, and contact information.  Config file entries  take
       the  form of key-value pairs.  This page describes the various configu-
       ration keys and their possible values.

       Each BitKeeper repository must have some minimum configuration informa-
       tion available in order to properly execute BitKeeper commands.  Repos-
       itory configuration  information  is  searched  for  in  the  following
       places, in order:

       `bk root`/BitKeeper/etc/config     This repository's config file
       `bk root -P`/BitKeeper/etc/config  Product repository config file
       `bk dotbk`/config                  Personal config file
       /etc/BitKeeper/etc/config          Per-machine config file
       `bk bin`/config                    Per-installation config file
       `bk root`/BitKeeper/log/config     This repository's config file
       `bk root -P`/BitKeeper/log/config  Product repository config file
       $BK_CONFIG                         Environment variable

       The  BitKeeper/log/config  file[s]  are  not version controlled but the
       BitKeeper/etc/config file[s] are.  Having two gives you a way  to  have
       repository specific values that do not propagate.

       For  detailed  information  about how all the search order works, or to
       get help debugging your configuration, please see bk help config.

CONFIG FILE ENTRIES
   AUTOFIX
       The bk check command can automatically fix a number of  problems  found
       in a repository.  The default is that this variable is on in newly cre-
       ated  repositories, and that the variable will be passed through as the
       "-f" option to bk check.  To enable or disable autofix, one of the fol-
       lowing should be in your configuration:

           autofix:yes
           autofix:no

   AUTOPOPULATE
       Cause all (nested) pull operations to use  the  --auto-populate  option
       (thus bringing in missing components as needed).  Default is no.

           auto_populate:yes
           auto_populate:no

   BAM SIZE
       The optional BAM variable controls how large a binary needs to be to be
       stored in BAM.  The size is compared to the size of the initial checkin
       only.  Example values the variable may hold are:

           BAM: on
           BAM: off
           BAM: 1K
           BAM: 64K

       A  "K"  suffix  means  multiply by 1024, a "M" suffix means multiply by
       1024^2.  The default size, if not specified, is 64K.

   BK/WEB PREFERENCES
       BK/Web preferences can be specified your configuration.  If these pref-
       erences are specified, information given will appear on the BK/Web site
       for the project.

       bkweb    specify the BK/Web address for a project
       homepage the home page for your project or company
       master   the location from which source can be cloned

       For example,

           bkweb:    http://mysql.bkbits.net:8080/mysql-5.0
           master:   bk://mysql.bkbits.net/mysql-5.0
           homepage: http://www.mysql.com

   CHECKOUT MODE
       Specify checkout mode for a  repository.   If  unset,  the  default  is
       "none".   To change the default, add or change the following line to/in
       your configuration:

           checkout:<option>

       where option is one of:

       get  Automatically do a bk get <file> after doing a  bk  delta  <file>.
            (Checkout in read-only mode.)
       edit Automatically  do  a bk edit <file> after doing a bk delta <file>.
            Note: This will also adjust the modification time of the s.file to
            be two seconds before the modification time of the gfile, which is
            needed in order to prevent make(1) from attempting to  re-get  the
            file.  (Checkout in edit mode.)
       last Preserve the previous state of <file>.  This is like checkout:none
            for a clone.  If the file was later locked and then checked in, it
            will be checked out again with a lock.
       none Clear  the  gfile  after  doing  a  bk delta <file>.  (This is the
            default.)

       For those repositories with BAM data, there is a checkout mode specifi-
       cally for BAM files:

           BAM_checkout:option

       where option is as above.

       The BitKeeper support team recommends "BAM_checkout:last".

   CLOCK SKEW
       When BitKeeper is looking for modified files, file time stamps  can  be
       compared  to a per-repo database to determine when files are unmodified
       leading to a substantial performance improvement  in  larger  reposito-
       ries.   The  "clock_skew"  parameter  controls  how  old a file must be
       before file time stamps are to be trusted.  A certain amount  of  clock
       skew  is  strongly  advised  since  the use of network file systems can
       cause the time stamps to be incorrect.  The  time  is  in  seconds  and
       defaults to 604800 (one week).

           clock_skew: on          # use system defaults
           clock_skew: 86400       # one day
           clock_skew: off         # disable trusting of time stamps

   CLONE DEFAULT
       When  cloning  a  nested collection, if the -s option is not used, then
       the  "clone_default"  option  specifies  the  default  set  of   compo-
       nents/aliases  to  clone.   If "clone_default" is not set then "ALL" is
       implied.

           clone_default: THERE    # always match remote repository
           clone_default: PRODUCT  # only the product, no components
           clone_default: ALL      # all components cloned by default
           clone_default: MYALIAS  # clone MYALIAS by default

   COMPRESSION
       By default, when you setup a repository in compatibility mode, the com-
       pression algorithm will be set to gzip in your  configuration  as  fol-
       lows:

           compression:gzip

       This results in the compression of stored s.files.  To make the reposi-
       tory  use  no  compression by default, change the compression line your
       configuration to be:

           compression:none

       See bk help admin for more information about the "-Z" option  for  com-
       pression.

   DESCRIPTION
       The  config file must contain a one line description of the contents of
       the repository.

           description: cross-platform C-like GUI programming language

   KEYWORD EXPANSION
       Keyword expansion is turned OFF by default.  To have keyword  expansion
       flags  applied  to  a  file automatically upon checkin, add the keyword
       preference to your configuration.

       Keyword preference options are:

       sccs           expand SCCS keywords (%keyword%).
       expand1        expand keywords in the first line that contains keywords
                      only (avoids printf conflicts).
       rcs            expand rcs keywords ($keyword$)

       For example, having

           keyword: sccs, expand1

       in the config file will expand SCCS keywords only  in  the  first  line
       encountered  that  contains  sccs  keywords.  Note: Setting this option
       affects only files created subsequently.

   LINE TERMINATION
       The UNIX and Windows operating systems use different characters to rep-
       resent line terminations (eoln).  BitKeeper, by default, sets the  eoln
       preference  to  native when an sfile is created.  This means that files
       checked out on Windows will have the Windows eoln and files checked out
       on UNIX will have the UNIX eoln.

       When a file is created, the line termination is taken from  the  "eoln"
       configuration  variable.   It is a per-file flag that may be overridden
       with the bk admin command.

       Line-termination preference options are:

       native  Set line termination to the native sequence  for  the  platform
               ("\n"  on  UNIX  and  Linux;  "\r\n" on Windows).  (This is the
               default.)
       unix    Force line termination to the UNIX standard ("\n").
       windows Force line termination to the Windows standard ("\r\n").

       To force the UNIX eoln mode on all platforms, your  configuration  must
       have this:

           eoln:unix

       To force Windows line termination use:

           eoln:windows

       In general, the default of native line terminations is the right answer
       and  for exceptions the bk admin command may be used to set this option
       on a per file basis.

   PARALLEL
       By default, BitKeeper runs some processes in parallel to  gain  perfor-
       mance.   The defaults are 8 way parallel for NFS and 3 way parallel for
       local file systems.  You may override the defaults for all  cases  like
       so:

           parallel:12

       Setting the value to 0 will disable parallelism.

   PARTIAL CHECK
       BitKeeper  may  be  configured  to do a full repository integrity check
       after each update.  The integrity check validates  both  internal  Bit-
       Keeper  metadata  and  file  checksums.  The integrity checks have been
       shown to catch hardware problems such as bad  memory  chips,  bad  disk
       drives,  and software problems such as NFS inserting blocks of nulls in
       the middle of files.  Unless you have a larger  repository  (more  than
       5,000  files  and/or  more than 100MB) then you may want to enable full
       checks all the time.

       By default, BitKeeper will run in partial_check  mode,  which  means  a
       full  check  is  performed  no more than once per week and only partial
       checks are performed when the repository is updated.

       You may control the frequency of the full  checks  with  the  following
       variable, units are in days.  To force a full check every two days:

           check_frequency: 2

       The  following  will disable the partial_check mode and force BitKeeper
       to perform full integrity checks on every update (safest but at a  per-
       formance cost):

           partial_check: off

   PULL STATISTICS
       It  is  possible  to  make pull print statistics in a format compatible
       with diffstats by adding this to your configuration:

           stats_after_pull: on

       Note that gathering the statistics needs another pass over the data  so
       if  you  are  very  performance  sensitive, you might want to keep this
       option off.

   SYNC
       In some environments it may be safer to have BitKeeper do  an  fsync(2)
       after  each  update of a history file.  Some Linux file systems perform
       poorly because fsync(2) is implemented as a system wide sync(2).

       The default is not to flush but the default may be overridden with:

           sync:on

   TRIGGER PATHS
       By default, triggers are  stored  in  the  repository  under  the  Bit-
       Keeper/triggers/ directory and this is the only directory searched when
       looking  for triggers.  More than one triggers directory may be used by
       setting the triggers variable.  The format is one or more  paths  sepa-
       rated by a vertical bar, each path has "BitKeeper/triggers" appended to
       it and the resulting path is scanned for triggers.  For example, if you
       wanted to run triggers from /etc/BitKeeper/triggers and from the repos-
       itories'  BitKeeper/triggers,  set the variable as follows in your con-
       figuration:

           triggers: /etc|.

       The directories are processed in the order found in the variable.

       There are several special values which are interpreted:

       .   This is the default, it means  `bk  -R  pwd`/BitKeeper/triggers  is
           scanned for triggers.

       $BK_DOTBK
           If present, `bk dotbk`/BitKeeper/triggers is scanned for triggers.

       $BK_BIN
           If present, `bk bin`/BitKeeper/triggers is scanned for triggers.

       $NONE
           If present, with no other values, then no triggers are processed.

       $PRODUCT
           If present, `bk -P pwd`/BitKeeper/triggers is scanned for triggers.
           This  only  applies when in a component repository of a nested col-
           lection.  It is a way to run product level triggers in each  compo-
           nent.

       $SOMETHING_ELSE
           All  other  paths  starting with "$" are ignored, that character is
           reserved.

   UPGRADE URL
       The upgrade command normally looks for new versions of BitKeeper  here:
       http://upgrades.bitkeeper.com/upgrades/  but that location may be over-
       ridden by setting the upgrade_url field to an different URL.

       For example,

           upgrade_url:   http://www.example.com/bk-release/

       The contents of that directory will need to be manually  mirrored  from
       BitKeeper Inc.

   USER PREFERENCES
       Repository  preferences  can be defined in your configuration: The gen-
       eral format for the repository preference config file is

           [filter]preference:option

       The optional filter can be any of the following:

       no filter      preference:option
       empty filter   []preference:option
       per user       [jdoe]preference:option
       per host       [@xyz.com]preference:option
       per pathname   [:/path/to/repo]preference:option
       per user@host  [jdoe@xyz.com]preference:option
       per repository [:/path/to/repo]preference:option
                      [@xyz.com:/path/to/repo]preference:option
                      [jdoe@xyz.com:/path/to/repo]preference:option

       Preferences can be listed multiple times with different  filters.   The
       filters  are examined in order and the first line that matches the cur-
       rent user, host, and pathname is used.  So in general the most restric-
       tive directives should appear first.

SEE ALSO
       bk help admin, bk help config-gui, bk help config, bk  help  setup,  bk
       help upgrade

CATEGORY
       Overview
       Admin

BitKeeper Inc                         1E1                  bk config-etc(none)
$
help://config-gui
help://config-gui.1
help://bk-config-gui
help://bk-config-gui.1
help://GUI
help://gui
help://GUI-config
help://gui-config
help://gui config
help://gui configuration
bk config-gui(none)         BitKeeper User's Manual        bk config-gui(none)

NAME
       bk config-gui - configuration for BitKeeper graphical tools

DESCRIPTION
       BitKeeper  uses a configuration file called config-gui for the configu-
       ration of the BitKeeper graphical tools.   The  configuration  file  is
       used to modify colors, fonts, and widget dimensions.

       The  location  of  this  configuration  file can be determined for your
       platform by running the command bk dotbk.  This command will return the
       pathname of the directory where the BitKeeper graphical tools will look
       for the config-gui file.

       The config file must be a valid tcl program as it is evaluated  by  the
       BitKeeper  GUI  tools  (which  are also tcl/tk programs).  The point of
       being a program is that tcl code may be added to  the  config  file  in
       order  to  customize  the gui based on arbitrary values such as machine
       name, screen size, etc.  For example, if all screens of a certain  size
       were  known  to  be LCD screens (typically laptops), then the following
       technique could be used  to  get  colors  more  appropriate  for  those
       screens:

           if {[winfo screenwidth .] <= 1024} {
                # These show up better on LCD displays.
                set gc(diffColor) gray
                set gc(activeDiffColor) lightseagreen
                set gc(fm3.handColor) yellow
           }

       The point of the config-gui file is to change configuration options.  A
       typical line looks like this:

           set gc(diffColor) #f0f0f0

       and the meanings for each part of that line are:

           set           tcl syntax for assigning variables
           gc(diffColor) configuration option
           #f0f0f0       hexadecimal color value

       Each  variable  in the config file may take one of two forms, tool spe-
       cific or global.  Tool specific variables,  which  apply  only  to  the
       named tool, have the tool name as a prefix, i.e.,

           set gc(cset.fixedFont)  {fixed 12 roman}

       whereas  global  variables,  which apply to all tools unless there is a
       tool specific version defined as well, look like

           set gc(fixedBoldFont) {fixed 12 roman bold}

       The tool names used to get to tool specific variables  (or  to  have  a
       change only apply to that tool) are the GUI tool's name with the trail-
       ing "tool" dropped, i.e., "diff" for "difftool".

TCL INFORMATION
       The  following  tcl/tk commands may be useful for display specific cus-
       tomization:

       [winfo depth .]        returns the color depth of the screen  in  bits,
                              i.e., 16 means the screen can do 65536 different
                              colors.
       [winfo screen .]       Returns  the name of the screen in the form dis-
                              playName.screenIndex,     i.e.,      "disks.bit-
                              keeper.com:0.0".
       [winfo screenheight .] returns the height of the screen in pixels.
       [winfo screenwidth .]  returns the width of the screen in pixels.

GUI CONFIGURATION
   GLOBAL CONFIGURATION
       The  following  is  a  list of variables used by the various gui tools.
       Each of these needs to be in a statement like:

           set gc(<variable>) <value>

       but in the list below we just show the <variable> part.

       fixedFont     Font used in all of the text widgets such as file  lists,
                     entry  boxes, and text widgets showing contents of files.
                     Defaults  to  values  that   match   appropriate   system
                     defaults.
       fixedBoldFont Bold  font  used  to  highlight  text  such as difference
                     within lines in bk difftool.   Defaults  to  values  that
                     match appropriate system defaults.
       diffColor     Color   of   the   changed   lines   in   a   diff  view.
                     Default: #EDEDED
       activeDiffColor
                     Color  of  the  selected  diff  block  in  a  diff  view.
                     Default: #2FEDAD
       oldColor      Color of the older revision or diff.
                     Overrides diffColor.  Default: #B48CFF
       newColor      Color of the newer revision or diff.
                     Overrides diffColor.  Default: #A8D8E0
       activeOldColor
                     Color  of  the  older selected diff block in a diff view.
                     Overrides activeDiffColor.  Default: #2FEDAD
       activeNewColor
                     Color of the newer selected diff block in  a  diff  view.
                     Overrides activeDiffColor.  Default: #2FEDAD
       highlightOld  Color  of  the  subline  highlighting  for old lines in a
                     diff.  Default: #FFA500
       highlightNew  Color of the subline highlighting  for  new  lines  in  a
                     diff.  Default: #FFA500
       noticeColor   Color for warnings and messages.  Default: #DBDFE6
       searchColor   Highlight  color  for search matches. Used in bk difftool
                     and bk revtool.  Default: #FFA500
       warnColor     Color  of  the  error  messages.  Used  in   bk   citool.
                     Default: #FFFF00
       textBG        Background  color  for  text  windows. Used in all of the
                     tools.  Default: #FFFFFF
       textFG        Text color.  Used in all of the tools.  Default: #000000
       tabwidth      The  width  of  a  tab  in  average   sized   characters.
                     Default: 8.
       quit          Key  used to exit from the gui tools.  Default: <Control-
                     q>

   CITOOL CONFIGURATION
       ci.commentsHeight height of the comments window.
       ci.diffHeight     height of the diffs window (the lower window).
       ci.display_bytes  Number of bytes to show in new files  in  bk  citool.
                         If   set   to   0,  the  entire  file  is  displayed.
                         Default: 8192
       ci.editHeight     Height of the popup editor.  Default: 30
       ci.editWidth      Width of the popup editor.  Default: 80
       ci.excludeColor   Color   of   the   exclude   icon   (X    character).
                         Default: #FF0000
       ci.filesHeight    number of files in the top window.
       ci.rescan         Set  this  to option to 1 if you would like bk citool
                         to run again after doing the  commit.  Rescanning  is
                         useful  if you do development in the manner where you
                         modify many files that logically belong  to  separate
                         changesets. This option then allows you to stay in bk
                         citool  and create different changesets for the files
                         without restarting citool each time.  Default: 0

   CSETTOOL CONFIGURATION
       cset.annotation   Annotation options to apply when getting files to  be
                         diffed.   See  the  "-a"  option to bk get.  Example:
                         "-aum".  Default: "" (do not display annotations)
       cset.listHeight   Number of lines in the list windows.  Default: 12

   DIFFTOOL CONFIGURATION
       diff.diffHeight   Number of lines in the diff windows.  Default: 50
       diff.searchColor  Highlight color for search matches.  Default: #ADD8E6

   FM3TOOL CONFIGURATION
       fm3.comments           Boolean which controls the display of  the  com-
                              ments window at the top.  Default: 1 (on)
       fm3.firstDiff          Keyboard  accelerator  for  going  to  the first
                              change.  Default: "-"
       fm3.handColor          Color used  to  highlight  hand  selected  merge
                              choices  in  the  side  by side local and remote
                              diff windows.  Default: #B4B6CB
       fm3.lastDiff           Keyboard  accelerator  for  going  to  the  last
                              change.  Default: "+"
       fm3.mergeColor         Color used to highlight merge choices, both man-
                              ual  and  automatic,  in the lower merge window.
                              Default: #B4B6CB
       fm3.nextConflict       Keyboard accelerator for going to the next  con-
                              flict (skips automerged changes).  Default: "}"
       fm3.nextDiff           Keyboard  accelerator  for  going  to  the  next
                              change.  Default: "]"
       fm3.prevConflict       Keyboard accelerator for going to  the  previous
                              conflict     (skips     automerged     changes).
                              Default: "{"
       fm3.prevDiff           Keyboard accelerator for going to  the  previous
                              change.  Default: "["
       fm3.sameColor          Color  used  to  highlight the portion of a con-
                              flict    consisting    of    unchanged    lines.
                              Default: #EFEFEF
       fm3.showEscapeButton   When entering edit mode, if this variable is set
                              to  1  a  button  will be displayed that you can
                              click on to exit edit mode.  Default: 1
       fm3.spaceColor         Color used to highlight the beginnings of  lines
                              which are "spacers" inserted to make the changes
                              line up horizontally.  Default: #000000
       fm3.toggleAnnotations  Keyboard accelerator for toggling the display of
                              annotations.  Default: "z"
       fm3.toggleGCA          Keyboard accelerator for toggling the display of
                              the GCA.  Default: "x"
       fm3.undo               Keyboard  accelerator for undoing the last merge
                              selection.  Default: "u"

   HELPTOOL CONFIGURATION
       help.linkColor    Color   of   the   hyperlinks   in    bk    helptool.
                         Default: #0000FF
       help.scrollbars   The  location of the two scrollbars in helptool.  The
                         value should be two characters with each one being  L
                         or  R.  The first character indicates the position of
                         the topic list scrollbars as Left or Right, while the
                         second character specifies the position of  the  con-
                         tent scrollbar.  Default: RR
       help.topicsColor  Highlight    color    for   topic   search   matches.
                         Default: #FFA500
       help.height       Number  of  rows   to   display   in   bk   helptool.
                         Default: 50
       help.width        Number   of   columns  to  display  in  bk  helptool.
                         Default: 72
       help.exact        Only return full  word/phrase  matches.   Default: 0,
                         set to 1 to enable

   RENAMETOOL CONFIGURATION
       rename.listHeight Height  of  the file list widget in bk renametool (in
                         lines).  Default: 8

   REVTOOL CONFIGURATION
       rev.canvasBG      Color of the graph background.  Default: #9FB6B8
       rev.commentBG     Background color of the comment window in  the  anno-
                         tated listing.  Default: #ADDD8E6
       rev.arrowColor    Color  of  the  arrows connecting the revision boxes.
                         Default: #00008B
       rev.mergeOutline  Color of the box  surrounding  the  merge  revisions.
                         Default: #00008B
       rev.revOutline    Color  of  the box surrounding the regular revisions.
                         Default: #00008B
       rev.revColor      Fill color of the unselected node.  Default: #9FB6B8
       rev.selectColor   Highlight color  for  the  selected  annotated  line.
                         Default: #ADDD8E6
       rev.commentHeight Height of the comment window above the annotated file
                         listing.  Default: 5
       rev.textWidth     Width  of  widget  that  displays  the  file content.
                         Default: 92
       rev.annotate      Arguments to the annotate command.  Default: "-Aur".
       rev.textHeight    Height of widget  that  displays  the  file  content.
                         Default: 50
       rev.showRevs      The  number  of  revs  to  show  when running revtool
                         against a single file.  Default: 250
       rev.showCsetRevs  The number of  revs  to  show  when  running  revtool
                         against a ChangeSet file.  Default: 50
       rev.tagOutline    Color  of  the  outline around nodes in the ChangeSet
                         graph that have a tag associated with them.  If  this
                         value  is  the empty string no outline will be drawn.
                         Default: #FFFF00
       rev.dateColor     Color of the  date  text  at  the  bottom  of  graph.
                         Default: #181818

SEE ALSO
       Any Tcl/Tk documentation
       X(1)
       bk  help citool, bk help csettool, bk help difftool, bk help fmtool, bk
       help fm3tool, bk help helptool, bk help revtool, bk help renametool

CATEGORY
       Overview
       Admin
       GUI-tools

BitKeeper Inc                         1E1                  bk config-gui(none)
$
help://conflicts
help://conflicts.1
help://bk-conflicts
help://bk-conflicts.1
bk conflicts(none)          BitKeeper User's Manual         bk conflicts(none)

NAME
       bk conflicts - list unresolved files which contain conflicts

SYNOPSIS
       bk conflicts [-dDfrvS] [<file> ...]

DESCRIPTION
       The  conflicts  command lists unmerged files which contain content con-
       flicts and need to be resolved.  Both filenames and directory names may
       be specified and they are treated as in bk  gfiles.   Only  files  that
       contain conflicts are actually listed.

       Any  options specified will operate only on the set of files that would
       normally be listed.

OPTIONS
       -d   Invoke bk diff on the file, showing the  differences  between  the
            local and remote files.
       -D   Like -d but using the graphical diff tool instead of text diffs.
       -f   Invoke  the  3-way filemerge in read-only mode.  This is useful in
            case the developer working on a particular merge  wants  a  second
            person to see the conflict in question without the danger of over-
            writing the merged file.
       -r   Invoke  revtool,  highlighting the GCA, LOCAL, and REMOTE versions
            in the file.
       -S   When  used in a nested collection, treat the repository as  if  it
            were detached rather than as part of the  collection.
       -v   Verbose  listing.  The output lists the files that match the file-
            names or directories specified, along  with  the  number  of  non-
            automerged conflicts in the file.
       -vv  More  verbose  listing.  As above but shows the number of lines in
            conflict with the authors of those lines.

EXAMPLES
           $ bk conflicts '*.h'
           src/bkd.h
           src/logging.h
           src/mdbm/common.h
           src/mdbm/mdbm.h
           src/sccs.h
           src/win32.h

           $ bk conflicts -v '*.h'
           src/bkd.h has 2 conflict blocks
           src/logging.h has 2 conflict blocks
           src/mdbm/common.h has 1 conflict block
           src/mdbm/mdbm.h has 3 conflict blocks
           src/sccs.h has 3 conflict blocks
           src/win32.h has 1 conflict block

           $ bk conflicts -vv 'src/logging.h'
           src/logging.h has 2 conflict blocks
             63 local lines by wscott
              7 local lines by lm
             33 remote lines by wscott
              5 remote lines by lm

SEE ALSO
       bk help diff, bk help difftool, bk help fm3tool, bk  help  resolve,  bk
       help resolving, bk help revtool, bk help gfiles

CATEGORY
       Repository

BitKeeper Inc                         1E1                   bk conflicts(none)
$
help://cp
help://cp.1
help://bk-cp
help://bk-cp.1
help://copy
bk cp(none)                 BitKeeper User's Manual                bk cp(none)

NAME
       bk cp - create a copy of a file preserving its revision history

SYNOPSIS
       bk cp <oldfile> <newfile>

DESCRIPTION
       Use  bk  cp  to copy an existing file and its revision history to a new
       file.  The new file will have a changed root identifier so that  it  is
       managed  as  a new object under BitKeeper control.  There is no linkage
       between <oldfile> and <newfile>, i.e., updates to <oldfile> will not be
       applied to <newfile> as well.

SEE ALSO
       bk help mv

CATEGORY
       File

BitKeeper Inc                         1E1                          bk cp(none)
$
help://credits
help://credits.1
help://bk-credits
help://bk-credits.1
bk credits(none)            BitKeeper User's Manual           bk credits(none)

NAME
       bk credits - License info for software included with BitKeeper

BSD
       This  BSD  text  is  included with BitKeeper because BitKeeper is built
       with some libraries that were included in the  original  4.4BSD  source
       distribution.

   BSD LICENSE TEXT
       Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.

       Redistribution and use in source and binary forms, with or without mod-
       ification,  are  permitted  provided  that the following conditions are
       met:

       Redistributions of source code and documentation must retain the  above
       copyright notice, this list of conditions and the following disclaimer.
       Redistributions  in  binary  form  must  reproduce  the above copyright
       notice, this list of conditions and the  following  disclaimer  in  the
       documentation and/or other materials provided with the distribution.

       All  advertising  materials mentioning features or use of this software
       must display the following acknowledgement:

       This product includes software developed or owned by  Caldera  Interna-
       tional, Inc.

       Neither  the name of Caldera International, Inc. nor the names of other
       contributors may be used to endorse or promote  products  derived  from
       this software without specific prior written permission.

       USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA INTERNA-
       TIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WAR-
       RANTIES,  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
       CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
       EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT, INDI-
       RECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  (INCLUD-
       ING,  BUT  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
       AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY,
       OR  TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
       THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  POSSIBILITY  OF  SUCH
       DAMAGE.

   LZ4
       Fast  LZ  compression  algorithm  Copyright (C) 2011-2012, Yann Collet.
       BSD    2-Clause    License     (http://www.opensource.org/licenses/bsd-
       license.php)

       Redistribution and use in source and binary forms, with or without mod-
       ification,  are  permitted  provided  that the following conditions are
       met:

       =>  Redistributions of source code  must  retain  the  above  copyright
           notice, this list of conditions and the following disclaimer.
       =>  Redistributions  in  binary form must reproduce the above copyright
           notice, this list of conditions and the following disclaimer in the
           documentation and/or other materials provided  with  the  distribu-
           tion.

       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       IS"  AND  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTIC-
       ULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  OWNER  OR
       CONTRIBUTORS  BE  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  BUT  NOT  LIMITED  TO,
       PROCUREMENT  OF  SUBSTITUTE  GOODS  OR  SERVICES; LOSS OF USE, DATA, OR
       PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY  OF
       LIABILITY,  WHETHER  IN  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  OF  THE  USE  OF  THIS
       SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

       You can contact the author at :

       =>  LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
       =>  LZ4 source repository : http://code.google.com/p/lz4/

GPL
       The  GPL text is included with BitKeeper because BitKeeper includes the
       GNU packages diffutils and patch.  These programs are the part  of  the
       BitKeeper system covered by the GPL.

   GPL LICENSE TEXT
                             GNU GENERAL PUBLIC LICENSE
                                Version 2, June 1991

               Copyright (C) 1989, 1991 Free Software Foundation, Inc.
               59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
            Everyone is permitted to copy and distribute verbatim copies
              of this license document, but changing it is not allowed.

       Preamble

       The  licenses  for most software are designed to take away your freedom
       to share and change it.  By contrast, the GNU General Public License is
       intended to guarantee your freedom  to  share  and  change  free  soft-
       ware--to  make  sure the software is free for all its users.  This Gen-
       eral Public License applies to most of the Free  Software  Foundation's
       software  and  to  any  other program whose authors commit to using it.
       (Some other Free Software Foundation software is  covered  by  the  GNU
       Library General Public License instead.)  You can apply it to your pro-
       grams, too.

       When we speak of free software, we are referring to freedom, not price.
       Our General Public Licenses are designed to make sure that you have the
       freedom to distribute copies of free software (and charge for this ser-
       vice  if  you  wish), that you receive source code or can get it if you
       want it, that you can change the software or use pieces of  it  in  new
       free programs; and that you know you can do these things.

       To protect your rights, we need to make restrictions that forbid anyone
       to  deny you these rights or to ask you to surrender the rights.  These
       restrictions translate to certain responsibilities for you if you  dis-
       tribute copies of the software, or if you modify it.

       For example, if you distribute copies of such a program, whether gratis
       or  for  a  fee,  you  must give the recipients all the rights that you
       have.  You must make sure that they, too, receive or can get the source
       code.  And you must show them these terms so they know their rights.

       We protect your rights with two steps: (1) copyright the software,  and
       (2)  offer  you  this license which gives you legal permission to copy,
       distribute and/or modify the software.

       Also, for each author's protection and ours, we want  to  make  certain
       that everyone understands that there is no warranty for this free soft-
       ware.   If  the  software is modified by someone else and passed on, we
       want its recipients to know that what they have is not the original, so
       that any problems introduced by others will not reflect on the original
       authors' reputations.

       Finally, any free program is threatened constantly by software patents.
       We wish to avoid the danger that redistributors of a free program  will
       individually  obtain patent licenses, in effect making the program pro-
       prietary.  To prevent this, we have made it clear that any patent  must
       be licensed for everyone's free use or not licensed at all.

       The  precise terms and conditions for copying, distribution and modifi-
       cation follow.

                                    GNU GENERAL PUBLIC LICENSE
            TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

       0. This License applies to any program or other work which  contains  a
       notice  placed  by  the  copyright  holder saying it may be distributed
       under the terms of this General Public License.  The "Program",  below,
       refers  to  any such program or work, and a "work based on the Program"
       means either the Program or any derivative work  under  copyright  law:
       that  is  to  say,  a  work  containing the Program or a portion of it,
       either verbatim or with modifications and/or  translated  into  another
       language.   (Hereinafter, translation is included without limitation in
       the term "modification".)  Each licensee is addressed as "you".

       Activities other than copying, distribution and  modification  are  not
       covered  by  this License; they are outside its scope.  The act of run-
       ning the Program is not restricted, and the output from the Program  is
       covered  only  if  its  contents constitute a work based on the Program
       (independent of having been made by running the Program).  Whether that
       is true depends on what the Program does.

       1. You may copy and distribute verbatim copies of the Program's  source
       code  as you receive it, in any medium, provided that you conspicuously
       and appropriately publish on each copy an appropriate copyright  notice
       and  disclaimer  of warranty; keep intact all the notices that refer to
       this License and to the absence of any warranty;  and  give  any  other
       recipients  of  the  Program a copy of this License along with the Pro-
       gram.

       You may charge a fee for the physical act of transferring a  copy,  and
       you may at your option offer warranty protection in exchange for a fee.

       2.  You may modify your copy or copies of the Program or any portion of
       it, thus forming a work based on the Program, and copy  and  distribute
       such modifications or work under the terms of Section 1 above, provided
       that you also meet all of these conditions:

       a)  You  must cause the modified files to carry prominent notices stat-
           ing that you changed the files and the date of any change.

       b)  You must cause any work that you distribute  or  publish,  that  in
           whole  or  in  part  contains or is derived from the Program or any
           part thereof, to be licensed as a whole at no charge to  all  third
           parties under the terms of this License.

       c)  If  the modified program normally reads commands interactively when
           run, you must cause it, when started running for  such  interactive
           use  in  the most ordinary way, to print or display an announcement
           including an appropriate copyright notice and a notice  that  there
           is  no  warranty  (or else, saying that you provide a warranty) and
           that users may redistribute the program under these conditions, and
           telling the user how to view a copy of this  License.   (Exception:
           if  the  Program  itself is interactive but does not normally print
           such an announcement,  your  work  based  on  the  Program  is  not
           required to print an announcement.)

       These requirements apply to the modified work as a whole.  If identifi-
       able sections of that work are not derived from the Program, and can be
       reasonably  considered  independent  and  separate works in themselves,
       then this License, and its terms, do not apply to those  sections  when
       you  distribute  them  as  separate works.  But when you distribute the
       same sections as part of a whole which is a work based on the  Program,
       the  distribution  of  the  whole must be on the terms of this License,
       whose permissions for other licensees extend to the entire  whole,  and
       thus to each and every part regardless of who wrote it.

       Thus,  it  is not the intent of this section to claim rights or contest
       your rights to work written entirely by you; rather, the intent  is  to
       exercise the right to control the distribution of derivative or collec-
       tive works based on the Program.

       In  addition, mere aggregation of another work not based on the Program
       with the Program (or with a work based on the Program) on a volume of a
       storage or distribution medium does not bring the other work under  the
       scope of this License.

       3.  You  may  copy  and  distribute the Program (or a work based on it,
       under Section 2) in object code or executable form under the  terms  of
       Sections 1 and 2 above provided that you also do one of the following:

       a)  Accompany  it  with  the  complete  corresponding  machine-readable
           source code, which must be distributed under the terms of  Sections
           1  and  2  above  on  a medium customarily used for software inter-
           change; or,

       b)  Accompany it with a written offer, valid for at least three  years,
           to  give  any  third  party, for a charge no more than your cost of
           physically performing source distribution, a complete machine-read-
           able copy of the corresponding source code, to be distributed under
           the terms of Sections 1 and 2 above on a  medium  customarily  used
           for software interchange; or,

       c)  Accompany  it  with the information you received as to the offer to
           distribute corresponding source code.  (This alternative is allowed
           only for noncommercial distribution and only if  you  received  the
           program  in  object  code or executable form with such an offer, in
           accord with Subsection b above.)

       The source code for a work means the preferred form  of  the  work  for
       making  modifications  to  it.  For an executable work, complete source
       code means all the source code for all modules it  contains,  plus  any
       associated interface definition files, plus the scripts used to control
       compilation  and installation of the executable.  However, as a special
       exception, the source code distributed need not include  anything  that
       is  normally  distributed  (in  either  source or binary form) with the
       major components (compiler, kernel, and so on) of the operating  system
       on  which the executable runs, unless that component itself accompanies
       the executable.

       If distribution of executable or object code is made by offering access
       to copy from a designated place, then  offering  equivalent  access  to
       copy  the source code from the same place counts as distribution of the
       source code, even though third parties are not compelled  to  copy  the
       source along with the object code.

       4.  You  may  not  copy,  modify, sublicense, or distribute the Program
       except as expressly provided under this License.  Any attempt otherwise
       to copy, modify, sublicense or distribute the Program is void, and will
       automatically terminate your rights under this License.  However,  par-
       ties  who  have received copies, or rights, from you under this License
       will not have their licenses terminated so long as such parties  remain
       in full compliance.

       5.  You  are  not  required  to accept this License, since you have not
       signed it.  However, nothing else grants you permission  to  modify  or
       distribute the Program or its derivative works.  These actions are pro-
       hibited  by law if you do not accept this License.  Therefore, by modi-
       fying or distributing the Program (or any work based on  the  Program),
       you  indicate  your  acceptance  of  this License to do so, and all its
       terms and conditions for copying, distributing or modifying the Program
       or works based on it.

       6. Each time you redistribute the Program (or any  work  based  on  the
       Program), the recipient automatically receives a license from the orig-
       inal  licensor  to  copy,  distribute  or modify the Program subject to
       these terms and conditions.  You may not impose  any  further  restric-
       tions  on  the  recipients' exercise of the rights granted herein.  You
       are not responsible for enforcing compliance by third parties  to  this
       License.

       7.  If,  as  a  consequence of a court judgment or allegation of patent
       infringement or for any other reason (not limited  to  patent  issues),
       conditions  are  imposed  on  you (whether by court order, agreement or
       otherwise) that contradict the conditions of this License, they do  not
       excuse you from the conditions of this License.  If you cannot distrib-
       ute so as to satisfy simultaneously your obligations under this License
       and  any other pertinent obligations, then as a consequence you may not
       distribute the Program at all.  For example, if a patent license  would
       not  permit royalty-free redistribution of the Program by all those who
       receive copies directly or indirectly through you, then  the  only  way
       you could satisfy both it and this License would be to refrain entirely
       from distribution of the Program.

       If  any  portion of this section is held invalid or unenforceable under
       any particular circumstance, the balance of the section is intended  to
       apply  and the section as a whole is intended to apply in other circum-
       stances.

       It is not the purpose of this section to induce  you  to  infringe  any
       patents  or  other  property right claims or to contest validity of any
       such claims; this section  has  the  sole  purpose  of  protecting  the
       integrity  of  the  free  software distribution system, which is imple-
       mented by public license practices.  Many  people  have  made  generous
       contributions  to  the  wide range of software distributed through that
       system in reliance on consistent application of that system; it  is  up
       to  the  author/donor  to  decide if he or she is willing to distribute
       software through any other system and a  licensee  cannot  impose  that
       choice.

       This  section  is intended to make thoroughly clear what is believed to
       be a consequence of the rest of this License.

       8. If the distribution and/or use of the Program is restricted in  cer-
       tain  countries  either  by  patents  or by copyrighted interfaces, the
       original copyright holder who places the Program under this License may
       add an explicit geographical distribution  limitation  excluding  those
       countries, so that distribution is permitted only in or among countries
       not thus excluded.  In such case, this License incorporates the limita-
       tion as if written in the body of this License.

       9. The Free Software Foundation may publish revised and/or new versions
       of  the  General  Public  License from time to time.  Such new versions
       will be similar in spirit to the present version,  but  may  differ  in
       detail to address new problems or concerns.

       Each  version is given a distinguishing version number.  If the Program
       specifies a version number of this License which applies to it and "any
       later version", you have the option of following the terms  and  condi-
       tions  either  of that version or of any later version published by the
       Free Software Foundation.  If the Program does not  specify  a  version
       number  of  this  License, you may choose any version ever published by
       the Free Software Foundation.

       10. If you wish to incorporate parts of the  Program  into  other  free
       programs  whose  distribution  conditions  are  different, write to the
       author to ask for permission.  For software which is copyrighted by the
       Free Software Foundation, write to the  Free  Software  Foundation;  we
       sometimes make exceptions for this.  Our decision will be guided by the
       two  goals of preserving the free status of all derivatives of our free
       software and of promoting the sharing and reuse of software generally.

                                            NO WARRANTY

       11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE  IS  NO  WAR-
       RANTY  FOR  THE  PROGRAM,  TO  THE  EXTENT PERMITTED BY APPLICABLE LAW.
       EXCEPT WHEN OTHERWISE STATED IN WRITING THE  COPYRIGHT  HOLDERS  AND/OR
       OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
       EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS FOR A PARTICULAR PURPOSE.
       THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE  OF  THE  PROGRAM  IS
       WITH  YOU.   SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
       ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

       12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRIT-
       ING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
       REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR  DAM-
       AGES,  INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAM-
       AGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM  (INCLUDING
       BUT  NOT  LIMITED  TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
       LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO
       OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER  OR  OTHER  PARTY
       HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

                                    END OF TERMS AND CONDITIONS

                      How to Apply These Terms to Your New Programs

       If  you  develop  a  new program, and you want it to be of the greatest
       possible use to the public, the best way to achieve this is to make  it
       free  software  which  everyone can redistribute and change under these
       terms.

       To do so, attach the following notices to the program.  It is safest to
       attach them to the start of each source file to most effectively convey
       the exclusion of warranty; and each  file  should  have  at  least  the
       "copyright" line and a pointer to where the full notice is found.

              <one line to give the program's name and a brief idea of what it does.>
              Copyright (C) 19yy  <name of author>

              This program is free software; you can redistribute it and/or modify
              it under the terms of the GNU General Public License as published by
              the Free Software Foundation; either version 2 of the License, or
              (at your option) any later version.

              This program is distributed in the hope that it will be useful,
              but WITHOUT ANY WARRANTY; without even the implied warranty of
              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
              GNU General Public License for more details.

              You should have received a copy of the GNU General Public License
              along with this program; if not, write to the Free Software
              Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       Also  add  information  on  how  to contact you by electronic and paper
       mail.

       If the program is interactive, make it output a short notice like  this
       when it starts in an interactive mode:
              Gnomovision version 69, Copyright (C) 19yy name of author
              Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
              This is free software, and you are welcome to redistribute it
              under certain conditions; type `show c' for details.
       The  hypothetical commands `show w' and `show c' should show the appro-
       priate parts of the General Public License.  Of  course,  the  commands
       you  use may be called something other than `show w' and `show c'; they
       could even be mouse-clicks or menu items--whatever suits your program.

       You should also get your employer (if you work as a programmer) or your
       school, if any, to sign a "copyright disclaimer" for  the  program,  if
       necessary.  Here is a sample; alter the names:
              Yoyodyne, Inc., hereby disclaims all copyright interest in the program
              `Gnomovision' (which makes passes at compilers) written by James Hacker.

              <signature of Ty Coon>, 1 April 1989
              Ty Coon, President of Vice
       This  General Public License does not permit incorporating your program
       into proprietary programs.  If your program is  a  subroutine  library,
       you  may consider it more useful to permit linking proprietary applica-
       tions with the library.  If this is what you want to do,  use  the  GNU
       Library General Public License instead of this License.

CATEGORY
       Compat

BitKeeper Inc                         1E1                     bk credits(none)
$
help://cset
help://cset.1
help://bk-cset
help://bk-cset.1
bk cset(none)               BitKeeper User's Manual              bk cset(none)

NAME
       bk cset - manage changesets

SYNOPSIS
       bk cset [-Cq] [-i<list>] [-x<list>]

DESCRIPTION
       The  cset command may be used to restore changeset marks in files (part
       of BitKeeper's per file metadata), to re-include one or more changesets
       which were previously excluded, or to exclude one or more changesets.

OPTIONS
       -C       Clear and remark all changeset boundaries in all  files  under
                BitKeeper control.
       -i<list> Create a new changeset that includes the changes in <list>.
       -q       Run quietly.
       -S       If using -i or -x and not currently in the product, then limit
                the -i or -x to a component.
       -x<list> Create a new changeset that excludes the changesets in <list>.

BUGS
       The  "-i"  and  "-x"  options currently work only on file contents, not
       renames, creates, mode changes, or xflags.

REMOVED INTERFACES
       Older versions of bk cset had two forms which are no  longer  supported
       since bk changes can provide the same information.

           $ bk cset -r1.5
           ChangeSet|1.5
           BitKeeper/deleted/.del-resolve.perl|1.4
           src/takepatch.c|1.16
           $ bk changes -r1.5 -vnd':GFILE:|:REV:'
           ChangeSet|1.5
           BitKeeper/deleted/.del-resolve.perl|1.4
           src/takepatch.c|1.16
           $ echo 1.5 | bk cset -l -
           ChangeSet|1.5
           BitKeeper/deleted/.del-resolve.perl|1.4
           src/takepatch.c|1.16
           $ echo 1.5 | bk changes -vnd':GFILE:|:REV:' -
           ChangeSet|1.5
           BitKeeper/deleted/.del-resolve.perl|1.4
           src/takepatch.c|1.16

SEE ALSO
       bk help admin, bk help changes

CATEGORY
       Admin
       Repository

BitKeeper Inc                         1E1                        bk cset(none)
$
help://csetprune
help://csetprune.1
help://bk-csetprune
help://bk-csetprune.1
bk csetprune(none)          BitKeeper User's Manual         bk csetprune(none)

NAME
       bk csetprune - shrink a repository by removing files

SYNOPSIS
       bk csetprune [options] - < keylist

DESCRIPTION
       The  csetprune  command is used to prune certain files from the reposi-
       tory.  These files are removed in a way which is permanent,  i.e.,  the
       prune cannot be undone.

       The command operates on a list of file keys (sometimes called BitKeeper
       inodes).   Each  file associated with a key is removed from the reposi-
       tory and from all changesets in the ChangeSet  file.   If  a  changeset
       becomes  empty  as  a result of the key removal, then that changeset is
       removed from the ChangeSet file history.  If a removed changeset had  a
       tag,  the  tag  is  moved  to  the  closest non-removed ancestor in the
       ChangeSet file.  If that ancestor was already tagged with the same tag,
       the duplicate tag is discarded.

       After all files have been removed, the identity of the  ChangeSet  file
       is  changed (using bk newroot) and the remaining files are "reparented"
       to the new ChangeSet file.

OPTIONS
       -k<16hexDigits>
                    Specify the <16hexDigits> used in a repository root
                    key.  This is needed when doing a  csetprunes  over
                    time  on  same  key  set  and wanting the resulting
                    repository to communicate with a repository created
                    by an earlier csetprune.
       -G<gonefile> This will prune out the gone file and put the  con-
                    tents of file passed in with -G as the initial con-
                    tent  of  a new gone file.  If there are additional
                    files and deltas missing, a delta to the  new  gone
                    file will be automatically generated and committed.
       -S
       --standalone Just  run csetprune on the current component.  This
                    has no effect in a traditional  standalone  reposi-
                    tory,  but  in  a nested collection, processes just
                    the current component and  not  the  entire  nested
                    collection.
       --tag-csets  Alter the symbol structure to remove duplicates and
                    move  the  symbols  directly  onto the tagged cset.
                    Use this if you do not need to csetprune more  than
                    one repository such that the resulting repositories
                    to  communicate  via  push,  pull or changes.  With
                    this option, the internal symbol graph structure is
                    streamlined.

GENERATING KEYS
       The bk log command may be used to generate  the  list  of  keys.
       When generating keys, it is important to realize that looking in
       a  particular  subdirectory  is likely to miss some of the files
       that you may want to remove.  The files may have been  moved  to
       another directory or they may have been removed (which is really
       just a move to the BitKeeper/deleted subdirectory).

       The following command will generate a list of keys for all files
       originally  created  in  the  junk  subdirectory,  including all
       deleted and/or moved files:

           bk -A log -hr+ -nd:ROOTKEY: | grep '|junk/'

EXAMPLE
       Suppose there is a repository which has two  major  subsections,
       called  docs  and src respectively.  The repository has grown to
       be too large and the goal is to split it in  two.   The  process
       for doing so would be to

       (1) Make  sure all users have pushed their changes into the main
           repository.  Changes made  after  the  split  will  have  to
           exported  as  a  traditional patch and imported, which loses
           the checkin comments.

       (2) Clone the repository twice, once for each of docs and src.

       (3) In each new repository, strip out the files which will be in
           the other repository.

       Commands which will do this:

           bk clone master src
           bk clone master docs
           # Remove the docs files from the src repository
           cd src
           bk -A log -hr+ -nd:ROOTKEY: | grep '|docs/' | bk csetprune
           # Remove the src files from the docs repository
           cd ../docs
           bk -A log -hr+ -nd:ROOTKEY: | grep '|src/' | bk csetprune

SEE ALSO
       bk help newroot, bk help log, bk help gfiles

CATEGORY
       Admin

BitKeeper Inc                         1E1                   bk csetprune(none)
$
help://csets
help://csets.1
help://bk-csets
help://bk-csets.1
bk csets(none)              BitKeeper User's Manual             bk csets(none)

NAME
       bk csets - run changes or csettool on last set of incoming changes

SYNOPSIS
       bk csets [--stats] [-DTv]

DESCRIPTION
       The  csets  command will run the bk csettool command on the last set of
       changesets imported into this repository with a  bk pull,  or  bk push.
       This is useful for tracking down problems and/or doing a quick review.

OPTIONS
       -D      Use  bk  difftool (gui mode) or bk diff -pu (text mode) to dis-
               play the changesets.  If there were  many  pulled  in,  perhaps
               with  changes added and then deleted as part of a review, view-
               ing the difference between the start and the end points may  be
               less "noisy".
       --stats Print a statistics header like diffstat.
       -T      Use bk changes to display the changesets (text mode).
       -v      Pass "-v" to bk changes.

BUGS
       The  "-T"  option should be implied if there is no graphical display to
       be found.

SEE ALSO
       bk help changes, bk help csettool, bk help pull, bk help push

CATEGORY
       Repository

BitKeeper Inc                         1E1                       bk csets(none)
$
help://csettool
help://csettool.1
help://bk-csettool
help://bk-csettool.1
bk csettool(none)           BitKeeper User's Manual          bk csettool(none)

NAME
       bk csettool - BitKeeper graphical changeset browser

SYNOPSIS
       bk csettool [-]
       bk csettool [-S] [-r<revs>] [dir]
       bk csettool [-r<revs>] [-f<file>|<rev>]
       bk csettool [-S] -L[<url>]

DESCRIPTION
       bk  csettool  is  used to view detailed information about the specified
       changeset[s].  bk csettool displays the list of changes in each change-
       set, the file and ChangeSet checkin comments, and the differences found
       in each file contained in each changeset.

       Csettool is a useful aide when tracking down bugs.  For  example,  when
       using  revtool  to  view comments for a specific file in order to track
       when a change was made to the file. Once the desired file is found, the
       user can then click on the "View ChangeSet" button in revtool to  bring
       up to see what other files were modified at the same time that the file
       of interest was modified.

       To see the changes for a particular file, click on the file name in the
       top left window and you will see:

       => the number of diffs in the middle status window
       => the old version of the file in the lower-left window
       => the new version of the file in the lower-right window
       => the  ChangeSet's  comments  followed  by the delta's comments in the
          upper-right window

       Use the space bar to move between diffs and files.  Each time  you  hit
       the  space  bar, the next diff is brought into view.  If you are on the
       last diff, the tool moves to the next file. The "Next" (>>) buttons and
       "Previous" (<<) buttons in the top menu bar  will  also  allow  you  to
       browse the files and diffs.

       The "History" button in the menu bar can be used to start the graphical
       history browser, revtool, on either the entire project (ChangeSet file)
       or on the file highlighted in the upper-left window.

       The  "View  Product"  button in the menu bar, if present, will view the
       current changeset from the point of view of the product rather than the
       component.  If the changeset being viewed was part of  a  commit  in  a
       nested  collection and spanned multiple components, this wider view can
       be useful.

OPTIONS
       All options, with the exception of -S, are  mutually  exclusive,  i.e.,
       pick one (or none) of the following.

       -r<revs>        ChangeSet revision to examine. Can be a single revision
                       or  a  range  of revisions. If no "-r" option is given,
                       csettool  defaults  to  "-r+",  i.e.  the  most  recent
                       changeset.
       -L[<url>]       Show  all changesets unique to this repository relative
                       to the (outgoing) parent or <url> if one was specified.
                       Very similar to:

                           bk csettool -r@`bk repogca [<url>]`..

       -S
       --standalone    By default, bk csettool runs in the product of a nested
                       collection.  To view the changeset in  the  context  of
                       this component you run

                           $ bk csettool -S

       -f<file>|<rev>  Given  a filename and revision, csettool starts up with
                       the specified file and revision selected.
       -               expects a list of revisions on stdin.

BINDINGS
       Home            Scroll both files to the top
       End             Scroll both files to the bottom
       PageUp          Scroll both files one screen up (also Control-b)
       PageDown        Scroll both files one screen down (also Control-f)
       UpArrow         Scroll both files one line up (also Control-y)
       DownArrow       Scroll both files one line down (also Control-e)
       LeftArrow       Scroll both files to the left
       RightArrow      Scroll both files to the right
       Alt-UpArrow     Make the diffs windows one line bigger  and  the  lists
                       windows one line smaller.
       Alt-DownArrow   Make  the  diffs windows one line smaller and the lists
                       windows one line bigger.
       Control-q       Quit
       space           Next diff, if last diff in this file,  then  goto  next
                       file
       n               Next  diff,  if  last diff in this file, then goto next
                       file
       p               Previous diff, if first diff in this  file,  then  goto
                       previous file
       .               Center the current diff on the screen
       Control-n       Next file
       Control-p       Previous file
       s               Export the current ChangeSet as a patch.
       Double-Clicking Double  clicking the left mouse button on a file in the
                       file list brings up revtool for the specified file.

FUTURE DIRECTIONS
       We plan on having a single screen diff window option where the  changes
       are all shown color coded in one window.

SEE ALSO
       bk help changes, bk help config-gui, bk help cset, bk help difftool, bk
       help range, bk help revtool

CATEGORY
       GUI-tools
       Repository

BitKeeper Inc                         1E1                    bk csettool(none)
$
help://debugtool
help://debugtool.1
help://bk-debugtool
help://bk-debugtool.1
bk debugtool(none)          BitKeeper User's Manual         bk debugtool(none)

NAME
       bk debugtool - tool for use in remote command line debugging

SYNOPSIS
       bk    debugtool   [--shell]   [--server]   [-p<proxy>]   [-u<username>]
       [host:port]

DESCRIPTION
       bk debugtool launches a graphical interface  to  connect  to  a  remote
       debug  server  and  allow the possibility of remote command line debug-
       ging.  Once instance of debugtool connecting  to  the  server  declares
       themselves  as  the  shell,  and all other instances can chat and issue
       commands to the shell.

       The debugtool works by connecting to a remote debug  server  using  the
       HTTP  protocol.   It does not keep an open connection to the server but
       instead polls the server for updates at regular intervals.  This allows
       the debugtool to appear exactly as any other HTTP client to any  inter-
       mediate  proxy  servers,  which  should allow all communication to pass
       through any firewalls that already allow web traffic.  The client  will
       simply appear as another web client.

       Passing  --shell  signifies that you wish your instance of debugtool to
       be the shell that everyone executes commands on.  Each time  a  command
       is requested, you are asked to allow the command to proceed, or you can
       simply say that all commands from that user should be allowed.

       There  can only be one shell in a session, and any attempt to connect a
       second shell will simply disable the shell for the subsequent  clients.
       Only the first to request it is given the shell.

       Passing  --server  will  start a local instance of the debug server and
       then immediately  launch  the  debugtool  and  connect  to  that  local
       instance.   Others  can then connect to your local instance to create a
       debug session.

COMMANDS
       Hitting Tab from within the debugtool  will  switch  between  chat  and
       shell  mode.   The prompt at the bottom next to the entry box will show
       the current mode.  Anything you type while in chat mode will simply  be
       echoed  to  everyone  in  the session.  Anything entered while in shell
       mode will be sent to the client who has the shell,  executed  on  their
       machine, and the result echoed back for everyone to see.

       Typing  a / as the first character of anything entered specifies any of
       a list of commands to be called from within the  tool.   The  available
       commands are:

       /allow <all | username>
       Allow  all users or a single user access to execute commands if you are
       the shell.  This will give permanent permission to execute commands  if
       you  are the shell, and you will not be prompted to approve commands if
       they are sent from this user (or all users).

       /clear <chat | shell>
       Clear either the chat or shell window.

       /say <message>
       Send a message to the chat window no matter  which  mode  you  are  in.
       This  is  handy  if  you  want to say something without exiting command
       mode.

       /shell <command>
       Execute a command in the shell no matter which mode you are  in.   This
       is  handy  if  you want to execute a quick command without exiting chat
       mode.

BitKeeper Inc                         1E1                   bk debugtool(none)
$
help://delta
help://delta.1
help://bk-delta
help://bk-delta.1
help://ci
bk delta(none)              BitKeeper User's Manual             bk delta(none)

NAME
       bk delta - check in modified files

SYNOPSIS
       bk delta [-acflpqu] [-D<file>] [-y<msg>] [<file> ... | -]
       bk delta [-acflpqu] [-D<file>] [-Y<file>] [<file> ... | -]

DESCRIPTION
       The  bk delta command is used to check in changes made to revision con-
       trolled files.  This command is fairly rich in features and is the pre-
       ferred interface for scripting.  For interactive checkins, bk citool is
       the preferred interface.

       After a delta saves the modifications in a file, the state of the  user
       file  is  controlled  by the 'checkout' config option and the -l and -u
       options below.  In checkout:edit (aka -l) mode  (the  default  for  new
       repositories)  the  file is left unmodifed in an edited/writable state.
       In checkout:get (aka -u) mode, the file is unlocked and made read-only.
       In checkout:none mode, the file is removed after its contents has  been
       recorded. The file is removed even if no changes are found.

       By  default,  bk  delta with no file arguments operates on all files in
       the current directory.  If you want to disable this behavior, for exam-
       ple to prevent accidental checkins,  you  can  set  the  BK_NODIREXPAND
       environment variable to a value of 1.

OPTIONS
       -a          Normally,  bk delta is used to modify existing files.  This
                   option changes bk delta to act like bk new  for  new  files
                   and  bk  delta  for existing files.  The usefulness of this
                   option is more apparent when you consider  having  a  mixed
                   list  of  files,  some under revision control and some not.
                   For example,

                       bk -Axc delta -a -y'mass checkin'

                   runs bk new on all the new files and bk delta  on  all  the
                   modified  files.   When  called  with this option, bk delta
                   does not create a null delta on an  edited  but  unmodified
                   file.
       -c          Take checkin comments from SCCS/c.filename.  It is an error
                   if the c.file does not exist.
       -D<file>    Take RCS format (diff -n or bk diff -hn) diffs from <file>.
       -f          Force  the  creation  of  a null delta even if there are no
                   changes to the file.
       -l          Follow check in with a locked check out like "bk edit".
       -M<mode>    Set the permissions on the new delta to <mode>.  More  com-
                   monly used with bk new.
       -p          Print differences before prompting for comments.
       -q          Run silently.
       -u          Follow check in with an unlocked check out.
       -Y<file>    Use  the  comment  specified in <file> for comments for all
                   files.
       -y<comment> Sets the revision comment to <comment>.

SEE ALSO
       bk help citool, bk help get, bk help edit, bk help new

CATEGORY
       File

BitKeeper Inc                         1E1                       bk delta(none)
$
help://describe
help://describe.1
help://bk-describe
help://bk-describe.1
bk describe(none)           BitKeeper User's Manual          bk describe(none)

NAME
       bk describe - generate a tag-based release name

SYNOPSIS
       bk describe [--brief] [--dirty]

DESCRIPTION
       This  command  generates  a  name based on the most recent tag.  If the
       most recent tag is older than the tip then the name  is  appended  with
       "+%d@0x%x"  where  %d is replaced with the number of changesets implied
       by the tip that are not implied by  the  tagged  changeset  and  %x  is
       replaced with the time_t of the latest commit in hexadecimal.

       Note  that the changeset[s] that have the same time_t as the 0xDDDDDDDD
       can be listed with

           bk changes -c<time_t>

       where <time_t> is the 0xDDDDDDDD part of the name.  In most cases there
       will be only one match, if there are more than one you can usually fig-
       ure it out by the distance from the tag.

       --brief Skip the timestamp.  This makes the name far  less  unique  but
               more human readable.
       --dirty If the tree has modified, extra, and/or pending files, then the
               name is appended with "-dirty".

EXAMPLES
           # No tags, 3 csets total, last cset at 0x564f5316, clean
           $ bk describe
           1.0+3@0x564f5316
           # No tags, 3 csets total, last cset at 0x564f5316, with changes
           1.0+3@0x564f5316-dirty
           # newest tag is v1.0, tag is on tip cset, clean repo
           v1.0
           # newest tag is v1.0, tag is on tip cset, dirty repo, with --dirty
           v1.0-dirty
           # newest tag is v1.0, tag is 1 cset older than tip cset, clean repo
           v1.0+1@0x564f5316
           # newest tag is v1.0, tag is 1 cset older than tip cset, dirty repo
           v1.0+1@0x564f5316-dirty
           # same except tag is 5 csets older than tip, brief format
           v1.0+5-dirty

SEE ALSO
       bk help changes

SOURCE
       This is an L script in `bk bin`/lscripts/describe.l

CATEGORY
       Utility

BitKeeper Inc                         1E1                    bk describe(none)
$
help://detach
help://detach.1
help://bk-detach
help://bk-detach.1
bk detach(none)             BitKeeper User's Manual            bk detach(none)

NAME
       bk detach - create a stand-alone clone of a component repository

SYNOPSIS
       bk detach [-q] [-B<url>] [-E<e>=<v>] [-r<rev>] <component> [<to>]

DESCRIPTION
       The  bk  detach  command  is a form of bk clone used to create a stand-
       alone clone of a component repository.

OPTIONS
       -B<url>       Set the BAM server url to <url> in the destination repos-
                     itory.
       -E<env>=<val> Export an environment variable to the bkd running in  the
                     remote  BitKeeper  repository.   Typically  used  to pass
                     information to remote triggers.  Only variables with  the
                     prefix BKU_ are allowed.
       -q            Run quietly.
       -r<rev>       Clone  the  repository up to and including cset <rev>.  A
                     changeset number or changeset key can be used to  specify
                     <rev>.

SEE ALSO
       bk help attach, bk help clone, bk help port, bk help setup

CATEGORY
       Nested

BitKeeper Inc                         1E1                      bk detach(none)
$
help://diff
help://diff.1
help://bk-diff
help://bk-diff.1
help://differences
help://sdiffs
help://diffs
bk diff(none)               BitKeeper User's Manual              bk diff(none)

NAME
       bk diff - show differences in revision controlled files

SYNOPSIS
       bk diff [<opts>] [<file> ... | -]

DESCRIPTION
       The  bk diff command is typically used to show changes to working files
       relative to the previously checked in version.  Unified diffs are  pro-
       duced by default.

       The bk diff command supports context, unified, procedural, and side-by-
       side  diffs.   All  of the above can be optionally annotated with file-
       name, author, date, and/or revision numbers.

       To view changes you have made to all of the files in the current direc-
       tory:

           $ bk diff

       To see the changes for all files in your tree:

           $ bk -U diff

OPTIONS
       -A<bdpru>    Align prefix output in a human readable form.  The set  of
                    annotations will be followed by a vertical bar and a space
                    before  the  data from each line of the file starts.  Each
                    annotation is aligned in a column.  The option argument[s]
                    turn on one or more annotations as a prefix to each  line.
                    The possible annotations are:

                    b   Prefix each line with the basename of the file.
                    d   Prefix each line with the date of last modification.
                    p   Prefix each line with pathname of the file relative to
                        the root of the repository.
                    r   Prefix  each  line with the revision of last modifica-
                        tion.
                    u   Prefix each line the name of the user who  last  modi-
                        fied it.
       -a<bdpru>    Similar to "-A" but without the alignment.
       -b           Ignore changes in amount of white space.
       -B           Ignore  changes  that  just  insert or delete blank lines.
       -c           Do old-style context diffs.
       -d<date>     Instead  of using revision[s] as the versions to diff, use
                    the revision[s] specified by the date (see help bk range).
       -f           Normally, bk diff  does  not  bother  to  diff  against  a
                    checked  out, read only file (unless a revision was speci-
                    fied).  This option forces bk diff to ignore the read only
                    hint and to do the diff against all specified files.

       -F regex     Only useful in unified diffs, the given regex  will
                    be  matched  with  the  lines before the diff block
                    and, if a match is found, it will be printed  after
                    the  '@@' at the start of the diff block. Typically
                    used to match function declarations.
       -h           Don't print headers.
       -H           Prefix diffs with  the  checkin  comments  of  that
                    range of revisions.  The comments printed are those
                    associated with the set difference of the two revi-
                    sions.
       -l<rev>      Show  all  changes made by the changeset containing
                    rev <rev>.  This  obscure  option  is  useful  when
                    there are multiple deltas in the same changeset and
                    you aren't sure of the changeset boundaries.  Simi-
                    lar to

                        bk changes -i<file> -vvr<rev>

       -L[<url>]    Show all the changes unique to this repository rel-
                    ative  to the (outgoing) parent or <url> if one was
                    specified.  In this context, "changes"  means  com-
                    mitted, pending, and/or modified files.  Very simi-
                    lar to:

                        bk -A diff -r@`bk repogca [<url>]`

       -n           Do RCS style diffs.
       --normal     Instead  of  unified diffs (the default) print less
                    verbose diffs like those produced by diff(1).
       -N           If a specified file is not under  revision  control
                    treat  it  as if it were under revision control and
                    the previous checked in version was empty.  Without
                    this option specified files not under revision con-
                    trol are listed as "New file: <filename>".
       -p           Procedural diffs, like "diff -p".
       -r<rev>      Diff revision <rev>.  (Or key  or  changeset  revi-
                    sion. See bk help terms under "rev argument.")
       -R<rev>      Show  diffs  between parent of <rev> and <rev>.  If
                    no revision is specified and the files  are  listed
                    on standard input as <file>|<rev> then the revision
                    is taken from the standard input.
       -s           Display  side-by-side  diffs.   The  total width is
                    controlled by the COLUMNS environment variable, and
                    defaults to 80.
       --stats      Print a statistics header like diffstat in addition
                    to the normal diff output.
       --stats-only Print a statistics header like  diffstat  and  sup-
                    press the normal diff output.
       -S
       --standalone Use with -L in a nested component when you want the
                    component to act like a standalone repository.
       -u<context>  Print  unified diffs (this is the default). Option-
                    ally, pass the number of lines of context to print.
       -v           Be verbose about non-matching ranges.
       -w           Ignore white space when comparing lines.

EXAMPLES
       You may diff specific revisions:

           $ bk diff -r1.2..1.4 foo.c

       When only one revision is supplied with "-r", then that revision
       is compared to the working file or the top of trunk if the  file
       is not edited.

       A fairly useful thing is to show the differences introduced by a
       specific revision or changeset:

           bk diff -R1.5 foo.c

       Normally, the revisions specified mean the revision in the file.
       Changeset  revisions  do  not match file revisions and sometimes
       you want to see the changes for a specific changeset.   Both  of
       these accomplish that:

           bk diff -l@<alpha1> <file>
           bk changes -i<file> -vvr<alpha1>

       To  create a patch which captures all content changes as well as
       all new files:

           bk -Axc diff -N

       You can use bk diff to diff your entire  tree,  including  edits
       against  an  existing  changeset revision or tag in your reposi-
       tory.

           $ bk -A diff
           $ bk -A diff -r@<rev>

       To see the diffs in the local tree from the new baseline cset in
       the parent (-L changes diff behavior to look at the whole tree):

           $ bk diff -L

BUGS
       This command does not currently  handle  displaying  differences
       for binary files.

SEE ALSO
       bk help changes, bk help difftool, bk help export, bk help range

CATEGORY
       Common
       File

BitKeeper Inc                         1E1                        bk diff(none)
$
help://difftool
help://difftool.1
help://bk-difftool
help://bk-difftool.1
bk difftool(none)           BitKeeper User's Manual          bk difftool(none)

NAME
       bk difftool - BitKeeper graphical differences viewer

SYNOPSIS
       bk difftool [<opts>]
       bk difftool [<opts>] <dir>
       bk difftool [<opts>] -
       bk difftool [<opts>] <file>
       bk difftool [<opts>] -r<rev> <file>
       bk difftool [<opts>] -r<rev1> -r<rev2> <file>
       bk difftool [<opts>] <file1> <file2>
       bk difftool [<opts>] <path/to/file1> <dir>
       bk difftool [<opts>] -r<@cset1> -r<@cset2>
       bk difftool [<opts>] [-S] -L[<url>]

DESCRIPTION
       The bk difftool command is a side-by-side differences viewer that shows
       the files being compared in separate windows. The differences are color
       coded,  but as you move to a new diff, that diff becomes highlighted in
       a bold font.  You can move back and forth through the diffs  using  the
       keys described below.

OPTIONS
       -b            Ignore changes in amount of white space.
       -L[<url>]     Show  changes that are unique to this repository relative
                     to the (outgoing) parent or <url>.
       -s<comp>      In a nested collection, limit the files processed to  the
                     set of component[s] (or aliases of components) specified.
                     This option may repeat.
       -S
       --standalone  When  used in a nested collection, treat  the  repository
                     as  if  it were detached rather than as part of the  col-
                     lection.  This option limits the files  being  considered
                     to those in the current component (or product).
       -w            Ignore white space when comparing lines.

ARGUMENTS
       If  no arguments are given, bk difftool finds all the modified files in
       the repository and allows the user to select the files they are  inter-
       ested  in  via  a pull-down menu.  Keyboard accelerators may also be be
       used to navigate between the files.

       If a directory, <dir>, is given as an argument, bk difftool  looks  for
       changes in and only in that directory.

       If  a  dash  ("-") is given as an argument, bk difftool takes a list of
       files to view from stdin. For example,

           $ bk gfiles -cU | bk difftool -
           $ bk -cgU difftool

       If only one file is specified and that file is a  locked  and  modified
       file, bk difftool will diff the most recent revision against the locked
       version.

       If  a  revision and a checked out file are specified, bk difftool diffs
       that version against the checked out file.

       If two revisions and a file are specified, bk difftool diffs those  two
       versions of the file.

       If two files are specified, bk difftool diffs those two files.

       If  a  file (or a path with a filename) are given as the first argument
       and a directory is given as the second argument, then the  basename  of
       the  first  argument is appended to the second argument. The purpose of
       this calling convention is to save typing. For example, if I have  mul-
       tiple-related  repositories  at  the same level in the filesystem and I
       want to diff a file in the local repository against the  same  file  in
       another version of the repository, I can do the following:

           bk difftool src/filename.c ../../repo/src

       The above command is equivalent to doing the following:

           bk difftool src/filename.c ../../repo/src/filename.c

       If  two revs are specified in changeset format, i.e., -r@cset, then the
       set of files displayed is based on the two changesets; each  file  that
       is different as of the specified changesets is shown.  This output for-
       mat  can  be  very useful for reviewing, see examples below.  If a file
       has been renamed, difftool will show the difference in contents as well
       as the change in the name.  Note  that  this  format  works  in  nested
       repositories as well as standalone repositories.

       If  the -L option is given, show all the changes unique to this reposi-
       tory relative to the (outgoing) parent or <url> if one  was  specified.
       This is similar to:

           bk difftool -r@`bk repogca [<url>]` -r@+

       but  not  identical  in  that  the -L option will also show any work in
       progress, such as files that are modified or have pending  deltas  (not
       yet committed to a changeset).

       Use -S with -L when in a nested component and you want the component to
       act like a standalone repository.

DISCARDING FILES
       When  a file that is being viewed is in the checked out state, a button
       labelled "discard" will be enabled. You may click this button  to  dis-
       card  your  changes  (see  bk unedit).  To perform the discard you must
       click on the "discard" button twice. After the first click you will  be
       prompted  to  make a second click. If you click anywhere other than the
       "discard" button, or wait 10 seconds, the discard will be cancelled.

       Once a file has been discarded, it's corresponding entry in the "Files"
       menu will be disabled.

EXAMPLES
       To see all the changes between two arbitrary changesets:

           bk difftool -r@<rev1> -r@<rev2>

       That form can be useful to "collapse" multiple changesets that may have
       added and then deleted content to the same file[s].

       In a nested collection, to do the same  as  the  previous  example  but
       limit the output to a particular component or alias:

           bk difftool -s<alias> -r@<rev1> -r@<rev2>

       In a nested collection, to limit showing changes to a particular compo-
       nent or alias:

           bk difftool -s<alias>

KEY BINDINGS
       Home            Scroll both files to the top
       End             Scroll both files to the bottom
       PageUp          Scroll both files one screen up
       PageDown        Scroll both files one screen down
       UpArrow         Scroll both files one line up
       DownArrow       Scroll both files one line down
       Left            Scroll both files to the left
       Right           Scroll both files to the right
       Control-q       Quit
       space           Next diff
       n               Next diff
       p               Previous diff
       .               Center the current diff on the screen
       Control-n       Go to then next file
       Control-p       Go to the previous file

SEE ALSO
       bk help config-gui, bk help diff, bk help fmtool, bk help range

CATEGORY
       Common
       GUI-tools
       Repository

BitKeeper Inc                         1E1                    bk difftool(none)
$
help://edit
help://edit.1
help://bk-edit
help://bk-edit.1
bk edit(none)               BitKeeper User's Manual              bk edit(none)

NAME
       bk edit - check out a file for editing

SYNOPSIS
       bk edit [-q] [-r<rev>] [<file> ... | -]

DESCRIPTION
       If  a  file  is  not  locked  for writing, i.e., it is not visible in a
       directory listing or it is read-only, then use bk edit to check out the
       file and lock it, making it available for writing.

       bk edit with no options will check out all files in a directory.

OPTIONS
       -q      run quietly
       -r<rev> Edit the file, rolling it back to  the  contents  specified  by
               <rev>.   (Or key or changeset revision. See bk help terms under
               "rev argument") BitKeeper will check out the tip revision  com-
               bined  with  a set of include and exclude deltas needed to pro-
               duce the requested revision.

NOTES
       While it may seem like this step could be done with a simple

           $ chmod +w foo.c

       that is not correct.  The reason is keyword  expansion.   Keywords  are
       expanded  only in read-only files, they are unexpanded in locked files.
       For example, if a file contains %M% %I%, when it  is  not  locked  that
       will look like foo.c 1.2.  If the file is modified after the chmod then
       the  keywords will forever more be foo.c 1.2, which is not likely to be
       the desired result.  One could argue  that  BitKeeper  should  try  and
       catch  this case (and it does, bk check will frequently fix it), but it
       is impossible to do so correctly in all cases.

SEE ALSO
       bk help terms

CATEGORY
       File
       Common

BitKeeper Inc                         1E1                        bk edit(none)
$
help://editor
help://editor.1
help://bk-editor
help://bk-editor.1
bk editor(none)             BitKeeper User's Manual            bk editor(none)

NAME
       bk editor - automatically check out BitKeeper files when using $EDITOR

SYNOPSIS
       bk editor <file>

DESCRIPTION
       bk  editor  is used as a shortcut to edit a file whether or not it is a
       BitKeeper file.  If the file is under revision control, bk editor  will
       bk  edit  the file then exec the editor of choice on that file.  If the
       file is not under revision control, it will exec  the  editor  on  that
       file.

       The  $EDITOR  environment  variable  must  be set to the editor of your
       choice.

       bk editor can be used as follows:

           bk editor foo.c

       Another method is to set the $EDITOR environment variable and alias the
       editor name to bk editor Using xemacs as an example,  set  $EDITOR  and
       then alias:

           EDITOR=xemacs
           alias xemacs='bk editor'

       To open the file for editing:

           xemacs foo.c

CATEGORY
       Compat

BitKeeper Inc                         1E1                      bk editor(none)
$
help://emacs
help://emacs.1
help://bk-emacs
help://bk-emacs.1
help://Compat/vc
bk emacs(none)              BitKeeper User's Manual             bk emacs(none)

NAME
       bk emacs - info on how to use emacs' vc-mode

DESCRIPTION
       BitKeeper  is  similar to SCCS, and vc-mode more or less supports SCCS,
       so most of the things that you can do  with  vc-mode  work:  visit-file
       will check out files automatically, C-x C-q locks files for editing, C-
       x v v will prompt for comments and check in an individual file, C-x v =
       will  compare  versions,  and  so on.  Filename completion doesn't know
       about sfiles; this appears to be a general problem with vc-mode, not  a
       BitKeeper specific issue.

       You  cannot create changesets with vc-mode; use bk citool or bk commit.
       vc-mode does not understand BitKeeper's symbol handling,  as  that  was
       not  part  of  the  original  SCCS.  Do not attempt to use vc's symbol,
       snapshot, and branch commands with BitKeeper.

       vc-mode expects to be able to refer to SCCS commands  directly  instead
       of via the BitKeeper front end.  In theory, it should suffice to put

           setq vc-path /usr/local/bitkeeper

       in .emacs, but this didn't work when last tested (most of the BK devel-
       opers  use  vi).   The commands vc wants to run are: admin, get, delta,
       unedit, stripdel, and bk log.  This just happens to be the list of com-
       mands that we symlink into /usr/bin during a standard installation.

       If you check in a file using bk citool or bk delta in a  shell  window,
       vc-mode  will  not  notice; you can go right on editing the buffer, and
       BitKeeper will get very confused the next time you try to check out the
       file (locked or not).  The right way to get out of this mess is to kill
       off the offending buffer, rename the modified  file  out  of  the  way,
       check  out  the  file  for  editing,  and  rename  it back.  Do all the
       rearrangement from a shell prompt.  Kill all your buffers  before  run-
       ning bk citool to avoid the problem.

CATEGORY
       Compat

BitKeeper Inc                         1E1                       bk emacs(none)
$
help://export
help://export.1
help://bk-export
help://bk-export.1
bk export(none)             BitKeeper User's Manual            bk export(none)

NAME
       bk export - export a patch or version of a BitKeeper repository

SYNOPSIS
       bk export -tpatch [-ahpST] [-s<alias>] [-i<pat>] [-x<pat>] -r<r1,r2>
       bk  export  -tplain  [-akSTvw]  [-s<alias>] [-i<pat>] [-x<pat>] -r<rev>
       <to>

DESCRIPTION
       The bk export command generates a directory  tree  alongside  the  Bit-
       Keeper  repository  which  contains checked-out copies of all the files
       under BitKeeper control.  It can also generate traditional (diff  -Nur)
       patches  between  any two revisions of the source tree.  By default, bk
       export only exports user files.  Files under  the  BitKeeper  directory
       are  not exported.  This behavior can be changed with the "-i" and "-x"
       options.

OPTIONS
       -a            Include system  files  from  BitKeeper/  subdirectory  in
                     exports.
       -h            Disable patch header.
       -i<pat>       Export only pathnames matching <pat> pattern (see below).
       -k            Do not expand keywords (default is to expand keywords).
       -p            Do procedural diffs when exporting a patch (see diff(1)).
       -r<rev>       Export the tree as of revision <rev>.
       -S
       --standalone  Just export the current component.  This has no effect in
                     a traditional standalone repository, but in a nested col-
                     lection, processes just the current component and not the
                     entire nested collection.
       -s<alias>     In  a  nested collection, export can recurse into some or
                     all of the populated  components.   Using  the  -s<alias>
                     option  limits the repositories processed to those speci-
                     fied by <alias>.  If this option is repeated the  implied
                     subset  is  the union of all specified components.  If no
                     <alias> is specified that is taken  to  be  the  same  as
                     -sHERE.
       -T            Set gfile modification time to check-in time.
       -t<type>      Select export format via <type>:

                     plain       Export  file  in  plain  text  to a directory
                                 tree.
                     patch       Export file in gnu patch format.
       -v            Be verbose.
       -w            Make files writable (default is read-only).
       -x<pat>       Export all pathnames  not  matching  <pat>  pattern  (see
                     below).

INCLUDE/EXCLUDE PROCESSING
       Include  and/or exclude patterns may be used to control which files are
       exported.  There may be multiple include and/or exclude patterns.   The
       patterns  are  a  file  glob the same as used by bk glob.  Patterns are
       matched against the partial pathname from the root of  the  repository.
       If  the  partial  pathname matches any of the exclude patterns then the
       file is skipped.  If there are one or more  include  patterns  but  the
       partial  pathname  does  not match any of the include patterns then the
       file is skipped.  Exclude processing takes precedence over include pro-
       cessing.

       When exporting patches there can be ambiguity as to which name is  used
       for  include/exclude  processing because some files may have been moved
       in the changes implied by the exported patch.  The include/exclude pro-
       cessing always applies to any of file names contained  in  the  changes
       implied  by  the  patch.   For example, suppose you have a file that is
       currently deleted but at the time of the patch was  in  src/foo.c.   If
       you told the system to export src/* then the file will be in the set.

SEE ALSO
       diff(1), patch(1), bk help glob, bk help rset

CATEGORY
       Compat

BitKeeper Inc                         1E1                      bk export(none)
$
help://extras
help://extras.1
help://bk-extras
help://bk-extras.1
bk extras(none)             BitKeeper User's Manual            bk extras(none)

NAME
       bk extras - list extra files not under revision control

SYNOPSIS
       bk extras [-a] [<dir>]

DESCRIPTION
       The  bk extras command finds files which are not under revision control
       and are not listed in the ignore file.

       The default behavior is to find all extra files  in  the  entire  tree;
       this can be changed by specifying a subdirectory like so

           bk extras .

       The default behavior is to respect the ignore file; this can be changed
       by adding the "-a" flag like so

           bk extras -a    # find all extra files in entire repo
           bk extras -a .  # find all extra files at or below "."

SEE ALSO
       bk help ignore, bk help gfiles

CATEGORY
       File

BitKeeper Inc                         1E1                      bk extras(none)
$
help://fast-export
help://fast-export.1
help://bk-fast-export
help://bk-fast-export.1
bk fast-export(none)        BitKeeper User's Manual       bk fast-export(none)

NAME
       bk fast-export - export the repository in a format compatible with git

SYNOPSIS
       bk fast-export <options>

DESCRIPTION
       bk  fast-export  exports the entire repository in a format suitable for
       input to git's fast-import command. The output is sent to standard out-
       put.

       By default the BitKeeper MD5KEY of the  equivalent  changeset  will  be
       added to every commit in git.

OPTIONS
       -A<filename>
       --authors=<filename> Use  the given file as a map for authors. The syn-
                            tax is compatible with git cvsimport:

                                USER = Name <email@domain.com>

                            With one user per line.
       --branch=<branch>    By default the export will be done for  the  "mas-
                            ter"  git  branch.  This  option  lets  you do the
                            export for a different branch. This is useful  for
                            exporting  two  different BitKeeper branches (e.g.
                            "dev" and "stable") into the same git  repository.
                            See SUGGESTED USE below.
       --incremental=<repo> Do  an  incremental  export starting from the last
                            exported cset found in the Git repository  <repo>.
                            This  will  not  work  if the previous export used
                            --no-bk-keys.
       --no-bk-keys         Don't add the "bk: <mk5key>" line at  the  end  of
                            the comments (incompatible with --incremental).
       -q
       --quiet              Don't print warnings or other information.
       -S
       --standalone         When  used in a nested collection, export only the
                            product or the component implied  by  the  current
                            working directory.

EXAMPLES
       The  commands to export a BitKeeper repository named "bk-repo" to a git
       repository named "git-repo" would be:

           $ git init git-repo
           $ (cd bk-repo; bk fast-export) | (cd git-repo ; git fast-import)

       And to do an incremental export later:

           $ (cd bk-repo; bk fast-export --incremental=../git-repo) | \
             (cd git-repo ; git fast-import)

SUGGESTED USE
       It is suggested that you create a pristine import branch where  no  git
       commits are created. By default, fast-export warns if the latest commit
       in  the  import  branch  is not marked with a BitKeper key (This can be
       disabled with the --quiet option).

       For example, if you have two separate BitKeeper  branches:  'dev',  and
       'stable',  you  can import each of them into corresponding git branches
       and pass the appropriate --branch option to fast-export each  time.  If
       the git repository is also being developed, this can be done in a sepa-
       rate git branch (e.g. 'master').

EXIT STATUS
       bk  fast-export  returns exit status 0 if the export completed success-
       fuly. Non-zero if there was an error.

SEE ALSO
       bk help fast-import

CATEGORY
       Utility

BitKeeper Inc                         1E1                 bk fast-export(none)
$
help://fast-import
help://fast-import.1
help://bk-fast-import
help://bk-fast-import.1
bk fast-import(none)        BitKeeper User's Manual       bk fast-import(none)

NAME
       bk fast-import - import a new repository using git's fast-export format

SYNOPSIS
       bk fast-import [options] [<repo>]

DESCRIPTION
       bk  fast-import creates a new repository from a stream on data on stdin
       that follows the data format expected by git's fast-import command.

OPTIONS
       -q       Do  not  generate  any  output  unless  an  error   has
                occurred.
       -v       Generate  verbose output printing a message before each
                file is imported.
       -i<glob> Only include pathnames  matching  this  'glob'  in  the
                resulting repository.
       -x<glob> Never  include  pathnames  matching  this 'glob' in the
                resulting repository.

EXAMPLES
       The commands to import a git  repository  into  bitkeeper  would
       look like this:

           $ rm -rf bk-repo
           $ git -C git-repo fast-export master | bk fast-import bk-repo

EXIT STATUS
       bk  fast-import  returns  exit  status 0 if the import completed
       successfuly. Non-zero if there was an error.

SEE ALSO
       bk help fast-export

CATEGORY
       Utility

BitKeeper Inc                         1E1                 bk fast-import(none)
$
help://features
help://features.1
help://bk-features
help://bk-features.1
bk features(none)           BitKeeper User's Manual          bk features(none)

NAME
       bk features - display features used or known

SYNOPSIS
       bk features [--all] [<feature>]
       bk features [-m]

DESCRIPTION
       This  command  either  lists  the optional features used by the current
       repository, or, with --all, lists all optional features known  by  this
       version  of  BitKeeper,  or, with a single specified feature, uses exit
       status to indicate if the feature is known  to  this  version  of  Bit-
       Keeper.

       Run  with the -m option, this command will print the minimum (earliest)
       BitKeeper release that will be able to operate on the  current  reposi-
       tory.

EXIT STATUS
       When run with no arguments, returns 1 if not run in a repository.
       When  run with a single feature, the exit status is 0 if the feature is
       known to this version of BitKeeper and 1 if the feature is not known.
       All other exits are 0.

CATEGORY
       Utility

BitKeeper Inc                         1E1                    bk features(none)
$
help://files
help://files.1
help://bk-files
help://bk-files.1
bk files(none)              BitKeeper User's Manual             bk files(none)

NAME
       bk files - demo program to show file name expansion

SYNOPSIS
       bk files [<file> ... | -]

DESCRIPTION
       Most  BitKeeper  commands  are  designed  to operate on a set of files.
       This command demonstrates how to specify the set of files.

       File names can be implied, be specified as arguments, be implied with a
       directory name argument, or be specified as a list on stdin.

       Implied (nothing specified)
                   If no files are specified, the default list is  every  ver-
                   sion controlled file in the current working directory.
       Listed      If  the  command invocation includes a list of files at the
                   end then those files and only those files are operated upon
                   by the command.  If any of the specified files are a direc-
                   tory then the list is expanded to include all revision con-
                   trolled files associated with the specified directory.
       All files   A common thing to want to do is to run  a  command  against
                   all  files under revision control.  There is an easy way to
                   do this:

                       bk -A <command>

       All user files
                   The previous form will list all  files,  including  deleted
                   files  and  metadata files.  A more useful form is one that
                   only lists files that are user files and are not deleted:

                       bk -U get

       STDIN       If the command invocation has as its last  argument  a  "-"
                   then the command reads the standard input stream for a list
                   of  files,  one per line, on which to operate.  If the list
                   is in the form

                       file.c|1.5
                       header.h|1.8
                       manpage|1.8..1.20

                   then the receiving command will  operate  on  the  supplied
                   revision[s].
       WILDCARDS   It  is  possible to restrict the command to a specified set
                   of files using what are called wild cards (or globs in Unix
                   terminology).  If a name specified includes a glob  pattern
                   then  only files matching that pattern are processed.  Only
                   the basename of the file is compared against the glob,  not
                   the  full  path  name.  The patterns are standard Unix glob
                   patterns (see "bk help glob") with one exception for conve-
                   nience: a "=" may be used in place of a "*"  to  match  any
                   pattern.   In  order for the "=" alias to work, an environ-
                   ment variable BK_GLOB_EQUAL must be set to the  value  YES.
                   To match all header files both of the following do the same
                   thing:

                       export BK_GLOB_EQUAL=YES
                       bk diff =.h
                       bk diff '*.h'

                   If  you have a file with an "=" or other glob characters in
                   its name you will need to  either  quote  those  characters
                   with  a  proceeding  backslash (i.e., "\*.h" matches a file
                   named "*.h"), or if the file name specified contains a  "/"
                   then  no glob expansion is applied.  This makes it possible
                   to do things like

                       bk diff './*.h'

                   and have that match the file named "*.h".

EXCEPTIONS
       Certain commands do not autoexpand directories because the commands are
       destructive.  An example is bk unedit, this  command  throws  away  any
       changes  made  to  files and it refuses to autoexpand to all files, the
       files must be specified.

EXAMPLES
       See changes in the current directory:

           bk diff

       See all changes in the repository:

           bk -U diff

       See all changes to header files in the repository:

           bk -U diff '*.h'

       List all C or header files containing the phrase "proc" in their name:

           bk -A files '*proc*.[ch]'

       See all modified user files:

           bk -cU

       See all extra files:

           bk -xA

EXIT STATUS
       bk files returns exit status 0.

SEE ALSO
       bk help bk, bk help diff, bk help glob, bk help gfiles

CATEGORY
       File
       Repository

BitKeeper Inc                         1E1                       bk files(none)
$
help://filetypes
help://filetypes.1
help://bk-filetypes
help://bk-filetypes.1
help://File/filetype
help://File/gfile
help://File/sfile
help://File/pfile
help://File/cfile
help://File/s.file
help://File/p.file
help://File/c.file
help://File/x.file
help://File/z.file
bk filetypes(none)          BitKeeper User's Manual         bk filetypes(none)

NAME
       bk filetypes - summary of BitKeeper file types

DESCRIPTION
       For each file under revision control, there are a number of files asso-
       ciated with the main file.  The following list describes the purpose of
       each file:

       <foo>        "gfile" - the "gotten" file; this is your source file
       SCCS/s.<foo> "sfile"  -  the  revision  history  of all versions of the
                    gfile
       SCCS/x.<foo> "xfile" - a temporary file which contains the new  version
                    of  the  sfile  under  construction.  When the check-in is
                    finished, the sfile is removed and the xfile is moved into
                    its place.
       SCCS/c.<foo> "cfile" - a temporary copy of check in comments, currently
                    used only by bk citool.
       SCCS/d.<foo> "dfile" - a temporary file  that  indicates  there  is  at
                    least one pending delta in the sfile.

FUTURE DIRECTIONS
       Other than the gfile, accessing any of these files directly is discour-
       aged.   In  the future, all of the meta-files will be virtual.  At that
       point, there will be interfaces to read them, test for their  presence,
       and write them.

CATEGORY
       Overview
       File

BitKeeper Inc                         1E1                   bk filetypes(none)
$
help://findkey
help://findkey.1
help://bk-findkey
help://bk-findkey.1
bk findkey(none)            BitKeeper User's Manual           bk findkey(none)

NAME
       bk findkey - look for keys in files

SYNOPSIS
       bk findkey [opts | key] [<file> ... | -]

DESCRIPTION
       bk  findkey may be used to look for keys in one or more files.  In Bit-
       Keeper, keys are the internal names for files and/or file deltas.

       The keys may be either the long form or the MD5 form (see bk log).  You
       may search for keys using only a portion of the key as described below.
       Each delta in each file that matches all specified parts is listed.

OPTIONS
       -b<random> specify the random bits part of a key.
       -c<chksum> specify the checksum part of a key.
       -e<email>  specify the user@host.domain part of a key.
       -h<h.dom>  specify the host.domain part of a key.
       -p<path>   specify the path part of a key.
       -t<utc>    specify the timestamp part of a key.  Date formats  accepted
                  are either yyyymmddhhmmss or yyyy/mm/dd hh:mm:ss.
       -u<user>   specify the username part of a key.

SEE ALSO
       bk help log

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk findkey(none)
$
help://findmerge
help://findmerge.1
help://bk-findmerge
help://bk-findmerge.1
bk findmerge(none)          BitKeeper User's Manual         bk findmerge(none)

NAME
       bk findmerge - show where two revisions where merged

SYNOPSIS
       bk findmerge [-a] -r<rev1> -r<rev2> <file>

DESCRIPTION
       This  command  will  print  the revision which is the least upper bound
       (LUB) of the specified two revisions.  If there is more than one  merge
       for  the  two  revisions  (e.g. because two different users merged them
       independently), then findmerge will return the oldest one.  Adding  the
       -a option lists all of them.

OPTIONS
       -a      list  all  of  the least upper bound merges where the two given
               revisions came together.
       -r<rev> specify the first and second rev (both are required).

       CATEGORY
              Utility

BitKeeper Inc                         1E1                   bk findmerge(none)
$
help://fixtool
help://fixtool.1
help://bk-fixtool
help://bk-fixtool.1
bk fixtool(none)            BitKeeper User's Manual           bk fixtool(none)

NAME
       bk fixtool - fix up pending changes

SYNOPSIS
       bk fixtool [-fpsuw] [<file> ...]

DESCRIPTION
       bk  fixtool  allows  you  to revise changes made to one or more working
       files prior to creating a delta.  Typically, this feature is used imme-
       diately before a check in when  it  is  realized  that  that  there  is
       unwanted  work,  such  as debugging messages, mixed in with useful work
       which should be saved.

       bk fixtool calls "bk gfiles -c" to find files which have been  changed.
       The  default  is to find all files which have been changed but this may
       be controlled by specifying a set of files and/or directories.

       For each changed file bk fixtool

       =>  clears the screen
       =>  shows the changes (via bk diff)
       =>  and prompts for an action.

       The action must be a letter followed by "Enter".  The choices are:

       n   (no) skips this file and continues to the next file.
       q   (quit) stop processing files.
       u   (unedit) discards all changes made to the named file.
       y   (yes) run bk fmtool on the previously checked  in  version  of  the
           file  and  the current working file.  This is most commonly used to
           remove debugging statements while leaving the new work.
           Note: When you have selected the changes you want, clicking  "Done"
           saves your merges, overwriting the current working file.

OPTIONS
       -f  forces the answer to all prompts to be "y".
       -p  passed through to bk diff to get procedural diffs.
       -s  passed through to bk diff to get side-by-side diffs.
       -u  passed through to bk diff to get unified diffs.
       -w  passed through to bk diff to ignore whitespace in diffs.

SEE ALSO
       bk help citool, bk help diff, bk help fmtool

CATEGORY
       File
       Repository

BitKeeper Inc                         1E1                     bk fixtool(none)
$
help://flags
help://flags.1
help://bk-flags
help://bk-flags.1
bk flags(none)              BitKeeper User's Manual             bk flags(none)

NAME
       bk flags - show a listing of files and their BitKeeper flags

SYNOPSIS
       bk flags [<file> ... | -]

DESCRIPTION
       Displays  a listing of files and their BitKeeper flags in the following
       format:

           foo.c  BITKEEPER,CSETMARKED,EXPAND1,SCCS

       The flags are described on the bk admin man page.

SEE ALSO
       bk help admin, bk help log

CATEGORY
       Admin

BitKeeper Inc                         1E1                       bk flags(none)
$
help://fm3tool
help://fm3tool.1
help://bk-fm3tool
help://bk-fm3tool.1
bk fm3tool(none)            BitKeeper User's Manual           bk fm3tool(none)

NAME
       bk fm3tool - BitKeeper three-way merge tool

SYNOPSIS
       bk fm3tool [-o<filename>] [-fn] -l<local_rev> -r<remote_rev> <file>

DESCRIPTION
       bk  fm3tool  is  a  three-way merge tool used for resolving conflicting
       changes between two different versions of a file  that  have  a  common
       ancestor.   Normally  fm3tool  is  not run from the command line; it is
       started during the resolve phase of a pull by responding  with  "f"  at
       the merge prompt.

       The  purpose  of  this tool is to aid in the resolving of parallel work
       that contains conflicts.  A conflict is defined as one  or  more  lines
       that were added, deleted, or modified in the local version of the file,
       at  or adjacent to one or more lines that were added, deleted, or modi-
       fied in the remote version of the file.

       When the tool  is  started  up,  all  of  the  changes  that  could  be
       automerged have been automerged.  The rest of the changes are noted as

           <<<<<<
           UNMERGED
           >>>>>>

       in  the merged file window (see below).  The tool's default behavior is
       to go to the first conflict and wait for you to merge  it.   Typically,
       you  merge  that  conflict,  go  to the next conflict, and repeat until
       done.  It is not necessary to merge the conflicts  in  order;  you  may
       look  at them all and merge them in any order.  You must merge all con-
       flicts, however, before you may save the file and exit.

       When you are finished, you must save the file to complete the merge.

RUNNING OTHER GUI TOOLS
       It might be useful to look at other  information  associated  with  the
       changes.  The "File" menu allows you to run several other tools:

       revtool  This  shows  you  the  file  history  with the GCA, local, and
                remote versions highlighted.  This is useful to see  the  pro-
                gression of changes by selecting the GCA and then diffing down
                one side and then the other side one delta at a time.
       csettool May  be run on the additions, deletions, or both.  This can be
                useful when the context needed to resolve the conflict is con-
                tained elsewhere in the changeset that caused the conflict.

SCREEN LAYOUT
       When bk fm3tool is started, there are six main  areas  on  the  screen.
       Notice  that  information about the local repository is on the left and
       remote repository is on the right.

           +--------------------+------------------- +
           | Local change info  | Remote change info |
           +--------------------+--------------------+
           | - GCA baseline     | - GCA baseline     |
           | + Local change     | + Remote change    |
           |                    |                    |
           +--------------------+-----+--------------+
           | Merge                    | Information  |
           |                          |              |
           |                          |              |
           +--------------------------+--------------+

       Local change info  Revision history for the local changes to the file
       Remote change info Revision history for the remote changes to the file
       Local diff         Diff of local file versus the greatest common ances-
                          tor (GCA)
       Remote diff        Diff of remote file versus the GCA
       Merge              Result of the merge
       Information        Informational messages and navigation controls

       As the tool moves from change to  change,  the  top  two  windows  will
       change to show revision history of the current highlighted change.  The
       history  shown  for the deleted lines corresponds to the revisions that
       did the deletions.  The annotation  about  which  revisions  added  and
       deleted  lines  in  the files are shown by selecting View->Show Annota-
       tions.

OPTIONS
       -o<filename>   save output to the specified file.
       -f             force overwrite of existing  file.  By  default  fm3tool
                      will not overwrite an existing merge file.
       -l<local_rev>  the  revision  in  the  file  to  be considered the most
                      recent local work.
       -n             do not write any merged output, put the tool in readonly
                      mode.
       -r<remote_rev> the revision in the  file  to  be  considered  the  most
                      recent remote work.

HAND-EDITING
       A merge conflict may be edited manually by single-clicking over a high-
       lighted  diff  in  the merge window. The merge window will then enter a
       special edit mode where you can make changes.  To exit the  edit  mode,
       press  <escape>  or  click on area that divides the merge area from the
       areas above it.

COPY AND PASTE
       When the tool is in edit mode, it  is  possible  to  select  text  from
       either  diff  window  and  then copy them into the clipboard.  The text
       copied to the clipboard is taken from the window with the active focus.
       This can include the merge window itself.

       Pasting while focused in the left or right diff window will paste  into
       the  merge  window  at  the  insertion cursor.  If the current block is
       UNMERGED, it will be replaced with the contents of the clipboard.  Sub-
       sequent pastes will be inserted  after  the  last  insertion.   Pasting
       while  focused  in  the merge window itself will paste at the insertion
       cursor with no special action.

KEYBOARD BINDINGS
       fm3tool has two major modes: "merging mode," for navigating through the
       diffs and conflicts and "editing mode," for hand-editing a merge.  Each
       of these modes has its own set of key bindings.

   MERGING MODE
       Left-Click        Over a highlighted block  in  the  upper  windows,  a
                         left-click  will append the highlighted block of text
                         to the current merge  region  in  the  merge  window.
                         Left-Click Over the merge window will enter hand-edit
                         mode. See the section on HAND EDITING, above.
       Right-Click       Over  a  highlighted  block  in  the upper windows, a
                         right-click will append  the  single  line  that  was
                         clicked  on  to the current merge region in the merge
                         window.
       Shift-Left-Click  Works like a left click, but replaces the contents of
                         the current merge rather than adding on to it.
       Shift-Right-Click Works like a right click, but replaces  the  contents
                         of  the  current merge with the line that was clicked
                         on.
       PageUp            Scroll up one page.
       PageDown          Scroll down one page.
       UpArrow           Scroll up one line.
       DownArrow         Scroll down one line.
       LeftArrow         Scroll left.
       RightArrow        Scroll right.
       <space>           move to the next conflict.
       [                 Move to previous difference.
       ]                 Move to next difference.
       {                 Move to previous conflict.
       }                 Move to next conflict.
       -                 Move to first difference.
       +                 Move to last difference.
       x                 Toggle the display of the GCA.
       z                 Toggle the display of annotations.
       c                 Clears the current merge region.
       a                 Restores the auto-merge.
       m                 Restores the manual merge.
       s                 Saves the merge file.
       u                 Will undo the effects that the last mouse  click  had
                         on the current merge region.
       e                 This  will move the focus to the merge edit window at
                         the bottom and put the tool in edit mode.
       Control-q         Exit from fm3tool.

   EDITING MODE
       <escape>          Exit edit mode
       Control-a         move to start of line.
       Control-e         move to end of line.
       Control-n         move to next line.
       Control-p         move to previous line.
       Control-d         delete character under cursor.
       Control-y         Redo the last undone change.
       Control-z         Undo the last typed change.
       UpArrow           Move the cursor up one line.
       DownArrow         Move the cursor down one line.
       LeftArrow         Move the cursor left one character.
       RightArrow        Move the cursor right one character.
       PageUp            Scroll up one page.
       PageDown          Scroll down one page.

SEE ALSO
       bk help config-gui, bk help resolving, bk help smerge, bk help fmtool

CATEGORY
       GUI-tools

BitKeeper Inc                         1E1                     bk fm3tool(none)
$
help://fmtool
help://fmtool.1
help://bk-fmtool
help://bk-fmtool.1
help://GUI-tools/fm
bk fmtool(none)             BitKeeper User's Manual            bk fmtool(none)

NAME
       bk fmtool - BitKeeper side-by-side merge tool

SYNOPSIS
       bk fmtool
       bk fmtool <local_file> <remote_file> <merged_file>

DESCRIPTION
       bk  fmtool  is a side-by-side merge tool used for resolving differences
       between two different versions of a file.

       If bk fmtool is started without arguments, use  the  "Open"  button  to
       select the files that you wish to merge.

       When  fmtool  is  started,  there are three main windows, the ``local''
       window on the left,  the  ``remote''  window  on  the  right,  and  the
       ``merge''  window on the bottom.  When doing a bk pull, your repository
       is considered local and the other one is considered  remote,  and  Bit-
       Keeper  arranges to have the local version of the file on the left side
       and the remote version on the right.

       Merging is done as follows:

       =>  bk fmtool starts scanning both files from the top until  difference
           are  found.  The identical work (i.e the work up to the point where
           the differences are found) is put in the merge window.
       =>  The user selects whether the remote or local version of the  change
           will  be  used  by  clicking the "Use Left" or "Use Right" buttons.
           When the user picks a version, the changes are placed in the  merge
           window.
       =>  Repeat the process until all changes are placed in the merge file.

       The  changes in the merge window are colored so that it is easy to tell
       whether the work was from the local or remote file.

       Each merge may be undone either by clicking the "Undo" button or  using
       the  keys listed below.  The undo works all the way to the start of the
       file.

       If you need to make adjustments to the merge, you can edit the work  in
       the merge window.  The merge window is a simple editor - move the mouse
       pointer where you want to make the changes and start typing.

BINDINGS
       Control-LeftArrow   Use the diff in the left window.
       Control-RightArrow  Use the diff in the right window.
       Control-DownArrow   Skip the current diff, using neither.
       Control-UpArrow     Undo the last choice.
       Control-q           Exit from bk fmtool.
       Alt-UpArrow         Grow the merge window and shrink the diff windows.
       Alt-DownArrow       Grow the diff windows and shrink the merge window.

       The  following  keys operate on the set of windows that have the focus.
       Click in the diff windows or the merge window to set the focus.

       PageDown            Scroll the diffs or the merge window up one screen.
       PageUp              Scroll the diffs or the merge window up one screen.
       DownArrow           Scroll the diffs or the merge window up one line.
       UpArrow             Scroll the diffs or the merge window up one line.

SEE ALSO
       bk help config-gui, bk help merge,  bk  help  merge-binaries,  bk  help
       resolving

CATEGORY
       GUI-tools
       File

BitKeeper Inc                         1E1                      bk fmtool(none)
$
help://gate
help://gate.1
help://bk-gate
help://bk-gate.1
bk gate(none)               BitKeeper User's Manual              bk gate(none)

NAME
       bk gate - set or show the gate status of a nested collection

SYNOPSIS
       bk gate [-q] .
       bk gate [-q] -r

DESCRIPTION
       The  bk  gate command either reports whether the nested collection is a
       gate or it changes that nested collection to be a gate.

       A gate repository is part of BitKeeper's product line functionality.  A
       gate is an instance of a nested collection in which changesets are con-
       sidered "safe", they will not be removed or collapsed.   Similarly  the
       set of components that are populated will not be unpopulated.

       The  gate  concept  exists  to allow bk pull to run in --unsafe mode by
       default when pulling from a gate. This allows developers to  work  with
       sparse  repositories  (where  not  all  components are populated) while
       guaranteeing that work will never be lost.

       With an argument of ".", it marks the  nested  collection  as  a  gate.
       With  no  argument,  the  command prints the gate status.  With -q, the
       exit status indicates gate status; 0 means it is, 1 means it is not.

RESTRICTIONS
       Inside of a gate, commands that would  remove  information  are  disal-
       lowed.   bk  undo, bk collapse, bk unpopulate are examples of such com-
       mands.  It is common that many other clones depend on the gate to be  a
       "safe"  container  of changes so removing information is not allowed by
       default.

       If it happens that a changeset gets pushed to a gate that  really  must
       be  removed,  then remove the gate status, undo (or unpull) the change-
       set, and put the gate status back.

OPTIONS
       -r  Unmark the nested collection as a gate.
       -q  Run silently.

SEE ALSO
       bk help portal, bk help pull

CATEGORY
       Nested

BitKeeper Inc                         1E1                        bk gate(none)
$
help://gca
help://gca.1
help://bk-gca
help://bk-gca.1
bk gca(none)                BitKeeper User's Manual               bk gca(none)

NAME
       bk gca - show the greatest common ancestor

SYNOPSIS
       bk gca -r<rev1> -r<rev2> <file>

DESCRIPTION
       This  command  will  print  the  revision  which is the greatest common
       ancestor (GCA) of the specified two revisions.  If there is no node  in
       the  graph  which  is an exact match, the printed revision will have an
       include list and/or an exclude list of revisions which must be added to
       the revision in order to get the actual GCA.

OPTIONS
       -r<rev> specify the first and second rev (both are required).

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk gca(none)
$
help://get
help://get.1
help://bk-get
help://bk-get.1
help://co
help://checkout
bk get(none)                BitKeeper User's Manual               bk get(none)

NAME
       bk get - check out BitKeeper files

SYNOPSIS
       bk get [options] [<file> ... | -]

ALTERNATE
       bk checkout [-qT] [<file> ... | -]

DESCRIPTION
       bk  get is used to check out files for viewing or editing.  By default,
       files are checked out unlocked and read-only.

       bk checkout is used to to checkout files in the  repository's  checkout
       mode (bk get defaults to read-only, this form matches the checkout con-
       fig).

OPTIONS
       -A<bdnpru> Align  prefix  output  in a human readable form.  The set of
                  annotations will be followed by a vertical bar and  a  space
                  before  the  data  from  each line of the file starts.  Each
                  annotation is aligned in a column.  The  option  argument[s]
                  turn  on  one  or more annotations as a prefix to each line.
                  The possible annotations are:

                  b   Prefix each line with the basename of the file.
                  d   Prefix each line with the date of last modification.
                  n   Prefix each line with its line number.
                  p   Prefix each line with pathname of the file  relative  to
                      the root of the repository.
                  r   Prefix each line with the revision of last modification.
                  u   Prefix  each line the name of the user who last modified
                      it.

       -a<bdnpru> Similar to "-A" but without the alignment.
       -e         Checkout the file for editing (same as bk edit).
       -g         Suppress the retrieval of any text;  sometimes  useful  with
                  "-e".
       -h         Invert sense of file's hash flag.
       -i<list>   Include revs in <list>.
       -k         Don't expand RCS or SCCS keywords.  "-k" is implied by "-e".
       -p         Write file to standard output (useful in scripts).
       -P         Write  to  stdout,  forcing  a check out even if the file is
                  corrupted (i.e., has a bad checksum).
       -q         Run quietly, suppressing diagnostics.
       -r<rev>    Get this revision (or key or changeset revision--see bk help
                  terms under "rev argument").  If combined with "-e"  (edit),
                  BitKeeper checks out the tip revision combined with a set of
                  deltas  to be included and excluded to produce the requested
                  revision.
       -S         Check out the file if and only if it is not already  checked
                  out.
       -T         Set  the  gfile's  modification time to the delta's creation
                  time.
       -x<list>   Exclude revs in <list>.

NOTE
       You may not need to check out every file in order to compile your  pro-
       gram  since  most  versions of the Make program will check files out as
       they are needed.  In order for this to work, the get command  needs  to
       be  in  your  path  (see bk help links) and the dependencies need to be
       correct in the Makefile.  If that is true, a simple "make"  will  check
       out and build your product.

EXAMPLE
       If  you are using Gnu Make the following will check out any non-checked
       out files:

           JUNK := $(shell bk -Ur. -1 -^G checkout)

SEE ALSO
       make(1), bk help config-etc, bk help edit, bk help keywords

CATEGORY
       Common
       File

BitKeeper Inc                         1E1                         bk get(none)
$
help://gethost
help://gethost.1
help://bk-gethost
help://bk-gethost.1
help://hostname
bk gethost(none)            BitKeeper User's Manual           bk gethost(none)

NAME
       bk gethost - display machine name

SYNOPSIS
       bk gethost [-nr]

DESCRIPTION
       Outputs  the  fully-qualified name of the machine.  Used primarily when
       doing BitKeeper scripting.

       -n  print the internet address instead of the host

       -r  print the real host name, ignoring $BK_HOST.

NOTES
       On some UNIX systems, it can happen that BitKeeper will output an error
       message complaining that localhost is an invalid hostname.   Often  the
       fix  is  to  simply  add a fully qualified hostname to /etc/hosts.  For
       example:

              ::1  localhost6 yourhost.yourdomain.com

SEE ALSO
       bk help getuser

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk gethost(none)
$
help://getuser
help://getuser.1
help://bk-getuser
help://bk-getuser.1
bk getuser(none)            BitKeeper User's Manual           bk getuser(none)

NAME
       bk getuser - display user name

SYNOPSIS
       bk getuser [-r]

DESCRIPTION
       This command displays BitKeeper's idea of the caller's user name.

       -r  print the real user name, ignoring $BK_USER.

SEE ALSO
       bk help gethost

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk getuser(none)
$
help://gfiles
help://gfiles.1
help://bk-gfiles
help://bk-gfiles.1
help://Files/sfiles
bk gfiles(none)             BitKeeper User's Manual            bk gfiles(none)

NAME
       bk gfiles - generate lists of BitKeeper controlled files

SYNOPSIS
       bk gfiles [-01acCdDgGijlnRsSuUvxy] [-p[<A|C>]] [<dirs>]

DESCRIPTION
       bk  gfiles  is  used to generate lists of revision control files, files
       related to revision control files,  directories  related  (or  not)  to
       revision  control  files,  and/or files not under revision control.  In
       other words, if you need a list of files,  you've  come  to  the  right
       place.

       bk  gfiles without any arguments finds all s.files in or below the cur-
       rent working directory.  This is what "bk -r <command>" uses to  gener-
       ate the list of files to feed to <command>.

       If a directory and/or file list is specified, then each of the items in
       the list is processed; directories are processed recursively.

OPTIONS
       Most  of  the  options below may be combined to list files which are in
       different states, for example, -cx would list modified files and  extra
       files not yet under BitKeeper control.

       When combining options it is best to also add -v so that what is listed
       is unambiguous.

       -0   Use a null character (instead of a newline) to separate each file-
            name printed.  This is to useful with GNU xargs -0.
       -1   Only  examine  the  current  (or named) directory.  Do not go into
            subdirectories.
       -a   Examine all files, even if listed in BitKeeper/etc/ignore.
       -c   List changed files (locked and modified).  If clock_skew is set in
            the config file then the file time stamps and other attributes are
            used to speed scanning.  The acceptable clock skew can be  config-
            ured, see clock_skew in bk help config-etc.
       -C   Identical to "-c" except the file time stamps are not trusted.
       -d   List directories under BitKeeper control (SCCS subdir exists).
       -D   List directories with no (or empty) SCCS subdirs.
       -E   Shorthand which means "show everything interesting in verbose for-
            mat".  Currently the same as: "-cdDGijlnRsuvxyp"
       -G   List files only if they are checked out ("gotten").
       -^G  List files only if they are not checked out ("not gotten").
       -i   List files which would normally be listed as extras (see -x below)
            but   are   suppressed  because  they  are  present  in  the  Bit-
            Keeper/etc/ignore file.  Note that this  options  works  on  files
            that were ignored, but not on directories that were pruned.  There
            is no way to force bk gfiles to descend into pruned directories.
       -j   List  junk files, i.e., files in SCCS subdirectories which are not
            metadata.
       -l   List locked files (p.file and/or z.file).
       -n   List s.files that are not in the correct location.
       -p   List files with one or more pending deltas.
       -pC  List only the tip delta of files with one or more pending  deltas,
            in the following format: <file>|<tip_rev>.
       -pA  List  all pending deltas of files with one or more pending deltas,
            in the following format: <file>|<rev>.
       -P   Like "-p", but don't trust the d.file.  Use the s.file for verifi-
            cation and create or delete the d.file to match the status of  the
            s.file.
       -R   List  sub-repositories, i.e., any repository root within your tree
            other than your repository root.
       -S   Produce a summary listing only, typically combined with "-E".
       -u   List unlocked files.
       -U   List user files only, skipping the ChangeSet file  and  everything
            below BitKeeper/ other than BitKeeper/triggers/*.
       -v   Prefix  the output with information about the state of the s.file.
            The information is in a 7 character field, followed  by  a  space,
            then  followed by the filename.  Each of the columns are described
            below, with the  notation,  then  the  option,  then  description.
            Script  writers  may depend on the format below with the following
            caveat: any addition information will be added in  columns  8,9,10
            etc.   The  first  space  found  will be the separator between the
            annotations and the filename.

            d------ (-d) a directory containing BitKeeper files
            D------ (-D) a directory containing no BitKeeper  files  (but  may
                         have subdirectories with BitKeeper files).
            i------ (-i) a file that is extra but is normally ignored
            j------ (-j) extra file under / dir
            R------ (-R) the file is a sub-repository root (overrides -d)
            s------ (-s) a file that is under BitKeeper control
            x------ (-x) a file that is not under BitKeeper control
            sl----- (-l) a BitKeeper file that is locked
            su----- (-u) a BitKeeper file that is not locked
            slc---- (-c) a  BitKeeper  file  that  is locked and modified (aka
                         changed)
            s--p--- (-p) a BitKeeper file that has one or more pending deltas
            s---G-- (-G) a BitKeeper file that is checked out (aka gotten)
            s----n- (-n) a BitKeeper file that is not in its recorded location
            s-----y (-y) a BitKeeper file that has saved checkin comments
            x-----y (-y) an extra file that has saved checkin comments

            Note: when verbose output is requested as much information as pos-
            sible is generated.  Currently, the information requested  by  the
            -n  option  is  suppressed  unless  that  option  was specifically
            requested because  of  the  performance  implications.   In  other
            words, unless you add -n to the options, that field will always be
            "-".

       -x   List files which have no revision control files.
       -y   List files which have saved checkin comments, the files listed may
            be either extra files and/or files under BitKeeper control.

NOTES
       bk  gfiles  will  not  descend  into  directories  pruned  in  the Bit-
       Keeper/etc/ignore file.

       The default ignore list shown in bk help ignore  is  always  in  effect
       even with -a.

       Revision control files must look like SCCS/s.*, not foo/bar/blech/s.*.

SEE ALSO
       bk help history, bk help ignore, bk help new

CATEGORY
       File

BitKeeper Inc                         1E1                      bk gfiles(none)
$
help://glob
help://glob.1
help://bk-glob
help://bk-glob.1
bk glob(none)               BitKeeper User's Manual              bk glob(none)

NAME
       bk glob - demo program to show glob pattern expansion

SYNOPSIS
       bk glob <pattern> <string> [<string> <string> ...]

DESCRIPTION
       Some  BitKeeper  interfaces  use what are called "glob patterns," some-
       times known as wild cards.  Examples include  the  configuration  file,
       history listing (bk changes), and file name expansion (bk files).

       This command may be used to match a glob against one or more strings to
       see examples of how the pattern matching works.

WILDCARD MATCHING
       A  string  is  a glob pattern if it contains one of the characters "*",
       "?", "[", or sometimes "=".  (The last one, "=", is an alias  for  "*",
       to  avoid  shell quoting in many cases.  See CONFIGURATION below.)  The
       glob pattern is used to match one or more strings (or file names), usu-
       ally in a process that takes a glob pattern  and  a  list  of  possible
       matches  and returns the subset of the list which matches the glob pat-
       tern.  Matching works as follows:

       ?      Matches any single character (unless "?" is between brackets).

       *      Matches any string (unless "*" is between brackets).

       [...]  A set of characters enclosed in brackets matches a single  char-
              acter if and only if the character is in the set.

       [^...] As  above  but inverts the set.  In other words "[^abc]" matches
              any character except "a", "b", or "c".

CONFIGURATION
       It is possible to disable all use of globs in file  name  expansion  by
       setting the environment variable BK_NO_FILE_GLOB to any value.

       Since  aliasing  "=" for "*" is not a standard feature and it may cause
       problems when processing files with "=" as part of their name, it  must
       be  explicitly   enabled  by setting BK_GLOB_EQUAL to the value of YES.
       No other value will enable this feature.

EXAMPLES
       Test a simple pattern match that matches file.c and file.h:

           bk glob '*.[ch]' file.c file.h file.1

       List all files ending in ".1":

           export BK_GLOB_EQUAL=YES
           bk -A files =.1

       See changes in all header files in the current directory:

           bk diff '*.h'

       See the revision history for all C/header files with the phrase  "sccs"
       in their name:

           bk sccslog '*sccs*.[ch]'

       See all changesets which include the phrase "BUGID:" followed by a num-
       ber:

           bk changes '-/BUGID:[123456789]/'

BUGS
       Sets  of characters, i.e., [A-Z], have only marginal support.  Escaping
       the minus in the set is not supported.

SEE ALSO
       bk help config-etc, bk help changes, bk help files

CATEGORY
       File
       Repository

BitKeeper Inc                        201E1                       bk glob(none)
$
help://gone
help://gone.1
help://bk-gone
help://bk-gone.1
bk gone(none)               BitKeeper User's Manual              bk gone(none)

NAME
       bk gone - mark a file (key) as gone

SYNOPSIS
       bk gone [-q] [<key key ...> | -]

DESCRIPTION
       The  bk  gone  command  is used when a file has been lost or physically
       deleted and the administrator of the repository has  decided  that  the
       file should be marked as gone.

       The key of the file can be generated from an existing file as follows:

           $ bk log -r+ -d:ROOTKEY: file

       The  key that is returned from the above command  needs to be marked as
       gone if the file is to be removed from the repository.

       Sometimes a file is lost (i.e. the gotten file and the s.file have been
       removed by accident). Whenever repository-level commands are run,  con-
       sistency  checks are performed. When these checks run, they will notice
       that a file is lost and will complain.  After looking over the  consis-
       tency  check  output  carefully,  you  can run the following command to
       automatically mark all the missing files as gone:

           bk -r check -ag | bk -R gone -

OPTIONS
       -q  be quiet.

NOTE
       Just adding the key to the gone file does not make the file "go  away."
       All  it  does  is make BitKeeper be happy if the file is actually gone.
       If you want to really remove the file, save the key, physically  remove
       the  file, and run "bk -r check -a".  If that complains, run bk gone on
       the listed keys.

SEE ALSO
       bk help check

CATEGORY
       Admin

BitKeeper Inc                         1E1                        bk gone(none)
$
help://grep
help://grep.1
help://bk-grep
help://bk-grep.1
bk grep(none)               BitKeeper User's Manual              bk grep(none)

NAME
       bk grep - search some/all revisions of one or more files for a pattern

SYNOPSIS
       bk grep [options] <pattern> [<file> ... | -]

DESCRIPTION
       The  bk grep command searches the named files (or standard input if the
       file name "-" is given) for lines containing a match to the given  pat-
       tern.   The  pattern  may  be a perl compatible regular expression.  By
       default, bk grep prints the matching lines.

       While designed to be command line compatible with GNU grep, bk grep can
       search in the most recent revision of a file, all revisions of a  file,
       a subset of revisions of a file, or the checked out and (possibly) mod-
       ified  version of a file.  By default, bk grep searches the checked out
       version of a file and if that is not present then it searches the  most
       recent  version of the file.  The "-r", "-R", and "-c" options are used
       to control where in a file's history to search.

       The printed lines may be annotated with  file  names,  dates,  revision
       numbers, line numbers, and/or user names.

OPTIONS
       -A<num>    Print  num  lines  of trailing context after matching lines.
                  Places a line containing "--" between contiguous  groups  of
                  matches.  (Like GNU grep.)
       -A<bdnpru> Annotate  the output with information from the revision his-
                  tory.  Each annotation is aligned in a column.   The  option
                  argument[s]  turn  on one or more annotations as a prefix to
                  each line.  The order of fields is  fixed  (no  matter  what
                  order  you specify them) and is the same as the order listed
                  below:
                  p      Prefix each line with the pathname of the file  rela-
                         tive  to  the current working directory.  The name is
                         always the current name of the file even  if  it  has
                         been renamed.
                  d      Prefix each line with the date of last modification.
                  u      Prefix  each  line with the name of the user who last
                         modified it.
                  r      Prefix each line with the revision of last  modifica-
                         tion.
                  n      Prefix each line with its line number.

                  This  option  is  incompatible  with  the  -A/-B/-C  context
                  options, use -a if you need more lines of context.
       -a<dnpru>  Similar to "-A" but each annotation is followed by  a  colon
                  rather  than a set of spaces aligning the output.  The order
                  of fields is fixed (no matter what order you  specify  them)
                  and is: pathname, date, user, revision, line number.
       -B<num>    Print  num  lines  of leading context before matching lines.
                  Places a line containing "--" between contiguous  groups  of
                  matches.  (Like GNU grep.)
       -C[<num>]  Print num lines of output context.  Places a line containing
                  "--"  between  contiguous groups of matches.  If no value is
                  given defaults to 2.  (Like GNU grep.)
       -c<dates>  Select the versions to search as all deltas created  in  the
                  specified range of dates.  (Different than GNU grep.)
       -h         Do  not print filenames with matches when multiple files are
                  searched.  Normally, if more than one file is  searched  the
                  results are prefixed with the filename.  (Like GNU grep.)
       -H         Print  the  file  name  even if there is only one file being
                  searched.  Normally, if only one file is searched, then  the
                  file  name  is  skipped  unless  it was explicitly selected.
                  (Like GNU grep.)
       -i         Ignore case distinctions in both the pattern and  the  input
                  files.  (Like GNU grep.)
       -l         Suppress normal output; instead print the name of each input
                  file  from  which  output would have normally been produced.
                  (Like GNU grep.)
       -L         Suppress normal output; instead print the name of each input
                  file from which no output would have normally been produced.
                  (Like GNU grep.)
       -n         Prefix each line with the line number from its  input  file.
                  (Like GNU grep.)
       -q         Do  not produce any output.  Exit immediately with zero sta-
                  tus if any match is  found.  (Like GNU grep.)
       -r<rev>    Only look in revision <rev> for the pattern.
       -R[<rev>]  Only look in range of revisions <rev> for the  pattern.   If
                  <rev>  is  not  specified,  that implies all versions of the
                  file[s].  The difference between this option and the  previ-
                  ous  option  is that in this case bk grep looks in the lines
                  added by the specified revision, but in the "-r"  case,  the
                  entire contents of the specified version is searched.
       -v         Invert  the sense of matching, to select non-matching lines.
                  (Like GNU grep.)
       -x         Select only those matches that exactly match the whole line.
                  (Like GNU grep.)

EXIT STATUS
       bk grep returns exit status:

       0   if any matches were found
       1   if no matches were found
       2   if an error occurred

EXAMPLES
       Look for a pattern in the working copy of a file:

           $ bk grep pattern foo.c

       Look for a pattern in the most recent checked in version of a file:

           $ bk grep -r+ pattern foo.c

       Look for a pattern in all checked in versions of a file (this  searches
       every  line  ever  present  in  the  file, even if some lines have been
       deleted):

           $ bk grep -R pattern foo.c

       Look for a pattern in all files in the current working directory:

           $ bk grep pattern

       Look for a pattern in any version of any file in your  tree  (including
       deleted  files;  if this doesn't find it then pattern was never present
       in your history):

           $ bk -A grep -R pattern

       To see if it occurs in the most recent version of of any file  of  your
       tree:

           $ bk -A grep -r+ pattern

       To see if it occurs anywhere in any of your checked out files (this may
       be substantially faster than searching all files because it skips files
       not checked out):

           $ bk -UG grep pattern

       To  see  if it was added by the most recent delta made in of any active
       (undeleted) file of your tree:

           $ bk -U grep -R+ pattern

       See if a pattern was added in the last year (skips deleted files):

           $ bk -U grep -c-1y pattern

       See if a pattern was added between June 1 of 2010 and July 31 of 2010:

           $ bk -U grep -c2010/06..2010/07

       See if a pattern was added between two tagged releases:

           $ bk -U grep -Rbk-4.6..bk-5.0

       See if you left some debugging in the modified files (we  tend  to  add
       fprintf(stderr,  "DEBUG  stuff0) statements but left justify them so we
       can find them):

           $ bk -cU grep '^fprintf'

BUGS
       The ways of specifying which versions to search are  non-obvious.   You
       need  to  read the examples carefully.  We made the default be the most
       useful/common one.

       Binary files are never searched, they are silently ignored.

SEE ALSO
       bk help annotate, bk help bk, bk help cat, bk help get, bk  help  pcre,
       bk help range

CATEGORY
       File

BitKeeper Inc                         1E1                        bk grep(none)
$
help://help
help://help.1
help://bk-help
help://bk-help.1
bk help(none)               BitKeeper User's Manual              bk help(none)

NAME
       bk help - get help for BitKeeper commands

SYNOPSIS
       bk help [-akp] [-f<filename>] <specific-topic>
       bk help topics

DESCRIPTION
       The  bk help command displays the online help for the specified command
       or topic.  Output gets displayed in the current command  shell  window.
       See bk helptool for information about the graphical interface for help.

       A quick reference guide can be found in

           `bk bin`/bk_refcard.pdf

       To get a list of all bk help topics use

           bk help topics

OPTIONS
       -a       Just  search  the  docs  for the string <topic>.  This matches
                substrings and prints the topic followed by the matching line.
       -f<file> Use <file> as the helptext file.
       -k       Similar to "-a", but only matches whole words.
       -p       disable the use of any pager just send the output to stdout.

FUTURE DIRECTIONS
       We will be adding a bk man command to format the man pages on the fly.

SEE ALSO
       bk help helptool

CATEGORY
       Common

BitKeeper Inc                         1E1                        bk help(none)
$
help://helptool
help://helptool.1
help://bk-helptool
help://bk-helptool.1
bk helptool(none)           BitKeeper User's Manual          bk helptool(none)

NAME
       bk helptool - graphical front-end to the BitKeeper help system

SYNOPSIS
       bk helptool [<topic>]

DESCRIPTION
       The  bk  helptool  command  is a graphical interface to the online help
       system.

       There are two text windows displayed, a window of topics  on  the  left
       and  the  help  text  on the right.  There are multiple sections, which
       group related topics together.  A topic is slightly indented, the  sec-
       tion heading is not.

       You  can move around using the mouse, clicking on topics.  You can also
       page through the entire help using "PageDown"  or  "PageUp".   To  move
       from section to section, use the "Left arrow" to move up and the "Right
       arrow" to move forward.  This is fairly useful since the first entry in
       each section tries to give a brief overview of that section.

HYPERLINK STACK
       Helptool  has  a stack of places that you have visited, very similar to
       the hyperlink stack in a web browser.  If you click on a topic you will
       notice that the "Back" button becomes enabled.  Clicking it  will  move
       back  to the previous topic.  Similarly for forward.  The same hot keys
       which work in Netscape are used here for forward and back.

SEARCHING
       Helptool includes a simple search facility.  To search for information,
       you type a word or phrase and hit return (or click on  "Search").   The
       search facility is fairly basic, single word searches tend to work bet-
       ter  than  phrases.   If  a phrase is wanted, it must be put in quotes,
       i.e., "lock file." By  default,  the  search  will  return  approximate
       matches,  i.e.,  searching  on "a" will return anything with the letter
       "a." There is a config option to turn this off.

       The lines which match, if any, are shown slightly indented.  Above  the
       indent lines is the name of the command or help page which contains the
       lines.   You  can  click on that to jump to that page.  Each command or
       page which contains the search phrase will be be highlighted in  orange
       so  that you click through each of the pages which contain the informa-
       tion.

       If you go to a page and it was not what you wanted,  and  you  wish  to
       look at the summary lines again, jump back by clicking "Search" or hit-
       ting  return.   Note that the search results are not part of the hyper-
       link stack of visited pages, but you can get back to the search results
       at any time by hitting Return.

BINDINGS
       The up/down bindings will move through topics, so when they hit the end
       and the key is pressed again, the topic changes to the next  or  previ-
       ous.

       DownArrow     Scroll the help text down one line.
       UpArrow       Scroll the help text up one line.
       LeftArrow     Scroll the help text left one column.
       RightArrow    Scroll the help text right one column.
       PageDown      Scroll the help text down one screen.
       PageUp        Scroll the help text up one screen.
       Home          Scroll to the top of help text.
       End           Scroll to the bottom of the help text.
       Control-Up    Move to the beginning of the previous topic.
       Control-Down  Move to the beginning of the next topic.
       Control-Left  Move to the beginning of the next section (not topic).
       Control-Right Move  to  the  beginning  of  the  previous  section (not
                     topic).
       Alt-Left      Move backwards to the previously visited topic.
       Alt-Right     Move forwards to the to the next topic in the stack.
       Escape        Exit bk helptool.
       Control-b     Scroll the help text up one screen.
       Control-f     Scroll the help text down one screen.
       Control-e     Scroll the help text down one line.
       Control-y     Scroll the help text up one line.
       Control-q     Exit from bk helptool.

SEE ALSO
       bk help config-gui, bk help help

CATEGORY
       GUI-tools

BitKeeper Inc                         1E1                    bk helptool(none)
$
help://here
help://here.1
help://bk-here
help://bk-here.1
help://populate
help://unpopulate
bk here(none)               BitKeeper User's Manual              bk here(none)

NAME
       bk here - list or change the set of populated repositories
       bk populate - add one or more components to a nested collection
       bk unpopulate - remove one or more components to a nested collection

SYNOPSIS
       bk here [set|check] [-@<URL>] [-fq] [<alias | comp>]
       bk populate [-@<URL>] [-fq] <alias | component> ...
       bk unpopulate [-@<URL>] [-fq] <alias | component> ...

   SETTING THE SET OF POPULATED COMPONENTS AND/OR ALIASES
       bk here set [-@<URL>] [-fq] <alias | component> ...

   LISTING POPULATED ALIASES
       bk here [-v]

   POPULATING COMPONENTS AND/OR ALIASES
       bk populate [-@<URL>] [-fq] <alias | component> ...

   CHECKING COMPONENT AVAILABILITY
       bk here check [-@<URL>] [-qv] [<alias | component>] ...

   UNPOPULATING COMPONENTS AND/OR ALIASES
       bk unpopulate [-@<URL>] [-fq] <alias | component> ...

   SETTING THE SET OF POPULATED COMPONENTS AND/OR ALIASES
       bk here set [-@<URL>] [-fq] <alias | component> ...

DESCRIPTION
       The bk here, bk populate, and bk unpopulate commands are used to manage
       the set of populated aliases and/or components in a nested collection.

       The  initial set of populated aliases are determined when a nested col-
       lection is cloned.  If no aliases are specified on  the  clone  command
       line  then  the  set  is  specified via the clone_default configuration
       variable (which is "ALL" if not found).  If one  or  more  aliases  are
       specified, then only the repositories implied by those aliases are pop-
       ulated.

       The bk here command can be used to list what is here, set what is here,
       or  check  what  is  here and list other places where components can be
       found.  The -a option to bk here check prints out all URLs in which the
       component(s) can be found.  If no alias parameters are listed  with  bk
       here check, then only the missing components are checked.

       The  bk  populate  command  can be used to add to what is here.  The bk
       unpopulate command can be used to remove from what is here.

       In order to preserve any local work, before removing any components  bk
       here  needs  to be able to verify everything being removed exists else-
       where.  The bk superset command will be run, which searches  for  local
       changesets,  deltas, modifications, extra files, etc.  See -f below for
       how to skip this check.

       Note that it is not (currently) possible to remove part  of  an  alias.
       If  DEVTOOLS  is  populated  and  it  implies  "cmd/gcc" and "cmd/gdb",
       attempting to remove either component will result  in  an  error.   See
       examples below for how to work around this.

OPTIONS
       -@<URL> When  looking  for  components,  include  <URL>  in the list of
               places to look.
       -a      When used with bk here check, print out all URLs in  which  the
               component(s) can be found.
       -f      When removing repositories, do not check for local only work in
               the  repositories  to be removed.  Using this option when there
               is local only work is dangerous unless you plan to undo all  of
               that work.
       -q      Run quietly.
       -v      When  listing  aliases, show alias expansions using an indented
               list.  Add -v more options to indent to a deeper  level.   When
               checking  aliases, -v will output status of connecting to other
               repositories.

EXAMPLES
       When cloning a product, it is possible to clone a subset of it by spec-
       ifying one or more component names or aliases.  That  will  clone  just
       that subset:

           $ bk clone -sDEVTOOLS bk://server/big-product
           $ cd big-product
           $ bk here
           DEVTOOLS
           PRODUCT

       Note that the list of what is "here" takes two forms, how you specified
       it  (typically  one or more aliases), and the set of components implied
       by those aliases.  To get the second form:

           $ bk comps -h
           ./cmd/gcc
           ./cmd/gas
           ./cmd/ld

       If you need to add something, you just tell bk populate to do that:

           $ bk populate DEBUGGER
           $ bk here
           DEBUGGER
           DEVTOOLS
           PRODUCT

       If you need to remove something, you can only remove  what  you  added,
       not individual components:

           $ bk unpopulate ./cmd/gcc
           unpopulate: ./cmd/gcc is part of the DEVTOOLS alias, not removing.

       If  you absolutely must remove a subset, you can do so by exploding the
       alias in question into components:

           $ bk here | grep -v DEVTOOLS > tmp
           $ bk alias DEVTOOLS >> tmp
           $ bk here set - < tmp
           $ bk unpopulate ./cmd/gcc
           $ bk here
           ./cmd/gas
           ./cmd/ld
           DEBUGGER
           PRODUCT

       If you want to check where missing components can be found:

           $ bk here check
           bin    : no valid urls found (missing)
           cmd/gcc: /repos/bk-trunk

       This shows that the missing bin component has unique work in  it  rela-
       tive  to other searched repositories.  In this case, in order for popu-
       late to work, the user would need to specify -@<URL> to name  where  to
       fetch the bin component.

       If you want to see all places this repository can find the missing com-
       ponents, add -a to the command:

           $ bk here check -a
           bin:
                no valid urls found (missing)
           cmd/gcc:
                /repos/bk-trunk
                bk://repos.bitkeeper.com/bk-trunk

SEE ALSO
       bk help alias, bk help comps

CATEGORY
       Nested

BitKeeper Inc                         1E1                        bk here(none)
$
help://history
help://history.1
help://bk-history
help://bk-history.1
bk history(none)            BitKeeper User's Manual           bk history(none)

NAME
       bk history - guide to viewing changes to files and/or repositories

TEXTUAL HISTORY
       There  are  multiple  tools to view the history of the repository, of a
       file, or of a collection of files such as a directory.  All  tools  are
       described more completely on their own man pages.

       To view the high-level changes to a repository, type:

           $ bk changes

       bk  changes has many options to control which changesets are shown, how
       they are shown, etc.  It is the primary way for finding out  what  hap-
       pened in the repository and reading the changes man page is highly rec-
       ommended.

       The revision history of a file can be accessed by typing:

           $ bk log foo.c

       bk  log has many options. The most commonly used is the -r option which
       is used to select a particular revision of the file.  For  example,  to
       see the most recent check-in for every file in the current directory:

           $ bk log -r+

       The  bk  log command documents the metadata associated with a BitKeeper
       file as well as how to display it.  Reading the  bk  log  man  page  is
       highly recommended.

       The  bk sccslog command is a time ordered view of changes over a set of
       files.  Unlike bk log, bk sccslog sorts all changes  from  all  of  the
       specified  (or  implied) files and then displays each change in chrono-
       logical order.  The following will display the changes which have  hap-
       pened to all the files in the current directory:

           $ bk sccslog

       All  three commands support the same range notation as well as a method
       of controlling the output format known as "dspecs" which are documented
       on the bk log man page.

GRAPHICAL HISTORY
       There are two graphical tools which are primarily used to view  changes
       to files or repositories.  These tools are described more completely on
       their man pages.

       bk  csettool is a graphical changeset viewer which displays the list of
       changes in each changeset, the ChangeSet history, and the file  differ-
       ences  (in a side by side display) for each file in each changeset.  It
       is the graphical version of bk changes.

       bk revtool as a tool which shows the revision history graph of either a
       specified file or of the the ChangeSet file.  Nodes in the graph may be
       selected to view that version of the file.  If two nodes  are  selected
       then the differences between the two versions are shown.

SEE ALSO
       bk  help  changes,  bk help csettool, bk help difftool, bk help log, bk
       help range, bk help revtool, bk help sccslog, bk help set

CATEGORY
       Overview
       Repository

BitKeeper Inc                         1E1                     bk history(none)
$
help://id
help://id.1
help://bk-id
help://bk-id.1
help://identity
bk id(none)                 BitKeeper User's Manual                bk id(none)

NAME
       bk id - display the identity of a package or repository

SYNOPSIS
       bk id [-5rS]

DESCRIPTION
       In  BitKeeper,  each  repository has two identities: a package identity
       and a repository identity.

       The package identity is the same across all repository instances of the
       same package.  Two repositories may synchronize with each other if  and
       only  if they have the same package identity.  bk id displays the pack-
       age identity.

       The repository identity is different in each repository, regardless  of
       the package.  "bk id -r" displays the repository identity.

OPTIONS
       -5 Return package identity as an md5key
       -r displays the repository identity
       -S in  a  nested  collection  return  the identity of the current repo,
          rather than the product.

SEE ALSO
       bk help newroot, bk help terms

CATEGORY
       Repository
       Admin

BitKeeper Inc                         1E1                          bk id(none)
$
help://ignore
help://ignore.1
help://bk-ignore
help://bk-ignore.1
bk ignore(none)             BitKeeper User's Manual            bk ignore(none)

NAME
       bk ignore - ignore shell glob patterns

SYNOPSIS
       bk ignore <glob> [<glob> ...]

DESCRIPTION
       bk  ignore  tells  BitKeeper to ignore specified files when looking for
       extra files that are not under revision control.  This affects the out-
       put of bk gfiles -x and all commands that use its output,  such  as  bk
       citool and bk extras.

       Typical  things  to  ignore are object files, core files, a.out, *.exe,
       and the like.

       Patterns that do not  contain  a  slash  (`/')  character  are  matched
       against  the  basename  of  the  file;  patterns containing a slash are
       matched against the pathname of the file relative to the  root  of  the
       repository.   Using  './'  at  the start of a pattern means the pattern
       applies only to the repository root.

       For example, if you always want to ignore files named  JUNK  regardless
       of which directory they are in, you can say

           bk ignore JUNK

       This matches JUNK and sub/dir/JUNK but not JUNK-PRECIOUS.

       If you want to match a file in just one subdirectory, you can do

           bk ignore sub/directory/this_one

       which matches sub/directory/this_one but not other_dir/this_one.

       If you want to ignore just the JUNK file at the root of the repository,
       you can do

           bk ignore ./JUNK

       which matches JUNK but not sub/dir/JUNK.

       You can also prune certain subdirectories of your repository by append-
       ing  "  -prune"  to  the  directory  path; no BitKeeper operations will
       descend into that directory.

           bk ignore 'sub/dir/build -prune'

       Note: It's important to use the quotes as  shown  when  using  "-prune"
       because  each  command  argument is treated as a separate pattern.  You
       may use "-prune" only with directory paths that  are  relative  to  the
       root of the repository.

       Pruning  large  non-revision  controlled directory trees that appear in
       your repository can significantly improve performance in some cases.

       With no arguments, bk ignore shows the current ignore list.

       The ignore list is stored in the file  BitKeeper/etc/ignore.   You  may
       edit  this  file  if  you wish; the format is simply one glob per line.
       Editing the ignore file is the only way  to  remove  entries  from  the
       list.

       The default ignore list is

           PENDING -prune
           BitKeeper/log -prune
           BitKeeper/tmp -prune
           BitKeeper/writer -prune
           BitKeeper/readers -prune
           BitKeeper/etc/level
           BitKeeper/etc/csets-in
           BitKeeper/etc/csets-out

       The following additions are suggested:

           core
           *.o
           *.swp
           *.a
           *.exe
           *~
           *.rej
           *.orig

ADVANCED USAGE
       You  may  manually  add additional ignore patterns on a per user basis.
       For example, if you have a tendency to have a file called "notes"  that
       you  never  want to check in, and you also use .xxx as your junk files,
       then do this:

           $ echo notes >> "`bk dotbk`/ignore"
           $ echo '*.xxx' >> "`bk dotbk`/ignore"

SEE ALSO
       bk help citool, bk help extras, bk help gfiles, bk help status

CATEGORY
       Admin

BitKeeper Inc                         1E1                      bk ignore(none)
$
help://import
help://import.1
help://bk-import
help://bk-import.1
bk import(none)             BitKeeper User's Manual            bk import(none)

NAME
       bk import - import files or changes into a BitKeeper package

SYNOPSIS
       bk import -tpatch [<options>] <patch> <destination>
       bk import -tplain [<options>] <directory> <destination>
       bk import -tCVS [<options>] <directory> <destination>
       bk import -tMKS [<options>] <directory> <destination>
       bk import -tRCS [<options>] <directory> <destination>
       bk import -tSCCS [<options>] <directory> <destination>

DESCRIPTION
       Use  bk  import  to  put  plain  text files, patches ("diff -Nur"), and
       RCS/CVS files (in this document RCS will mean CVS, MKS and RCS) into  a
       BitKeeper  package.  For file (text, SCCS, RCS, etc) imports, bk import
       does its work outside of your original tree thus leaving  the  original
       files intact while importing them into a BitKeeper package.

       Patch  imports are the only type of import which may be done repeatedly
       in the same destination package.

       See below for information specific types of imports.

OPTIONS
       -C           Do not commit the ChangeSet.
       -f           Force; do not prompt for list editing.
       -F           Fast; run more quickly for  large  imports.   NOTICE:  use
                    this  option only when you know that this is the only Bit-
                    Keeper activity you are doing.  Using this option  on  two
                    parallel imports may cause BitKeeper consistency problems.
       -g<gap>      Change or disable the gap used to cluster changeset group-
                    ing.  A gap of 0 clusters all changes into one big change-
                    set;  a gap of non-zero clusters changes which happen less
                    than that time span apart.  The value is in  minutes  with
                    the default set to 10.
       -H<hostname> Set  the  hostname used for the creation of any new deltas
                    during the import.
       -i           Prompts for a regular expression to apply to the  list  of
                    files.   All matches are included. (For use with all types
                    except patches.)
       -l<file>     Use the list of files in <file>.  (For use with all  types
                    except patches.)
       -q           Be quiet.
       -S<sym>      Add tag <sym> to the changeset created around the import
       -t<type>     Specify import file type.  <type> can be one of:

                    plain Import plain text files
                    patch Import a patch (diffs)
                    RCS   Import RCS files
                    CVS   Import  CVS  files. The only difference from "-tRCS"
                          is that Attic directories are processed and  deleted
                          files  are  detected.   All  RCS options may be used
                          with CVS imports.
                    MKS   Import MKS Source Integrity files.   The  files  are
                          stripped  of  the ext field, moved from rcs directo-
                          ries to RCS directories, a ,v suffix  is  added  and
                          then  the normal RCS processing is applied.  All RCS
                          options may be used with MKS imports.
                    SCCS  Import SCCS files
       -v           Be verbose.
       -x           Prompts for a regular expression to apply to the  list  of
                    files.  All matches are excluded.  (For use with all types
                    except patches.)

RCS OPTIONS
       -h           turn off verification of contents (faster, less safe).
       -T           Do not import tags. The default is to import tags.
       -u           Run  files  through  bk undos first; this will convert DOS
                    style end of lines to Unix style end of lines.

PATCH OPTIONS
       -p<num>      Strip   the   smallest  prefix  containing  <num>  leading
                    slashes from each file name found in the patch file.
       -r           Do not do rename processing when doing patch imports.
       -R           If  a  patch  fails  to apply cleanly, back out the entire
                    operation and exit with a failure.
       -y<comment>  Set the message for the delta comments for  all  files  to
                    <comment> rather than "Import patch PATCHNAME."
       -z<fuzz>     Control  the acceptance of fuzz by bk patch by passing the
                    argument "-F<fuzz>" to bk patch rather  than  the  default
                    "-F0"  , which indicates strict matching.  See the bk help
                    patch man page for further information.

IMPORTING PATCHES
       BitKeeper can be used to  track  external  work  by  importing  patches
       ("diff  -Nur") into a BitKeeper package.  BitKeeper can help with patch
       import problems, namely that renames are  not  tracked  well  and  that
       there generally aren't very good comments if any at all attached to the
       changes  being  made.  A rename in a patch is viewed as the deletion of
       one file and the creation of another file, so to track these, bk import
       will launch bk renametool which is the graphical tool used to  manually
       match the deleted files with the newly created files.

IMPORTING RCS (AND CVS OR MKS) FILES
       The  default  branch  of the RCS tree is the one that will be imported.
       No other branches are imported, branch  imports  are  on  a  consulting
       basis  only.   All  metadata, such as dates, times, user names, checkin
       comments, and symbolic tags are preserved on import.

       This type of import requires RCS 5.6 or later to be  installed  on  the
       importing system.

IMPORTING PLAIN TEXT
       Importing  a  plain text file into a BitKeeper package can only be done
       once.  If there is already a file in the package that has the same name
       as a file to be imported the import will fail.

       If a package is already populated with files use the "-i", "-x" or "-l"
       options to avoid  trying  to  import  files  already  in  the  package.
       Because  of  the  preceding  constraints, import does not catch renames
       with plain text files.  If a file has been renamed, it can be imported,
       but the original file will still exist in the package so it  is  neces-
       sary to remove the original file from the package tree after the import
       of the renamed file.

       Plain text files can be imported from a directory,

           bk import /path/to/src_files ~/package

       from a list of files relative to the source directory,

           bk import -l/tmp/list /path/to/src_files ~/package

       or by using regular expressions in interactive mode

           bk import -ix ~/src_files ~/package
           End patterns with . by itself or EOF
           File name pattern to include>> *.c
           File name pattern to include>> *.h
           File name pattern to include>> Makefile
           File name pattern to include>> .
           End patterns with . by itself or EOF
           File name pattern to exclude>> *.o
           File name pattern to exclude>> .

IMPORTING SCCS FILES
       Teamware and other SCCS files can be imported.  The history of the file
       is  preserved,  but  the unmerged branches are discarded.  This is okay
       because the necessary metadata is in the mainline.

       Importing BitKeeper files is not supported; use bk clone.

ERROR HANDLING
       Import does not handle all errors in a robust  way.   If  unsuccessful,
       import may leave work half done in the destination package.  It is sug-
       gested  that the import destination repository is a clone of the origi-
       nal package in case of a failed import.

SEE ALSO
       bk help log, bk help undos

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk import(none)
$
help://initscripts
help://initscripts.1
help://bk-initscripts
help://bk-initscripts.1
help://Admin/init.d
bk initscripts(none)        BitKeeper User's Manual       bk initscripts(none)

NAME
       bk initscripts - sample script for starting the BitKeeper daemon

EXAMPLES
       #!/bin/sh
       #
       # bitkeeper    Start/stop the bitkeeper daemon.
       #         @(#)bitkeeper.init 1.1 Copyright (c) 2000 Larry McVoy
       #
       # When starting repositories that are bound
       # to a specific port, create a file named
       # /var/bitkeeper/repositories. The repositories
       # file will contain a line for each repository.
       # The line consists of the directory where the
       # repository resides and a set of options used
       # when started the bk daemon.
       #
       # For example:
       #
       # ---- cut here and remove the leading hash mark and spaces -----
       # /home/bk/LMbench -p5000 -xcd -xpush -u99
       # /home/bk/bitcluster -p6000 -xcd -xpush -u99
       # /home/bk/one -p7000 -xcd -xpush -u99
       # --------------------- cut here ----------------------

       # Source networking configuration.
       if [ -f /etc/sysconfig/network ]
       then . /etc/sysconfig/network

            # Check that networking is up.
            [ ${NETWORKING} = "no" ] && exit 0
       fi
       [ -x /usr/bin/bk ] || exit 0
       VAR=/var/bitkeeper

       case "$1" in
           start_msg) echo "Start BitKeeper daemons"
                 ;;
           stop_msg)  echo "Stop BitKeeper daemons"
                 ;;
           restart)   $0 stop
                 $0 start
                 ;;
           start)     cd $VAR || exit 1
                 test -f repositories || {
                      echo Nothing advertised: Are there any entries in the
                      echo $VAR/repositories file?
                      exit 0
                 }
                 while read dir opts
                 do   (
                      cd $dir || exit 1
                      F=`basename $dir`
                      bk bkd $opts -l$VAR/log.$F -P$VAR/pid.$F
                      echo Started bkd $opts in $dir
                      )
                 done < repositories
                 ;;

           stop)
                 cd $VAR || exit 1
                 echo Shutting down BitKeeper daemons
                 for i in pid.*
                 do   kill -TERM `cat $i`
                      rm $i
                 done
                 ;;

           status)    ps -axf | grep bkd
                 ;;

           *)         echo "Usage: bitkeeper {start|stop|restart|status}"
                 exit 1
                 ;;
       esac
       exit 0

CATEGORY
       Overview
       Admin

BitKeeper Inc                         1E1                 bk initscripts(none)
$
help://isascii
help://isascii.1
help://bk-isascii
help://bk-isascii.1
bk isascii(none)            BitKeeper User's Manual           bk isascii(none)

NAME
       bk isascii - check that a file is ascii

SYNOPSIS
       bk isascii <filename>

DESCRIPTION
       bk isascii looks through a file for binary data which BitKeeper can not
       handle without encoding the file.  This consists of a NULL (zero byte).

EXIT STATUS
       bk isascii returns exit status:

       0   if <filename> is ASCII
       1   if <filename> is not ASCII
       2   if an error occurs

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk isascii(none)
$
help://key2path
help://key2path.1
help://bk-key2path
help://bk-key2path.1
bk key2path(none)           BitKeeper User's Manual          bk key2path(none)

NAME
       bk key2path - convert BitKeeper keys to pathnames

SYNOPSIS
       cat keys | bk key2path

DESCRIPTION
       This  utility  takes  one  or  more root keys on the standard input and
       prints the corresponding path of the file named by the key.  If  a  key
       is not found an error message is printed.

SEE ALSO
       bk help key2rev, bk help log

CATEGORY
       Utility

BitKeeper Inc                         1E1                    bk key2path(none)
$
help://key2rev
help://key2rev.1
help://bk-key2rev
help://bk-key2rev.1
bk key2rev(none)            BitKeeper User's Manual           bk key2rev(none)

NAME
       bk key2rev - convert BitKeeper keys to revisions

SYNOPSIS
       cat keys | bk key2rev <file>

DESCRIPTION
       This  utility  takes  one or more keys on the standard input and prints
       the corresponding revision in <file> implied by the key.

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk key2rev(none)
$
help://keywords
help://keywords.1
help://bk-keywords
help://bk-keywords.1
bk keywords(none)           BitKeeper User's Manual          bk keywords(none)

NAME
       bk keywords - list of RCS and SCCS keywords

DESCRIPTION
       BitKeeper  supports both the standard SCCS keywords, as well as most of
       the RCS keywords. In addition, there  are  several  keywords  that  are
       unique to BitKeeper.

       Note:  All  of the revision-oriented keywords (e.g. %I%) are useless in
       BitKeeper since they may change as a  result  of  a  re-synchronization
       that  causes  a  branch creation.  Use the %K% keyword when you need an
       identifier that is unique to a specific revision-level of a  file.  The
       %K% keyword is useful when tracking customer bugs. For example, a tech-
       nician  might ask the end-user to run the what command on an executable
       to check the versions of the components that make up  a  program.   The
       person doing troubleshooting can then use the %K% keyword to track down
       the specific source files that make up the executable.

       Note: SCCS keyword expansion can cause problems in printf-like strings.
       To deal with unwanted keyword expansion, BitKeeper can be given options
       to expand only the first keyword found. See bk help admin.

SCCS KEYWORDS
            %A%  Shorthand notation for an ID line with data for what(1):
                 %Z% %M% %I%%Z% @(#) GET 1.1@(#)
            %B%  SID branch component                    0
            %D%  Current date: yyyy/mm/dd                1991/04/13
            %E%  Date newest applied delta was created:  1991/04/13
            %F%  SCCS s.file name                        SCCS/s.GET
            %G%  Date newest applied delta was created: mm/dd/yyyy 4/13/1991
            %H%  Current date: mm/dd/yyyy                4/13/1991
            %I%  SID of the retrieved version: %R%.%L%.%B%.%S%
                 1.1 or 1.1.0.0 if fully specified as shown in the previous line
            %K%  Key for the delta (these do not change)
                 lm@va.bitkeeper.com|src/bkhelp.txt|19991116191217|50766
            %L%  SID level component                     1
            %M%  Module name: either the value of the m flag in the s.file
                 or the name of the s.file less the prefix
            %P%  Fully-qualified s.file name             /u/lm/SCCS/s.GET
            %R%  SID Release component                   1
            %S%  SID Sequence component                  0
            %T%  Current time: hh:mm:ss                  12:41:29
            %U%  Time the newest applied delta was created: hh:mm:ss    12:41:29
            %W%  Shorthand notation for an ID line with data for what:
                 %Z%%M% %I%     @(#)GET                  1.1
            %Y%  SCCS Compatible, not expanded in BitKeeper
            %Z%  4-character string: recognized by what. @(#)
            %@%  user@host
            %#%  user

RCS KEYWORDS
       The  following  is  the subset of RCS keywords that BitKeeper supports.
       The RCS keywords are only expanded if the RCS flag is turned  on.   See
       bk help admin.

        $Revision$  $Revision: 1.2 $
        $Id$        $Id: s.rcs_expand.c 1.2 99/11/16 11:25:18-08:00 lm@r.com $
        $Author$    $Author: lm@r.com $
        $Date$      $Date: 99/11/16 11:25:18-08:00 $
        $Header$    $Header: SCCS/s.rcs_expand.c 1.2 99/11/16 11:25:18-08:00 lm@r.com $
        $RCSfile$   $RCSfile: s.rcs_expand.c $
        $Source$    $Source: /tmp/beta11/src/SCCS/s.rcs_expand.c $

SEE ALSO
       bk help admin, bk help config-etc, bk help get

CATEGORY
       Overview

BitKeeper Inc                         1E1                    bk keywords(none)
$
help://latest
help://latest.1
help://bk-latest
help://bk-latest.1
bk latest(none)             BitKeeper User's Manual            bk latest(none)

NAME
       bk latest - run command using the latest version of bk

SYNOPSIS
       bk latest <command>

DESCRIPTION
       Run  the  specified <command> using the latest released version of Bit-
       Keeper. The  new  BitKeeper  version  is  downloaded  from  http://bit-
       keeper.com and installed in $HOME/.bk/latest.

CATEGORY
       Utility

BitKeeper Inc                         1E1                      bk latest(none)
$
help://level
help://level.1
help://bk-level
help://bk-level.1
help://workflow
bk level(none)              BitKeeper User's Manual             bk level(none)

NAME
       bk level - set or show the level of the repository

SYNOPSIS
       bk level [-l] [<num>]

DESCRIPTION
       The  bk  level  command  prints or sets the level of the repository.  A
       repository with no level setting defaults to level  1.   The  level  is
       automatically  set when a repository is cloned to the level of the par-
       ent repository.

       With an argument, it sets the level to that argument.   With  no  argu-
       ment, the command prints the repository level.  If an error occurs, the
       level is shown as 1 million (1000000).

       Repository  levels  may  be  used  to  control  the flow of changesets.
       Changes may only flow to a repository of the same or higher level.  The
       typical use for levels is to create a stable or bug-fix repository.  If
       that repository has a lower  level  than  the  development  repository,
       changes may be moved from stable to development, but not the other way.

OPTIONS
       -l     Just list the level on a line by itself.  Useful for scripts.

SEE ALSO
       bk help clone, bk help pull, bk help push

CATEGORY
       Repository

BitKeeper Inc                         1E1                       bk level(none)
$
help://little
help://little.1
help://bk-little
help://bk-little.1
help://L
help://l
bk little(1)                BitKeeper Users Manual                bk little(1)

Name
       Little

Synopsis
       L [options] script.l [args]

Introduction
       bk little, or Little, is a compiled-to-byte-code language that draws
       heavily from C and Perl.  From C, Little gets C syntax, simple types
       (int, float, string), and complex types (arrays, structs).  From Perl,
       Little gets associative arrays and regular expressions (PCRE).  And
       from neither, Little gets its own simplistic form of classes.

       The name "Little", abbreviated as simply "L", alludes to the language's
       simplicity.  The idea was to distill the useful parts of other
       languages and combine them into a scripting language, with type
       checking, classes (not full-blown OO but useful none the less), and
       direct access to a cross-platform graphical toolkit.

       Little provides a set of built-in functions, drawn from Perl and the
       standard C library.

       Little is built on top of the Tcl/TK system.  The Little compiler
       generates Tcl byte codes and uses the Tcl calling convention.  This
       means that L and Tcl code may be intermixed.  More importantly, it
       means that Little may use all of the Tcl API and libraries as well as
       TK widgets.  The net result is a type-checked scripting language which
       may be used for cross-platform GUIs.

       Little is open source under the same license as Tcl/TK (BSD like) with
       any bits that are unencumbered by the Tcl license also being available
       under the Apache License, Version 2.0.

Running Little programs
       You can run a Little program from the command line.

           bk little [options] progname.l [args]

       Alternatively, put this as the first line of your script, but make sure
       your script is executable ("chmod 755 script.l" under Unix).

           #!/path/to/L [options]

       Options:

       --fnhook=myhook
           When function tracing is enabled, use "myhook" as the trace hook.

       --fntrace=on | entry | exit | off
           Enable function tracing on both function entry and exit, entry
           only, exit only, or disable tracing altogether.

       --norun
           Compile only (do not run).  This is useful to check for compilation
           errors.

       --nowarn
           Disable compiler warnings.  This is useful when you know you have
           unused variables or other warnings that you don't want to be
           bothered with.

       --poly
           Treat all types as "poly".  This effectively disables type
           checking.

       --trace-depth=n
           When function tracing is enabled, trace only to a maximum call
           depth of n.

       --trace-files=colon-separated list of glob | /regexpr/
           Enable tracing of all functions in the given files, specified
           either as globs or regular expressions.  A leading + before a glob
           or regexp means to add to what is otherwise being traced and a
           leading - means to remove.  No leading + or - means to trace
           exactly what is specified.

       --trace-funcs=colon-separated list of glob | /regexpr/
           Like --trace-files but specifies functions.

       --trace-out=filename | host:port
           Send default trace output to a file or a TCP socket.

       --version
           Print the L build version and immediately exit.

       The tracing-related command-line options also can be specified in a
       #pragma inside the program; see the DEBUGGING section.

       The optional [args] is a white-space separated list of arguments that
       are passed to the script's main() function as an array of strings
       (argv).

Language syntax
       A Little script or program consists of one or more statements.  These
       may be executable statements, variable or type declarations, function
       or class declarations, or #pragma statements which specify tracing
       directives.  Statements outside of functions are said to be at the "top
       level" and are executed in the order they appear, although you can use
       a "return" statement to bail out.  There is no need to have a "main()"
       function, but if one is present, it is executed after all of the top-
       level statements (even if you did a "return" from the top level).

           puts("This is printed first.");
           void main()
           {
               puts("This is printed last.");
           }
           puts("This is printed second.");

       Little statements end in a semi-colon.

           printf("Hello, world\n");

       Both C style and hash style comments are allowed, but the hash-style
       comments are only for the first line and must start on column 1.

           # This is a comment
               // So is this
           /* And this too */
               # But this is an error, only allowed on column 1, line 1

       Whitespace usually is irrelevant.

           printf(
               "Hello, world\n")
               ;

       ... except inside quoted strings:

           # this would print with a linebreak in the middle
           printf("Hello\
           world\n");

       and around the string-concatenation operator " . " so it can be
       distinguished from the struct-member selection operator ".".

       Double quotes or single quotes may be used around literal strings:

           puts("Hello, world");
           puts('Hello, world');

       However, only double quotes "interpolate" variables and handle
       character escapes such as for newlines ("\n"):

           puts("Hello, ${name}");     // works fine
           puts('Hello, ${name}');     // prints ${name}\n literally

       Inside single quotes, you can still escape a line break, the single
       quote character ("\'"), and the escape character ("\\").

           puts('Here \' and \\ are escaped.');
           puts('This one spans a\
           line');

       If you put a line break in the middle of a string but forget to escape
       it, Little will complain.

       Adjacent string constants are automatically concatenated, like in C.

           printf("This " "prints "
                  "the concatenation "
                  "of ""all"" strings\n");

       prints "This prints the concatenation of all strings" followed by a
       newline.

       Little requires that they be the same "type", all interpolated ("") or
       all not interpolated ('') but the dot operator comes the rescue in this
       contrived example:

           'Hi there. ${USER} is ' . "${USER} today"

Variables, types, and constants
       Little is a statically typed language with both scalar and complex
       types.  All variables are typed and must be declared before use.

       The scalar types are int, float, and string.  The complex types are
       array, hash, struct, and list.  Little also supports function pointers,
       classes, and a special type called "poly" which matches any type and
       normally is used to disable type checking.  Finally, Little has the
       concept of an "undefined" value which a variable of any type can
       possess.

       Strong typing means that you can assign something of one type only to
       something else of a compatible type.  Normally, to be compatible the
       types must be structurally the same, but there are exceptions such as
       an int being compatible with float and a list sometimes being
       compatible with an array or struct.

       Variables begin with a letter and can contains letters, numerals, and
       underscores, but they cannot begin with an underscore (_).  This is
       because the Little compiler reserves names starting with _ for internal
       use.

       A variable declaration includes the type, the variable name, and
       optionally an initial value which can be any Little expression:

           int i = 3*2;

           printf("i = %d\n", i);  // prints i = 6

       If an initial value is omitted, the variable starts out with the
       undefined value "undef".

       Scalars
           A scalar represents a single value that is a string, integer, or
           floating-point number.  Strings are wide char (unicode), integers
           are arbitrarily large, and floats are like C's double.

           Examples:

               string animal = "camel";
               int answer = 42;
               float pi = 3.14159;

           When one of these types is expected, supplying another one usually
           is an error, except that an int always can be used as a float.  You
           can override this behavior with a type cast.

           Integer constants may be specified as follows:

               int space = 0x20;   // hex
               int escape = 0o33;  // octal
               int bits = 0b10101; // binary

           Integer constants can be arbitrarily large; they are not limited by
           the machine's word size.

           Strings have a special feature where they can be indexed like
           arrays, to get a character or range of characters, or to change a
           character (but you cannot change a range of characters):

               string s1, s2;

               s1 = "hello";
               s2 = s1[1];     // s2 gets "e"
               s2 = s1[1..3];  // s2 gets "ell"
               s1[1] = "x";    // changes s1 to "hxllo"
               s1[END+1] = "there";    // changes s1 to "hxllothere"

           The pre-defined identifier "END" is the index of the last
           character, or is -1 if the string is empty.  You always can write
           to one past the end of a string to append to it, but writing beyond
           END+1 is an error.

           You delete a character within a string by indexing the string and
           setting it to "" (the empty string), or by using the "undef()"
           built-in:

               s[3] = "";    // deletes fourth character of s
               undef(s[3]);  // same thing

           After the deletion any characters after the deleted character are
           shifted left by one:

               s = "123X456";
               undef(s[3]);        // s is now "123456"

       Undef
           Sometimes you want to signify that a variable has no legal value,
           such as when returning an error from a function.  Little has a
           read-only pre-defined identifier called "undef" which you can
           assign to any variable.

               int_var = undef;
               array_var = undef;

           This is different than the "undef()" built-in function which
           deletes array, hash, or string elements.

           When used in comparisons, a variable that is undefined is never
           seen as true, or as equal to anything defined, so you can easily
           check for error conditions:

               unless (f = fopen(file, "r")) {
                   die(file);
               }
               while (s = <f>) {
                   printf("%s\n", s);
               }

           You have to be a little careful because any numeric value (and
           poly) can be false in a condition because it can have the value of
           zero:

               int i;

               i = 0;
               if (i)              // false

               i = 1;
               if (i)              // true.

               i = undef;
               if (i)              // false

               i = 0;
               if (defined(i))     // true
               if (i)              // false

           Other than numeric types, you can skip the defined() and just use
           if (var).  That's true for arrays, structs, hashes, and FILE types.

           Little itself sometimes uses undef to tell you that no value is
           available.  One case is when you assign to an array element that is
           more than one past the end of an array.  Little auto-extends the
           array and sets the unassigned elements to undef.

       Arrays
           An array holds a list of values, all of the same type:

               string animals[] = { "camel", "llama", "owl" };
               int numbers[] = { 23, 42, 69 };

           You do not specify a size when declaring an array, because arrays
           grow dynamically.

           Arrays are zero-indexed.  Here's how you get at elements in an
           array:

               puts(animals[0]);              // prints "camel"
               puts(animals[1]);              // prints "llama"

           The pre-defined identifier "END" is the index of the last element
           of an array, or is -1 if the array is empty.

               puts(animals[END]);       // last element, prints "owl"

           END is valid only inside of an array subscript (strings are a kind
           of array so END works there).

           If you need the length of an array, use a built-in function:

               num_elems = length(animals);   // will get 3

           If the array is empty, length() returns 0.

           To get multiple values from an array, you use what's called an
           array "slice" which is a sub-array of the array being sliced.
           Slices are for reading values only; you cannot write to a slice.

               animals[0..1];            // gives { "camel", "llama" }
               animals[1..END];          // gives all except the first element

           In this last example where END is used, you must be careful,
           because if the array is empty, END will be -1, and an array slice
           where the second index is less than the first causes a run-time
           error.

           You can add and remove from an array with "push" and "pop",
           "unshift" and "shift", and "insert".  The "push" and "pop"
           functions add and remove from the end:

               string birds[], next;

               push(&birds, "robin");
               push(&birds, "dove", "cardinal", "bluejay");
               next = pop(&birds);   // next gets "bluejay"
               // birds is now { "robin", "dove", "cardinal" }

           The & means that birds is passed by reference, because it will be
           changed.  This is discussed in more detail in the section on
           functions.

           Another way to append:

               birds[END+1] = "towhee";

           The "unshift" and "shift" functions are similar but they add and
           remove from the beginning of the array.

           You can insert anywhere in an array with "insert":

               insert(&birds, 2, "crow");  // insert crow before birds[2]
               insert(&birds, 3, "hawk", "eagle");

           In these examples we inserted one or more single elements but
           whereever you can put an element you also can splice in a list:

               string new_birds[] = { "chickadee", "turkey" };
               push(&birds, new_birds);  // appends chickadee and turkey

           In this example the variable "new_birds" is not required; an array
           constant could have been pushed instead:

               push(&birds, { "chickadee", "turkey" });

           There is an ambiguity, resolved by the type of the first argument,
           as to whether it is two strings being pushed as two new entries in
           the array, or if it is a single item being pushed.  You have to
           know the type of the first argument to know which is which.

           You can remove from anywhere in an array with "undef":

               string dev_team[] = { "larry", "curly", "mo" };
               undef(dev_team[0]);  // delete "larry" from dev_team

           When you delete an element, all subsequent elements slide down by
           one index.  Note that undef() works only on a variable; it cannot
           remove an element from a function return value, for example.

           You also can directly assign to any array index even if the array
           hasn't yet grown up to that index.  If you assign more than one
           past the current end, the unassigned elements are assigned undef:

               string colors[] = { "blue, "red" };
               colors[3] = "green";   // colors[2] gets undef and
                                      // colors[3] gets "green"

           You can read from any non-negative array index as well.  You will
           simply get undef if the element doesn't exist.  Reading from a
           negative index causes a run-time error.

           An array can hold elements of any type, including other arrays.
           Although Little does not have true multi-dimensional arrays, arrays
           of arrays give you basically the same thing:

               int matrix[][] = {
                   { 1, 2, 3 },
                   { 4, 5, 6 },
                   { 7, 8, 9 }
               };

           When declaring an array, it is legal to put the brackets after the
           type instead of the name.  This sometimes is useful for
           readability, and is required in function prototypes that omit the
           parameter name.

               int[] mysort(int[]);        // prototype
               int[] mysort(int vector[]) { ... }

           An array in Little is implemented as a Tcl list under the covers.

       Hashes
           A hash holds a set of key/value pairs:

               int grades{string} = { "Tom"=>85, "Rose"=>90 };

           When you declare a hash, you specify both the key type (within the
           {}) and the value type.  The keys must be of scalar type but the
           values can be of any type, allowing you to create hashes of arrays
           or other hashes.

           To get at a hash element, you index the hash with the key:

               grades{"Rose"};           // gives 90

           If the given key does not exist in the hash, you get back undef.
           Using an undefined key causes a run-time error.

           You get a list of all the keys in a hash with the "keys()" built-
           in, which returns an array:

               string students[] = keys(grades);

           Because hashes have no particular internal order, the order in
           which the keys ("Tom" and "Rose") appear is undefined.  However,
           you can obtain a sorted array of keys like this:

               string students[] = sort(keys(grades));

           The "length" built-in works on hashes too and returns the number of
           key/value pairs.

           You remove an element from a hash with "undef":

               undef(grades{"Tom"});  // removes "Tom" from the hash

           Note that this is different than assigning undef to a hash element,
           which does not remove that element from the hash, it creates an
           element with the value "undef".  It is not an error to remove
           something that's not in the hash.  Note that undef() works only on
           a variable; it cannot remove an element from a function return
           value, for example.

           When declaring a hash, it is legal to put the braces after the type
           instead of the name.  It comes in handy for function definitons,
           here is is function that is returning an hash of integer grades
           indexed by student name after adjusting them:

               int{string} adjust_grades(int{string});     // prototype
               int{string} adjust_grades(int grades{string}) { ... }

           A hash in Little is implemented as a Tcl dict.

       Structs
           Little structs are much like structs in C.  They contain a fixed
           number of named things of various types:

               struct my_struct {
                   int    i;
                   int    j;
                   string s;
               };
               struct my_struct st = { 1, 2, "hello" };

           You index a struct with the "." operator except when it is a call-
           by-reference parameter and then you must use "->":

               void foo(struct my_struct &byref) {
                   puts(byref->s);  // prints hello
               }
               puts(st.i);    // prints 1
               puts(st.j);    // prints 2
               puts(st.s);    // prints hello
               foo(&st);      // pass st by reference

           It is an error to use "." when "->" is required and vice-versa.  Be
           careful to not put any whitespace around the "." or else you will
           get the string concatenation operator and not struct-member
           selection (this is a questionable overload of the "." operator but
           too useful to pass up).

           Structs can be named like "my_struct" above or they can be
           anonymous:

               struct {
                   int    i;
                   int    j;
               } var1;

           Struct names have their own namespace, so they will never clash
           with function, variable, or type names.

           A struct in Little is implemented as a Tcl list.

       Lists
           In the examples above, we have been initializing arrays, hashes,
           and structs by putting values inside of {}:

               string nums[] = { "one", "two", "three" };

           In Little, the "{}" is an operator that creates a "list" and can be
           used anywhere an expression is valid.  The array could instead be
           initialized like this:

               string nums[];
               nums = { "one", "two", "three" };

           We said before that you can assign a value to something only if it
           has a compatible type.  Lists are special in that they can be
           compatible with arrays, hashes, and structs.  A list where all the
           elements are of the same type, say T, is compatible with an array
           of things of type T.  The example above illustrates this.

           A list also is compatible with a struct if the list elements agree
           in type and number with the struct.  The assignment of the variable
           "st" above illustrates this.

           A list is compatible with a hash if it has a sequence of key/value
           pairs and they are all compatible with the key/value types of the
           hash:

               int myhash{string} = { "one"=>1, "two"=>2, "three"=>3 };

           Lists are very useful at times because you can use them to build up
           larger complex structures.  To concatenate two arrays, you could do
           this:

               { (expand)array1, (expand)array2 };

           The (expand) operator takes an array (or struct or list) and moves
           its elements out a level as if they were between the { and }
           separated by commas.  The section on manipulating complex data
           structures has more details on the (expand) operator.

           A list in Little is implemented as a Tcl list.

       Poly
           Sometimes you don't want Little to do type checking.  In this case,
           you use the "poly" type, which is compatible with any type.  Poly
           effectively disables type checking, allowing you to use or assign
           values without regard to their types.  Obviously, care must be
           taken when using poly.

           The -poly option to Little causes all variables to be treated as if
           they were of type poly, regardless of how they are declared.

       Type Casts
           Something of one type can be converted into something of another
           type with a type cast like in C:

               string_var = (string)13;

           If the thing being cast cannot be converted to the requested type,
           the result of the cast is "undef".

       Typedefs
           You can declare a type name to be a shorthand for another type, as
           you would in C:

               typedef struct {
                   int     x, y;
               } point;

           And then use the shorthand as you would any other type name:

               point points[];
               points[] = { 1,1, 2,2, 3,3 };

           You can typedef a function pointer too.  This declares compar_t as
           type function that takes two ints and returns an int:

               typedef int &compar_t(int a, int b);

           Type names belong to their own namespace, so you can define a
           typedef with the same name as a variable, function, or struct
           without ambiguity (though it is poor practice to do so).

   Name scoping
       Variables must be declared before use, or a compile-time error will
       result.  However, functions need not be declared before use although it
       is good practice to do so.

       Declarations at the top-level code exist at the "global" scope and are
       visible across all scripts executed by a single run of Little.  You can
       qualify a global declaration with "private" to restrict it to the
       current file only; this is similar to a "static" in C, except that
       private globals are not allowed to shadow public globals.  Names
       declared in a function, or in a block within a function, are "local"
       and are scoped to the block in which they are declared.

       Functions and global variables share the same namespace, so a variable
       and function cannot have identical names.  Struct tags have their own
       namespace, and type names have theirs.

       Inside a function, two locals cannot share the same name, even if they
       are in parallel scopes.  This is different than C where this is
       allowed. If a local shares the same name as a global, the local is said
       to "shadow" the global.  Locals cannot shadow globals that have been
       previously declared.

       Names declared inside of a class can be either local or global
       depending on how they are qualified.

String interpolation
       Expressions can be interpolated into double-quoted strings, which means
       that within a string you can write an expression and at run-time its
       value will be inserted.  For example, this interpolates two variables:

           int    a = 12;
           string b = "hello";

           /* This will print "A is 12 and b is hello". */

           printf("A is ${a} and b is ${b}\n");

       Everything inside the ${} is evaluated like any other Little
       expression, so it is not limited to just variables:

           printf("The time is ${`date`}\n");
           s = "The result is ${some_function(a, b, c) / 100}";

Here documents
       Sometimes you need to assign a multi-line string to a variable.  "Here
       documents" help with that:

           string s = <<EOF
           This is the first line in s.
           This is the second.
           And the last.
           EOF;

       Everything in the line starting after the initial <<EOF delimiter and
       before the final EOF delimiter gets put into the variable "s".  You can
       use any identifier you want as the delimiter, it doesn't have to be
       EOF.  A semicolon after the EOF is optional.

       The text inside the here document undergoes interpolation and escape
       processing.  If you don't want that, put the initial delimiter inside
       of single quotes:

           string s = <<'EOF'
           None of this text is interpolated.
           So this ${xyz} appears literally as '${xyz}'.
           And so does \ and ' and " and anything else.
           EOF;

       To help readability, you can indent your here document but have the
       indenting white space ignored.  Put the initial delimiter on the next
       line and then whatever whitespace you put before it gets ignored:

           string s =
               <<EOF
               This is the first line in s and gets no leading white space.
                This line ends up with a single leading space.
                 And this ends up with two.
               EOF;

       Exceptions to the indentation rule: a blank line is processed as if it
       is indented, and the end delimiter can have any amount of leading white
       space so that you can indent it more or less if you like.

Operators
       Arithmetic
               +   addition
               ++  increment by 1 (integer only)
               -   subtraction
               --  decrement by 1 (integer only)
               *   multiplication
               /   division
               %   remainder

       Numeric and String comparison
               ==  equality
               !=  inequality
               <   less than
               >   greater than
               <=  less than or equal
               >=  greater than or equal

       String comparison
               =~  regexp match or substitute
               !~  negated regexp match

       Comparison of composite types (array, hash, struct)
               eq(a,b)

       Bit operations
               &   bit and
               |   bit or
               ^   bit exclusive or
               ~   bit complement
               <<  left shift
               >>  right shift

       Boolean logic
               &&  and
               ||  or
               !   not

       Conditional
               ?:  ternary conditional (as in C)

       Indexing
               []  array index
               {}  hash index
               .   struct index (no whitespace around the dot)
               ->  struct index (call-by-reference parameters dereference)
               ->  class and instance variable access (object dereference)

       Miscellaneous
               =   assignment
               ,   statement sequence
               .   string concatenation (must have whitespace around the dot)
               ``  command expansion

       Assignment
               +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, .=

       Operator precedence (highest to lowest) and associativity
               `` (non associative)
               [] {} . (struct index) -> ++ -- (left)
               unary + unary - ! ~ & (right)
               * / % (left)
               + - . (string concatenation) (left)
               << >> (left)
               < <= > >= (left)
               == != =~ !~ (left)
               & (left)
               ^ (left)
               | (left)
               && (left)
               || (left)
               ?: (right)
               = += -= *= /= %= &= |= ^= <<= >>= .= (right)
               , (left)

Control transfer statements
       Little has most of the usual conditional and looping constructs.

       For conditionals, numeric variables (including poly variables with a
       number in them), evaluate to true or false based on their value.  If
       you want to know if a numeric variable is defined you have to use the
       "defined()" builtin.

       For all other variable types (arrays, hashes, structs, strings, etc),
       the variable itself will yield true or false if it is / is not defined.

           int undefined = undef;
           int zero = 0;
           int one = 1;
           string args[];
           string more[] = { "hi", "there", "mom" };

           if (undefined)          // false (undef)
           if (zero)               // false (0 value)
           if (defined(zero))      // true (not undef)
           if (one)                // true (1 value)
           if (defined(one))       // true (set to some value)
           if (args)               // false, not initialized
           if (more)               // true, initialized

       See the list of operators in the next section for information on
       comparison and logic operators, which are commonly used in conditional
       statements.

       if
         The "if" statement comes in the traditional form:

             if ( condition ) {
                 ...
             } else if ( other condition ) {
                 ...
             } else {
                 ...
             }

         And there's a negated version of it (from Perl) provided as a more
         readable version of "if (!condition)".

             unless ( condition ) {
                 ...
             }

       while
             while ( condition ) {
                 ...
             }

             do {
                 ...
             } while ( condition )

       for
             for (i = 0; i < max; ++i) {
                 ...
             }

       foreach
         The "foreach" statement lets you iterate through the elements of an
         array:

             string element;
             string myarray[];

             foreach (element in myarray) {
                 printf("This element is %s\n", element);
             }

         ... or of a hash:

             string key;
             int value;
             int myhash{string};

             foreach (key=>value in myhash) {
                 printf("Key %s has value %d\n", key, value);
             }

         ... or of a string:

             string char;

             foreach (char in mystring) {
                 printf("This char is %s\n", char);
             }

         ... or through the lines in a string:

             int i = 0;
             string s;
             string lines = "a\nbb\nccc\ndddd\n";

             # (questionable) alias for foreach (s in split(/\n/, lines))
             foreach (s in <lines>) {
                 puts("line #${++i}: ${s}");
             }

         Inside the loop, the index variable(s) ("element", "key", "val", and
         "char" above) get copies of the iterated elements, so if you assign
         to them, the thing you're iterating over does not change.

         If you want to stride through more than one array element, character,
         or line in each iteration, just use a list of value variables instead
         of one:

             foreach (e1,e2,e3 in myarray) {
                 printf("Next three are %s:%s:%s\n", e1, e2, e3);
             }

         If there isn't a multiple of three things to iterate through, the
         stragglers get undef on the last iteration.  Strides work only for
         arrays and strings, not hashes.

         After completing the loop and falling through, all loop counters
         become undefined (they get the "undef" value).  If the loop is
         prematurely ended with a "break" or by jumping out of the loop with a
         "goto", the loop counters keep their values.

       braceless control flow
         Little allows braceless versions of "if, unless, while, for, foreach"
         provided that it is a single statement after the control flow
         keyword.  Note that "else" is not in the list, if then else always
         requires braces.

       switch
         The "switch" statement is like C's except that regular expressions
         and/or strings can be used as case expressions:

             switch (string_var) {
                 case "true":
                 case "false":
                     puts("boolean (sort of)");
                     break;
                 case /[0-9]+/:
                     puts("numeric");
                     break;
                 case /[a-zA-Z][0-9a-zA-Z]*/:
                     puts("alphanumeric");
                     break;
                 default:
                     puts("neither");
                     break;
             }

         The default case is optional.  The expression being switched on must
         be of type integer, string or poly.

         In addition to checking the value of the switch expression, you can
         test whether it is undefined.  This is useful when switching on a
         function return value which could be "undef" to signal an error
         condition.

             switch (myfunc(arg)) {
                 case /OK/:
                     puts("all is A-OK");
                     break;
                 case undef:
                     puts("error");
                     break;
                 default:
                     puts("unknown return value");
                     break;
             }

         Regular expressions have an alternative syntax (borrowed from Perl)
         that is used when the expression may contain "/".  In switch
         statements that syntax is somewhat restricted because of the parsing
         problems you can imagine below:

             switch (str) {
                 case m|x*y|:    // "|" and most other punctuation as the delim
                                 // are OK,
                                 // except "(" and ":" -- error
                                 // and any alphabetic character -- error
                     break;
                 case m:         // is the variable m (not a regexp) -- ok
                     break;
                 case mvar:      // and variables starting with "m" -- ok
                     break;
             }

       break and continue
         Little has "break" and "continue" statements that behave like C's.
         They work in all Little loops including "foreach" loops, and "break"
         works in "switch" case bodies.

       goto
         The "goto" statement unconditionally transfers control to a label in
         the same function, or to a label at the global scope if the goto is
         at the global scope.  You cannot use a goto to transfer in to or out
         of a function.  Labels have their own namespace so they will not
         clash with variable, function, or type names.

             /* A goto at the global scope. */
             goto L1;
             puts("this is not executed");
         L1: puts("but this is");

             void foo()
             {
                 goto L2;
                 puts("this is not executed");
         L2:     puts("but this is");
             }

         Some caveats: do not jump into a foreach loop or a run-time error may
         result due to bypassing the loop set-up.  Do not bypass a variable
         declaration or else the variable will be inaccessible.

Functions
       Little's functions are much like functions in C.  Like variable names,
       function names cannot begin with an underscore (_).

       Each function must be declared with a return type and a formal-
       parameter list:

           int sum(int a, int b)
           {
               return (a + b);
           }

       "void" is a legal return type for a function that returns no value.
       Functions cannot be nested.

       Function prototypes are allowed, where all but the function body is
       declared.  In a prototype, you can omit any parameter names or use
       "void" for an empty parameter list:

           void no_op1(void);
           void no_op2();
           int sum(int, int);

       Unlike Perl, when calling a function you must use parentheses around
       the arguments:

           sum(a, b);

       Little does a special kind of call called a "pattern function" call
       when the function name is capitalized and contains an underscore; these
       are useful for calling Tcl commands and are described later in the
       section "Calling Tcl from Little".  Normal function names therefore
       should not be capitalized and contain an underscore.

       Parameters are passed by value by default.  To pass by reference, you
       use a "&" in the declaration and in the function call:

           void inc(int &arg)
           {
               ++arg;
           }

           inc(&x);  // inc() can change x

       The "&" only tells Little to pass by reference.  It is not a pointer
       (no pointer arithmetic), it is a reference.  You use a reference to
       give the called function the ability to change the caller's variable.

       Only variables can be passed by reference, not elements of arrays,
       hashes, or structs.  This is one significant difference from C.
       Passing an array, hash, or struct element with "&" uses "copy in/out",
       not a true reference.  The element value is copied into a temp variable
       and the temp is passed by reference.  Then when the function returns,
       any changes to the temp are copied back into the array, hash, or struct
       element.  In most cases this behaves like call-by-reference and you
       don't need to worry about it.  But if you access the passed element
       during the function call, by referencing it directly instead of through
       the formal parameter, then you must be careful:

           string array[] = { "one", "two" };
           void fn(string &var, string val)
           {
               var = val;
               array[0] = "this gets overwritten by the copy-out";
           }
           void main()
           {
               fn(&array[0], "new");
               puts(array[0]);  // will print "new"
           }

       Instead of passing a reference, you can pass "undef" like you would a
       NULL pointer in C.  You test for this with the "defined()" operator:

           void inc(int &arg)
           {
               if (defined(&arg)) ++arg;
           }

           inc(undef);   // does nothing
           inc(&x);      // increments x

       In the example above, you might question why it is "defined(&arg)"
       instead of "defined(arg)".  If you think of it in terms of C, the &arg
       is like looking at a pointer, you are seeing if it is non-null, the
       "arg++" is like "*p += 1".

       If you pass "undef" as a reference and then attempt to access the
       parameter, a run-time error results similar to derefencing a NULL
       pointer in C.

       When accessing a struct argument inside a function, if the struct was
       passed by reference, the "->" operator must be used instead of ".".
       This makes it clear to the reader that the struct variable is passed by
       reference; it is intended to allude to a C pointer even though Little
       does not have general-purpose pointers.

   Variable arguments to functions
       Functions can take a variable number of arguments, like printf does.
       In the function declaration, you use the qualifier "..." in front of
       the last formal parameter name and omit its type:

           void dump(...args)
           {
               string s;
               foreach (s in args) puts(s);
           }
           dump("just one");
           dump("but two", "or three", "or more is OK");

       Inside the function, "args" has type array of poly, allowing any number
       of parameters of any type to be passed.

   The main() function
       If main() is present, it is called after all of the top-level
       statements have executed.  The main() function may be defined in any of
       the following ways:

          void|int main(void) {}
          void|int main(string argv[]) {}
          void|int main(int argc, string argv[], string env{string}) {}

       The "argv" array is populated from the script name and any arguments
       that appear after the name on the Little command line.  In this
       example, argc is 4 and argv[] contains "script.l", "arg1", "arg2", and
       "arg3":

          L script.l arg1 arg2 arg3

       The "env" hash is populated with the environment variables present when
       Little is invoked.  Although you can change this hash, writes to it are
       not reflected back into the environment.  To do that use the "putenv"
       library function.

       Only a "main" written in Little is automatically called.  You can write
       a "main" in Tcl but Little will not call it automatically.

       If "main" is declared to have return type "int" then any value returned
       will be the exit value.

   Function pointers
       Function pointers are supported, but only as arguments -- you cannot
       otherwise assign a function pointer to a variable.  It is common to
       first typedef the function-pointer type; here is one for a function
       that compares two strings:

           typedef int &str_compar_t(string a, string b);

       You can then pass such a compare function as follows:

           string    a[];

           bubble_sort(a, &unary_compar);

       Where the sort function looks like this:

           string[] bubble_sort(string a[], str_compar_t &compar)
           {
               do {
                   ...
                   if (compar(a[i], a[i+1] > 0)) { ... }
                   ...
               } ...
           }

       And the compare function looks like this:

           int unary_compar(string a, string b)
           {
               int     al = length(a);
               int     bl = length(b);

               if (al < bl) {
                       return -1;
               } else if (al > bl) {
                       return 1;
               } else {
                       return 0;
               }
           }

Regular expressions
       Little's regular expression support is based on the PCRE (Perl
       Compatible Regular Expressions) library <http://www.pcre.org>.  The
       basics are documented here but for more extensive documentation please
       see <http://www.pcre.org/pcre.txt>.

       Simple matching
               if (s =~ /foo/) { ... }  // true if s contains "foo"
               if (s !~ /foo/) { ... }  // false if s contains "foo"

           The "//" matching operator must be used in conjunction with "=~"
           and "!~" to tell Little what variable to look at.

           If your regular expression contains forward slashes, you must
           escape them with a backslash, or you can use an alternate syntax
           where almost any punctuation becomes the delimiter:

               if (s =~ m|/path/to/foo|) { ... }
               if (s =~ m#/path/to/foo#) { ... }
               if (s =~ m{/path/to/foo}) { ... }

           In the last case, note that the end delimiter } is different than
           the start delimiter { and you must escape all uses of either
           delimiter inside the regular expression.

       Simple substitution
               x =~ s/foo/bar/;         // replaces first foo with bar in x
               x =~ s/foo/bar/g;        // replaces all instances of foo
                                        // with bar in x
               x =~ s/foo/bar/i;        // does a case-insensitive search

           This form also has several alternate syntaxes:

               x =~ s|/bin/root|~root|;
               x =~ s{foo}{bar};
               x =~ s{foo}/bar/;

       More complex regular expressions
               .                   a single character
               \s                  a whitespace character
                                   (space, tab, newline, ...)
               \S                  non-whitespace character
               \d                  a digit (0-9)
               \D                  a non-digit
               \w                  a word character (a-z, A-Z, 0-9, _)
               \W                  a non-word character
               [aeiou]             matches a single character in the given set
               [^aeiou]            matches a single character not in given set
               (foo|bar|baz)       matches any of the alternatives specified

               ^                   start of string
               $                   end of string

           Quantifiers can be used to specify how many of the previous thing
           you want to match on, where "thing" means either a literal
           character, one of the meta characters listed above, or a group of
           characters or meta characters in parentheses.

               *                   zero or more of the previous thing
               +                   one or more of the previous thing
               ?                   zero or one of the previous thing
               {3}                 matches exactly 3 of the previous thing
               {3,6}               matches between 3 and 6 of the previous thing
               {3,}                matches 3 or more of the previous thing

           Some brief examples:

               /^\d+/              string starts with one or more digits
               /^$/                nothing in the string (length == 0)
               /(\d\s){3}/         a three digits, each followed by a whitespace
                                   character (eg "3 4 5 ")
               /(a.)+/             matches a string in which every odd-numbered
                                   letter is "a" (eg "abacadaf")

               // This loop reads from stdin, and prints non-blank lines.
               string buf;
               while (buf = <stdin>) {
                   unless (buf =~ /^$/) puts(buf);
               }

       Unicode
           Both regular expressions and the strings they are matched against
           can contain unicode characters or binary data.  This example looks
           for a null byte in a string:

               if (s =~ /\0/) puts("has a null");

       Parentheses for capturing
           As well as grouping, parentheses serve a second purpose.  They can
           be used to capture the results of parts of the regexp match for
           later use.  The results end up in $1, $2 and so on, and these
           capture variables are available in the substitution part of the
           operator as well as afterward.  You can use up to nine captures ($1
           - $9).

               // Break an e-mail address into parts.
               if (email =~ /([^@]+)@(.+)/) {
                   printf("Username is %s\n", $1);
                   printf("Hostname is %s\n", $2);
               }

               // Use $1,$2 in the substitution to swap two words.
               str =~ s/(\w+) (\w+)/$2 $1/;

           Capturing has a limitation.  If you have more than one regexp with
           captures in an expression, the last one evaluated sets $1, $2, etc.

               // This loses email1's captures.
               if ((email1 =~ /([^@]+)@(.+)/) && (email2 =~ /([^@]+)@(.+)/)) {
                   printf("Username is %s\n", $1);
                   printf("Hostname is %s\n", $2);
               }

           In situations like this, care must be taken because the evaluation
           order of sub-expressions generally is undefined.  But this example
           is an exception because the && operator always evaluates its
           operands in order.

Includes
       Little has an "#include" statement like the one in the C pre-processor.
       A #include can appear anywhere a statement can appear as long as it
       begins in the first column and is contained entirely on one line:

           #include <types.l>
           #include "myglobals.l"
           void main()
           {
               ...
           }

       Unless given an absolute path, when the file name is in angle brackets
       (like <types.l>), Little searches these paths, where BIN is where the
       running tclsh exists:

           $BIN/include
           /usr/local/include/L
           /usr/include/L

       When the file name is in quotes (like "myglobals.l"), Little searches
       only the directory containing the script that did the #include.

       Little also remembers which files have been included and will not
       include a file more than once, allowing you to have #include files that
       include each other.

Classes (experimental)
       Little has an experimental (as in don't count on this to be compatible
       going forward) "class" abstraction for encapsulating data and functions
       that operate on that data.  Little classes are simpler than full-blown
       object-oriented programming (there is no inheritance), but they get you
       most of the way there.

       You declare a class like this:

           class myclass
           {
               ....
           }

       The name "myclass" becomes a global type name, allowing you to declare
       an "object" of "myclass":

           myclass obj;

       You can declare both variables and functions inside the class.  These
       all must be declared inside one class declaration at the global scope.
       You cannot have one class declaration that has some of the declarations
       and another with the rest, and you cannot nest classes inside of
       functions or other classes.

       Inside the class, you can have "class variables" and "instance
       variables".  Class variables are associated with the class and not the
       individual objects that you allocate, so there is only one copy of
       each.  Instance variables get attached to each object.

           class myclass
           {
               /* Class variables. */
               public string pub_var;
               private int num = 0;

               /* Instance variables. */
               instance {
                   public string inst_var;
                   private int n;
               }
               ...
           }

       All declarations (except the constructors and destructors) must be
       qualified with either "public" or "private" to say whether the name is
       visible at the global scope or only inside the class.

       A class can have one or more constructors and destructors but they are
       optional.  Inside a constructor, the variable "self" is automatically
       declared as the object being constructed.  A constructor should return
       "self", although it also could return "undef" to signal an error.  A
       destructor must be declared with "self" as the first parameter.

           constructor myclass_new()
           {
               n = num++;
               return (self);
           }
           destructor myclass_delete(myclass self) {}

       If omitted, Little creates a default constructor or destructor named
       "classname_new" and "classname_delete".  Although not shown in this
       example, you can declare them with any number of parameters, just like
       regular functions.

       A "public" class member function is visible at the global scope, so its
       name must not clash with any other global function or variable.  A
       private member function is local to the class.

       The first parameter to each public function must be "self", the object
       being operated on.  Private functions do not explicitly include "self"
       in the parameter list because it is implicitly passed by the compiler.

           private void bump_num()
           {
               ++n;
           }
           public int myclass_getnum(myclass self)
           {
               bump_num();
               return (n);
           }

       To create an object, you must call a constructor, because just
       declaring the variable does not allocate anything:

           myclass obj;

           obj = myclass_new();

       To operate on an object, you call one of its public member functions,
       passing the object as the first argument:

           int n = myclass_getnum(obj);

       Little allows you to directly access public class and instance
       variables from outside the class.  To get a class variable, you
       dereference the class name (you must use ->):

           string s = myclass->pub_var;

       To get a public instance variable, you dereference the object whose
       data you want to access:

           string s = obj->inst_var;

       Once you free an object

           myclass_delete(obj);

       you must be careful to not use "obj" again unless you assign a new
       object to it, or else a run-time error will result.

Working with Tcl/TK
       Little is built on top of Tcl: Little functions are compiled down to
       Tcl procs, Little local variables are just Tcl variables local to the
       proc, and Little global variables are Tcl globals.  Although Little is
       designed to hide its Tcl underpinnings, sometimes it is useful for
       Little and Tcl to cooperate.

   Mixing Little and Tcl Code
       When you invoke Little with a script whose name ends in ".l", the
       script must contain only Little code.  If you run a ".tcl" script, you
       can mix Little and Tcl:

           puts "This is Tcl code"
           #lang L
           printf("This is Little code\n");
           #lang tcl
           puts "Back to Tcl code"

       You also can run Little code from within Tcl by passing the Little code
       to the Tcl command named "L":

           puts "Tcl code again"
           L { printf("Called from the Little Tcl command.\n"); }

   Calling Tcl from Little
       You call a Tcl proc from Little like you would a Little function:

           string s = "hello world";
           puts(s);

       In this example, "puts" is the Tcl command that outputs its argument to
       the "stdout" channel appending a trailing newline.

       If you want argument type checking, you can provide a prototype for the
       Tcl functions you call.  Otherwise, no type checking is performed.

       In Tcl, options usually are passed as strings like "-option1" or
       "-option2".  Little has a feature to pass these options more
       pleasantly:

           func(option1:);            // passes "-option1"
           func(option2: value, arg); // passes "-option2", value, arg

       Without this, you would have to say:

           func("-option1");
           func("-option2", value, arg);

       A similar feature is for passing sub-commands to Tcl commands:

           String_length("xyzzy");   // like Tcl's [string length xyzzy]
           String_isSpace(s);        // like Tcl's [string is space $s]

       Whenever the function name is capitalized and contains an underscore,
       the sequence of capitalized names after the underscore are converted to
       (lower case) arguments (although capitalizing the first name after the
       underscore is optional).  This is called a "pattern function" call.

           x = Something_firstSecondThird(a, b)

       is like this in Tcl:

           set x [something first second third $a $b]

       A pattern-function call often is used to call a Tcl proc, but you can
       call a Little function just as easily, and Little has a special case
       when the function is named like "Myfunc_*":

           void Myfunc_*(...args)
           {
               poly p;

               printf("Myfunc_%s called with:\n", $1);
               foreach (p in args) printf("%s\n", p);
           }
           void main()
           {
               Myfunc_cmd1(1);
               Myfunc_cmd2(3,4,5);
           }

       If "Myfunc_*" is declared, then any call like "Myfunc_x" becomes a call
       to "Myfunc_*" where the string "x" is put into a special pre-defined
       local variable $cmd inside "Myfunc_*".  The remaining parameters are
       handled normally.  This gives you a way to handle a collection of sub-
       commands without having to declare each as a separate Little function.

       Note: we are going to change this to not conflict with regular
       expressions.

       If you need to execute arbitrary Tcl code rather than just call a proc,
       you pass it to Tcl's "eval" command:

           eval("puts {you guessed it, Tcl code again}");

   Calling Little from Tcl
       Little functions are easily called from Tcl, because a Little function
       "foo" compiles down to a Tcl proc named "foo" in the global namespace.
       Let's say this is run from a script named "script.tcl":

           #lang L
           int avg(...args)
           {
               int i, sum=0;
               unless (length(args)) return (0);
               foreach (i in args) sum += i;
               return (sum/length(args));
           }
           #lang tcl
           set x [avg 4 5 6]
           puts "The average is $x"

       The Little code defines a proc named "avg" which the Tcl code then
       calls.

       An exception is that "private" Little functions are not callable from
       Tcl.

   Variables
       Because Little variables are just Tcl variables, you can access Little
       variables from Tcl code.  Here is an example from the Little library:

           int size(string path)
           {
               int sz;

               if (catch("set sz [file size $path]")) {
                   return (-1);
               } else {
                   return (sz);
               }
           }

       In this Tcl code, $path refers to the Little formal parameter "path",
       and the Little local "sz" is set to the file size.  This example also
       illustrates how you can use Tcl's exception-handling facility to catch
       an exception raised within some Tcl code.

       An exception is that private Little global names are mangled (to make
       them unique per-file).  You can pass the mangled name to Tcl code with
       the "&" operator.  Here we are passing the name of the private function
       "mycallback" to register a Tcl fileevent "readable" handler:

           private void mycallback(FILE f) { ... }

           fileevent(f, "readable", {&mycallback, f});

   Complex variables
       Passing scalar variables works because they have the same
       representation in Little and in Tcl.

       Passing complex variables is trickier and is not supported, but if you
       want to try here is what you need to know.  This is subject to change.
       A Little array is a Tcl list.  A Little struct is a Tcl list with the
       first struct member as the first list element and so on.  A Little hash
       table is a Tcl dict.  If a Little variable is deeply nested, so is the
       Tcl variable.

       So long as you understand that and do the appropriate thing in both
       languages, passing complex variables usually is possible.

   Namespaces
       You can access Tcl procs and variables in namespaces other than the
       global namespace by qualifying the name:

           extern string ::mynamespace::myvar;

           /* Print a bytecode disassembly of the proc "foo". */
           puts(::tcl::unsupported::disassemble("proc", "foo"));

           /* Print a variable in another namespace. */
           puts(::mynamespace::myvar);

   Calling Tk
       To help call Tk widgets, Little has a "widget" type that is used with
       the pattern function calls described above.  A widget value behaves
       like a string except in a pattern function call where it is the name of
       the widget to call:

           widget w = Text_new();
           Text_insert(w, "end", "hi!");   // like Tk's $w insert end hi!

       Another feature is useful for calling Tk widgets that take the name of
       a variable whose value is updated when the user changes a widget field.
       You can use a Little variable like this:

           string msg;
           ttk::label(".foo", textvariable: &msg);

       The ampersand (&) in front of "msg" alludes to a C pointer but it
       really passes just the name of the variable.  Little does this when the
       option name ends in "variable", as "textvariable" does in the example
       above (yes, this is a hack).

   Learning more about Tcl/Tk
       The Little language distribution includes the Tcl and Tk repositories.
       Each of those has a "doc/" subdirectory with files starting with upper
       case and lower case.  Ignore the upper case files ending in .3, those
       are internal C API documentation.  The lower case files are Tcl / Tk
       exposed APIs.  They are all "nroff -man" markup, to view

           $ nroff -man file.n | less

       For books we like these:

           Tcl and the Tk Toolkit 2nd Edition
           Effective Tcl/Tk Programming: Writing Better Programs with Tcl and Tk

Manipulating complex structures
       Little has built-in operators for turning complex data structures into
       something else: (expand), and (tcl).

       (expand) takes an array of things and pushes them all onto the run-time
       stack to call a function that expects such a list.  It is identical to
       Tcl's {*}:

           void foo(string a, string b, string c);

           string v[] = { "one", "two", "three" };

           foo((expand)v);     // passes three string arguments to foo

       It expands only one level, so if the array contains three hashes
       instead of three strings, (expand)v passes three hashes to foo.
       (expand) works with structs too.

       If you have this structure:

           struct {
               int   i[];
               int   h{string};
           } foo = {
               { 0, 1, 2, 3, },
               { "big" => 100, "medium" => 50, "small" => 10 }
           };

       And you use (expand) when passing these as arguments:

           func((expand)foo);

       you need a function definition like this:

           void func(int nums[], int sizes{string})
           {
           }

       There is no way to recursively expand at this time.

       (tcl) is used to pass a single string to a Tcl proc for processing.  It
       puts in the Tcl quotes.  So

           (tcl)foo

       is

           0 1 2 3 { big 100 medium 50 small 10 }

       Another example:

           string v[] = { "a b c", "d", "e" };
           string arg = (tcl)v;     // arg is "{a b c} d e"

       Sometimes you need to assign a group of variables all at once.  You can
       do this by assigning a list of values to a list of variables:

           {a, b, c} = {1, 2, 3};

       This is more than a short-cut for the three individual assignments.
       The entire right-hand side gets evaluated first, then the assignment
       occurs, so you can use this to swap the value of two variables:

           {a, b} = {b, a};

       If you want to ignore one of the elements in the right-hand list, you
       can put "undef" in the corresponding element of left-hand list instead
       of having to use a dummy variable:

           {a, undef, b} = {1, 2, 3};  // a gets 1, b gets 3

       If the right-hand side list isn't as long as the left-hand list, the
       stragglers get "undef":

           {a, b, c} = {1, 2};  // a gets 1, b gets 2, c gets undef

       These composite assignments also work with arrays or structs on the
       right-hand side:

           int dev, inode;
           struct stat st;

           lstat(file, &st);
           {dev, inode} = st;  // pull out first two fields of the stat struct

           {first, second} = split(line);  // get first two words in line

Html with embedded Little
       For building web-based applications, Little has a mode where the input
       can be HTML with embedded Little code (which we call "Lhtml").  This
       works in a way similar to PHP.  To invoke this mode, the input file
       must end in .lhtml:

           L [options] home.lhtml

       All text in home.lhtml is passed through to stdout except that anything
       between <? and ?> is taken to be one or more Little statements that are
       replaced by whatever that Little code outputs, and anything between <?=
       and ?> is taken to be a single Little expression that is replaced by
       its value.  All Little code is compiled at the global scope, so you can
       include Little variable declarations early in the Lhtml document and
       reference them later.

       Here's an example that iterates over an array of key/value pairs and
       formats them into a rudimentary table:

           <? key_value_pair row, rows[]; ?>
           <html>
           <body>
           <p>This is a table of data</p>

           <table>
           <? rows = get_data();
              foreach (row in rows) { ?>
                <tr>
                    <td><?= row.key ?></td>
                    <td><?= row.value ?></td>
                </tr>
           <? } ?>
           </table>

           </body>
           </html>

Pre-defined identifiers
       __FILE__
           A string containing the name of the current source file, or
           "<stdin>" if the script is read from stdin instead of from a file.
           Read only.

       __LINE__
           An int containing the current line number within the script.  Read
           only.

       __FUNC__
           A string containing the name of the enclosing function.  At the top
           level, this will contain a unique name created internally by the
           compiler to uniquely identify the current file's top-level code.
           Read only.

       END An int containing the index of the last character of a non-empty
           string or the last element of a non-empty array.  If the array or
           string is empty, END is -1.  Valid only inside of a string or array
           subscript.  Read only.

       stdio_status
           A struct of type STATUS (see system()) containing status of the
           last system(), `command`, successful waitpid(), or failed spawn().

       undef
           A poly containing the undef value, where defined(undef) is false.
           Assigning this to something makes it undefined.  However, undef is
           not guaranteed to have any particular value, so applications should
           not rely on the value.  Read only.

Reserved words
       The following identifiers are reserved.  They cannot be used for
       variable, function, or type names:

           break
           case
           class
           constructor
           continue
           default
           defined
           destructor
           do
           else
           END
           expand
           extern
           float
           for
           foreach
           goto
           if
           instance
           int
           poly
           private
           public
           return
           string
           struct
           switch
           typedef
           undef
           unless
           void
           while
           widget

Debugging
   Function tracing
       Little function tracing is controlled with #pragma statements,
       _attribute clauses in function declarations, command-line options,
       environment variables, and a run-time API.  When a function is marked
       for tracing, by default its entry and exit are traced to stderr, but
       you can use your own custom hooks to do anything you want.

       A #pragma takes a comma-separated list of attribute assignments:

           #pragma fntrace=on
           string myfunc(int arg)
           {
               return("return value");
           }
           void main()
           {
               myfunc(123);
           }

       When this program runs, traces go to stderr with a millisecond
       timestamp, the function name, parameter values, and return value:

           1: enter main
           1: enter myfunc: '123'
           2: exit myfunc: '123' ret 'return value'
           3: exit main

       The allowable tracing attributes are as follows.

       fntrace=on | entry | exit | off
           Enable tracing on both function entry and exit, entry only, exit
           only, or disable tracing altogether.

       trace_depth=n
           Trace only to a maximum call depth of n.

       fnhook=myhook
           Use myhook as the trace hook (see below).

       A #pragma stays in effect until overridden by another #pragma or by an
       _attribute clause in a function declaration which provides per-function
       tracing control:

           // don't trace this function
           void myfunc2(int arg) _attribute (fntrace=off)
           {
           }

       Tracing also can be controlled with command-line options:

       --fntrace =on | entry | exit | off
           Enable tracing of all functions on both function entry and exit,
           entry only, exit only, or disable all tracing.  This overrides any
           #pragma or _attribute clauses in the program.

       --trace-out=stdin | stderr | filename | host:port
           Send default trace output to stdin, stderr, a file, or a TCP
           socket.

       --trace-files=colon-separated list of glob | /regexp/
           Enable tracing of all functions in the given files, specified
           either as globs or regular expressions.  A + before a glob or
           regexp enables tracing, a - disables, and no + or - is like having
           a +, except that the leading one is special: if omitted, it means
           trace exactly what is specified, overriding any #pragmas or
           _attribute clauses in the code, by first removing all traces and
           then processing the file list.

       --trace-funcs=colon-separated list of glob | /regexp/
           Like trace-files but specifies functions.

       --fnhook=myhook
           Use "myhook" as the trace hook, overriding any #pragmas in the
           program.

       --trace-script=script.l | Little code
           Get the trace hook from a file, or use the given Little code (see
           below).

       Some examples:

           # Trace all functions
           $ L --fntrace=on myscript.l

           # Trace only foo
           $ L --trace-funcs=foo myscript.l

           # Trace foo in addition to what the source marks for tracing
           $ L --trace-funcs=+foo myscript.l

           # Trace all functions except foo
           $ L --trace-funcs=*:-foo myscript.l
           # This does it too
           $ L --fntrace=on --trace-funcs=-foo myscript.l

       Environment variables also can control tracing and take precedence over
       the other ways above:

           L_TRACE_ALL=on | entry | exit | off
           L_TRACE_OUT=stdin | stderr | filename | host:port
           L_TRACE_FILES=colon-separated list of glob | /regexp/
           L_TRACE_FUNCS=colon-separated list of glob | /regexp/
           L_TRACE_DEPTH=n
           L_TRACE_HOOK=myhook
           L_TRACE_SCRIPT=script.l | <Little code>

       Things in L_TRACE_FUNCS are applied after things in L_TRACE_FILES.  As
       with the command-line options, they also can begin with + or - to add
       or subtract from what is specified elsewhere.

       As a short-cut,

           L_TRACE=stdin | stderr | filename | host:port

       traces all functions and sets the trace output location.

       More examples:

           # Trace all files except foo.l
           L_TRACE_FILE=*:-foo.l L myscript.l

           # Trace main() and buggy() in addition to whatever is marked
           # for tracing with #pragmas or _attribute clauses in the code.
           L_TRACE_FUNCS=+main:buggy L myscript.l

           # Trace *only* main() and buggy().
           L_TRACE_FUNCS=main:buggy L myscript.l

       There also is a run-time API that takes a hash of named arguments
       analogous to those above:

           Ltrace({ "fntrace" => "on",
                    "fnhook_out" => "myhook",
                    "trace_depth" => 3,
                    "trace_out" => "tracing.out",
                    "trace_files" => "foo.l",
                    "trace_funcs" => "+main:buggy" });

       To use your own tracing function, specify "fnhook" in any of the above
       ways.  Your hook is called on function entry and exit instead of the
       default hook.  Its prototype must look like this:

           void myhook(int pre, poly argv[], poly ret);

       where pre is 1 when your hook is called upon function entry and 0 when
       called upon exit, argv contains the function's arguments (argv[0] is
       the function name; argv[1] is the first parameter), and ret is the
       return value (exit hook only; it is undef for entry).

       If you use your own hook and then want to go back to the default, set
       "fnhook=def".

       To avoid infinite recursion, during the call of a hook, further calls
       into the hook are disabled.  Also, functions defined as hooks, and the
       Little library functions, are not traced.

       The trace-script attribute is a useful way to provide your own hook:

           L_TRACE_SCRIPT=my-trace-hook.l  // filename must end in .l
           L_TRACE_SCRIPT=<Little code>

       In the latter case, the Little code gets wrapped in a function like
       this:

           void L_fn_hook(int pre, poly av[], poly ret)
           {
               ...code from L_TRACE_SCRIPT...
           }

       and "L_fn_hook" is used as the default trace hook.

       As one example of where this is useful: say you are trying to find
       whether the function "foo" is ever called with the first argument of
       123, and if so, to print all the arguments:

           L_TRACE_FUNCS=foo \
               L_TRACE_SCRIPT='if (av[0]==123) puts(av)' L myscript.l

Built-in and library functions
       Little has built-in functions and a set of library functions modeled
       after the standard C library and Perl.

       string <>
       string <FILE f>
           Get the next line from a FILE handle and return it, or return undef
           for EOF or errors.  Trailing newlines are removed.  If a file
           handle is specified, it is not closed by this function.

           The form without a file handle

               while (buf = <>) {
                   ...
               }

           means

               unless (argv[1]) {
                   while (buf = <stdin>) {
                       ...
                   }
               } else for (i = 1; argv[i]; i++) {
                   unless (f = open(argv[i], "r")) {
                       perror(argv[i]);
                       continue;
                   }
                   while (buf = <f>) {
                       ...
                   }
               }

           although if command-line arguments exist and are parsed with L's
           getopt(), then <> starts looking at argv[] after the last option
           instead of at argv[1].

           A trivial grep implementation:

               void
               main(int ac, string argv[])
               {
                   string  regexp = argv[1];
                   string  buf;

                   unless (regexp) die("usage: grep regexp [files]");
                   undef(argv[1]); // left shift down the args
                   while (buf = <>) {
                       if (buf =~ m|${regexp}|) puts(buf);
                   }
               }

       string `command`
           Execute the command (the string enclosed within back-ticks) and
           substitute its stdout as the value of the expression.  Any output
           to stderr is passed through to the calling application's stderr and
           is not considered an error.  The command is executed using the Tcl
           "exec" command which understands I/O re-direction and pipes, except
           that "command" is split into arguments using Bourne shell style
           quoting instead of Tcl quoting (see "shsplit").  The command string
           is interpolated.  Backslash escapes $, `, and \, \<newline> is
           ignored, but otherwise backslash is literally interpreted.  An
           embedded newline is an error.  If the command cannot be run, undef
           is returned.  The global variable "stdio_status" (see system())
           contains the command's exit status.

       int abs(int val)
       float abs(float val)
           Return the absolute value of the argument.

       void assert(int condition)
           Print an error and exit with status 1 if "condition" is false.  The
           filename, line number, and text of the condition are printed.

       string basename(string path)
           Return the file portion of a path name.

       string caller(int frame)
           Return the name of a calling function, or the caller's caller, etc.
           To get the caller, use a frame of 0, to get the caller's caller,
           use 1, etc.

       int chdir(string dir)
           Change directory to dir.  Return 0 on success, -1 on error.

       int chmod(string path, string permissions)
           Not available on Windows.  Change the mode of the file or directory
           named by path.  Permissions can be the octal code that chmod(1)
           uses, or symbolic attributes that chmod(1) uses of the form
           [ugo]?[[+-=][rwxst],[...]], where multiple symbolic attributes can
           be separated by commas (example: u+s,go-rw add sticky bit for user,
           remove read and write permissions for group and other).  A
           simplified ls-style string, of the form rwxrwxrwx (must be 9
           characters), is also supported (example: rwxr-xr-t is equivalent to
           01755).  Return 0 on success, -1 on error.

       int chown(string owner, string group, string path)
           Not available on Windows.  Change the file ownership of the file or
           directory names by path.  If either owner or group is an empty
           string, the attribute will not be modified.  Return 0 on success,
           -1 on error.

       int cpus()
           Return the number of processors (if known).  Defaults to 1.

       void die(string fmt, ...args)
           Output a printf-like message to stderr and exit 1.  If fmt does not
           end with a newline, append " in <filename> at line <linenum>.\n"

       string dirname(string path)
           Return the directory portion of a pathname.

       int eq(compositeType a, compositeType b)
           Compare two arrays, hashes, structs, or lists for equality.  The
           two arguments are compared recursively element by element.

       int exists(string path)
           Return 1 if the given path exists or 0 if it does not exist.

       int fclose(FILE f)
           Close an open FILE handle.  Return 0 on success, -1 on error.

       FILE fopen(string path, string mode)
           Open a file.  The "mode" string indicates how the file will be
           accessed.

           "r" Open the file for reading only; the file must already exist.
               This is the default value if access is not specified.

           "r+"
               Open the file for both reading and writing; the file must
               already exist.

           "w" Open the file for writing only. Truncate it if it exists. If it
               doesn't exist, create a new file.

           "w+"
               Open the file for reading and writing. Truncate it if it
               exists. If it doesn't exist, create a new file.

           "a" Open the file for writing only. The file must already exist,
               and the file is positioned so that new data is appended to the
               file.

           "a+"
               Open the file for reading and writing. If the file doesn't
               exist, create a new empty file. Set the initial access position
               to the end of the file.

           "v" This mode can be added to any of the above and causes open
               errors to be written to stderr.

           Return a FILE handle on success and undef on error.

       int fprintf(FILE f, string fmt, ...args)
           Format and print a string to the given FILE handle.  The FILE
           handles "stdin", "stdout", and "stderr" are pre-defined.

           Return 0 on success, -1 on error.

       int Fprintf(string filename, string fmt, ...args)
           Like fprintf but write to the given file name.  The file is
           overwritten if it already exists.  Return 0 on success, -1 on
           error.

       string ftype(string path)
           Return the type of file at the given path. Type can be "directory",
           "file", "character", "block", "fifo", "symlink" or "socket".
           Return undef on error.

       string[] getdir(string dir)
       string[] getdir(string dir, string pattern)
           Return the files in the given directory, as a sorted string array.
           Optionally filter the list by "pattern" which is a glob and may
           contain the following special characters:

           ?   Matches any single character.

           *   Matches any sequence of zero or more characters.

           [chars]
               Matches any single character in chars. If chars contains a
               sequence of the form a-b then any character between a and b
               (inclusive) will match.

           \x  Matches the character x.

           {a,b,...}
               Matches any of the strings a, b, etc.

           If the first character in a pattern is ``~'' then it refers to the
           home directory for the user whose name follows the ``~''. If the
           ``~'' is followed immediately by ``/'' then the value of the HOME
           environment variable is used.

       dirent[] getdirx(string dir)
           Return the files in the given directory as an array of structs,
           with the directories sorted and coming first in the array followed
           by the sorted file names.  Return undef on error.  The "dirent"
           struct is defined as follows:

               typedef struct dirent {
                   string  name;
                   string  type;    // "file", "directory", "other"
                   int     hidden;
               } dirent;

       string getenv(string varname)
           Return the value of an environment variable if it exists and is of
           non-zero length, or return undef if it has zero length or does not
           exist.  This allows you to say putenv("VAR=") and have
           getenv("VAR") return undef.

       string getopt(string av[], string opts, string longopts[])
           Parse command-line argument This version (from BitKeeper, same
           semantics) recognizes the following types of short and long options
           in the av array:

               -            leaves it and stops processing options
                            (for indicating stdin)
               --           end of options
               -a
               -abcd
               -r <arg>
               -r<arg>
               -abcr <arg>  same as -a -b -c -r <arg>
               -abcr<arg>   same as -a -b -c -r<arg>
               -r<arg>
               --long
               --long:<arg>
               --long=<arg>
               --long <arg>

           Short options are all specified in a single "opts" string as
           follows:

               d           boolean option          -d
               d:          required arg            -dARG or -d ARG
               d;          required arg no space   -dARG
               d|          optional arg no space   -dARG or -d

           Long options are specified in the "longopts" array (one option per
           element) as follows:

               long        boolean option          --long
               long:       required arg            --long=ARG or --long ARG
               long;       required arg no space   --long=ARG
               long|       optional arg no space   --long=ARG or --long

           The function returns the name of the next recognized option or
           undef if no more options exist.  The global variable "optind" is
           set to the next av[] index to process.  If the option has no arg,
           "optarg" is set to "undef".

           If an unrecognized option is seen, the empty string ("") is
           returned and the global variable "optopt" is set to the name of the
           offending option (unless the option is a long option).

           This example shows a typical usage of both short and long options.

               int     debug_level, verbose;
               string  c, lopts[] = { "verbose" };

               while (c = getopt(av, "d|v", lopts)) {
                   switch (c) {
                       case "d":
                           if (optarg) debug_level = (int)optarg;
                           break;
                       case "v":
                       case "verbose":
                           verbose = 1;
                           break;
                       default:
                           die("unrecognized option ${optopt}");
                   }
               }

       int getpid()
           Return the caller's process id.

       void here()
           Output a message like "myfunc() in script.l:86" to stderr which
           contains the file name, line number, and currently executing
           function name.  Typically used for debugging.

       void insert(type &array[], int index, type elem | type elems[], ...)
           Insert one or more elements into "array" before the element
           specified by "index".  If "index" is 0, the elements are inserted
           at the beginning of the array; this is what "unshift()" does.  If
           "index" is -1 or larger than or equal to the number of elements in
           the array, the elements are inserted at the end; this is what
           "push" does.  You can insert single elements or arrays of elements.

       int isalpha(string s)
           Return 1 if the given string contains only alphabetic characters,
           else return 0.  An empty string also returns 0.

       int isalnum(string s)
           Return 1 if the given string contains only alphabetic or digit
           characters, else return 0.  An empty string also returns 0.

       int isdigit(string s)
           Return 1 if the given string contains only digit characters, else
           return 0.  An empty string also returns 0.

       int isdir(string path)
           Return 1 if the given path exists and is a directory, else return
           0.

       int islink(string path)
           Return 1 if the given path exists and is a link, else return 0.

       int islower(string s)
           Return 1 if the given string contains only lower case alphabetic
           characters, else return 0.  An empty string also returns 0.

       int isreg(string path)
           Return 1 if the given path exists and is a regular file, else
           return 0.

       int isspace(string buf)
           Return 1 if all characters in the argument are space characters,
           else return 0.  An empty string also returns 0.

       int isupper(string s)
           Return 1 if the given string contains only upper-case alphabetic
           characters, else return 0.  An empty string also returns 0.

       int iswordchar(string s)
           Return 1 if the given string contains only alphanumeric or
           connector punctuation characters (such as underscore), else return
           0.  An empty string also returns 0.

       string join(string sep, type array[])
           Convert an array into a string by joining all of its elements by
           inserting sep between each pair.

       keyType[] keys(valType hash{keyType})
           Return an array containing the keys of a given hash.  Note that the
           return type depends on the argument type.

       string lc(string s)
           Return a copy of the string that is in all lower case.

       int length(string s)
           Return the number of characters in the given string.  Returns 0 if
           the argument is "undef".

       int length(type array[])
           Return the number of elements in the given array.  Returns 0 if the
           argument is "undef".

                   for (i = 0; i < length(array); i++)

       int length(valType hash{keyType})
           Return the number of key/value pairs in the given hash.  Returns 0
           if the argument is "undef".

       int link(string sourcePath, string targetPath)
           Create a hard link from sourcePath to targetPath.  Return 0 on
           success, -1 on error.

       int lstat(string path, struct stat &buf)
           Call lstat(2) on "path" and place the information in "buf".  Return
           0 on success, -1 on error.  The "struct stat" type is defined as
           follows:

               struct stat {
                   int     st_dev;
                   int     st_ino;
                   int     st_mode;
                   int     st_nlink;
                   int     st_uid;
                   int     st_gid;
                   int     st_size;
                   int     st_atime;
                   int     st_mtime;
                   int     st_ctime;
                   string  st_type;
               };

           where "st_type" is a string giving the type of file name, which
           will be one of file, directory, characterSpecial, blockSpecial,
           fifo, link, or socket.

       int|float max(int|float, int|float)
       int|float min(int|float, int|float)
           Return the maximum or minimum of two numbers.  The return type is
           float if either of the arguments is a float, otherwise the return
           type is int.

       int milli()
           Return the number of milliseconds since the currently executing
           script started.

       void milli_reset()
           Reset the internal state for milli() to begin counting from 0
           again.

       int mkdir(string path)
           Create a directory at the given path.  This creates all non-
           existing parent directories.  The directories are created with mode
           0775 (rwxrwxr-x).  Return 0 on success, -1 on error.

       int mtime(string path)
           Return the modified time of path, or 0 to indicate error.

       string normalize(string path)
           Return a normalized version of path. The pathname will be an
           absolute path with all "../" and "./" removed.

       int ord(string c)
           Return the numeric value of the encoding (ASCII, Unicode) of the
           first character of "c", or -1 on error or if "c" is the empty
           string.

       int pclose(FILE f)
       int pclose(FILE f, STATUS &s)
           Close an open pipe created by popen().  Return 0 on success, -1 on
           error.  See system() for details of the STATUS struct.

       void perror()
       void perror(string message)
           Print the error message corresponding to the last error from
           various Little library calls.  If "message" is not undef, it is
           prepended to the error string with a ": ".

       type pop(type &array[])
           Remove an element from the end of "array".  Return undef if the
           array is already empty.

       FILE popen(string cmd | argv[], string mode)
       FILE popen(string cmd | argv[], string mode, void
       &stderr_callback(string cmd, FILE f))
           Open a file handle to a process running the command specified in
           "argv[]" or "cmd".  In the "cmd" case, the command is split into
           arguments respecting Bourne shell style quoting.  The returned FILE
           handle may be used to write to the command's input pipe or read
           from its output pipe, depending on the value of "mode".  If write-
           only access is used ("w"), then standard output for the pipeline is
           directed to the current standard output unless overridden by the
           command.  If read-only access is used ("r"), standard input for the
           pipeline is taken from the current standard input unless overridden
           by the command.

           The optional third argument is a callback function that is invoked
           by Tcl's event loop when the command's stderr pipe has data
           available to be read.  The second argument of the callback is a
           non-blocking FILE for the read end of this pipe.  Care must be
           taken to ensure that the event loop is run often enough for the
           callback to reap data from the pipe often enough to avoid deadlock.
           In console apps, this may mean calling Tcl's "update()" function.
           The pclose() function also invokes the callback, so it is
           guaranteed to be called at least once.

           If the third argument to "popen" is "undef", the command's stderr
           output is ignored.  Otherwise, unless re-directed by the command,
           any stderr output is passed through to the calling script's stderr
           and is not considered an error.

           If Tk is being used, there is a default callback that pops up a
           window with any output the command writes to stderr.

           Return the FILE handle on success, or undef on error.

       int printf(string fmt, ...args)
           Format arguments and print to stdout, as in printf(3).  Return 0 on
           success, -1 on error.

       void push(type &array[], type element1 | type elements1[], ...)
           Push one or more elements onto the end of "array".  You can insert
           single elements or arrays of elements.

       string putenv(string var_fmt, ...args)
           Set an environment variable, overwriting any pre-existing value,
           using printf-like arguments:

                   putenv("VAR=val");
                   putenv("MYPID=%d", getpid());

           Return the new value or undef if var_fmt contains no "=".

       int read(FILE f, string &buffer)
       int read(FILE f, string &buffer, int numBytes)
           Read at most numBytes from the given FILE handle into the buffer,
           or read the entire file if numBytes == -1 or is omitted.  Return
           the number of bytes read, -1 on error or EOF.

       int rename(string oldpath, string newpath)
           Rename a file.  Return 0 on success, -1 on error.

       string require(string packageName)
           Find and load the given Tcl package packageName.  Return the
           version string of the package loaded on success, and undef on
           error.

       int rmdir(string dir)
           Delete the given directory.  Return 0 on success, -1 on error.

       type shift(type &array[])
           Remove and return the element at the beginning of "array".  Return
           undef if the array is already empty.

       string[] shsplit(string cmd)
           Split the string the same way as the Bourne shell and return the
           array.

       int size(string path)
           Return the size, in bytes, of the named file path, or -1 on error.

       void sleep(float seconds)
           Sleep for "seconds" seconds.  Note that "seconds" can be fractional
           to get sub-second sleeps.

       type[] sort(type[] array)
       type[] sort([decreasing: | increasing:], type[] array)
       type[] sort([integer: | real: | ascii:], type[] array)
       type[] sort(command: &compar, type[] array)
           Sort the array "array" and return a new array of sorted elements.
           The first variation sorts the elements into ascending order, and
           does an integer, real, or ascii sort based on the type of "array".
           The second two variations show optional arguments that can be
           passed to change this behavior.  The last variation shows how a
           custom compare function can be specified.  The function must take
           two array elements of type T as arguments and return -1 if the
           first comes before the second in the sort order, +1 if the first
           comes after the second, and 0 if the two are equal.

       int spawn(string cmd)
       int spawn(string cmd, STATUS &s)
       int spawn(string argv[])
       int spawn(string argv[], STATUS &s)
       int spawn(cmd | argv[], FILE in, FILE out, FILE err)
       int spawn(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s)
       int spawn(cmd | argv[], string in, FILE out, FILE err)
       int spawn(cmd | argv[], string in, FILE out, FILE err, STATUS &s)
       int spawn(cmd | argv[], string[] in, FILE out, FILE err)
       int spawn(cmd | argv[], string[] in, FILE out, FILE err, STATUS &s)
       int spawn(cmd | argv[], "input", "${outf}", "errors")
       int spawn(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
           Execute a command in background.  All forms return either a process
           id or undef to indicate an error.  In the error case the STATUS
           argument is set, otherwise it remains untouched and the status can
           be reaped by waitpid().

           See the system() function for information about the arguments.

           See the waitpid() function for information about waiting on the
           child.

       string[] split(string s)
       string[] split(/regexp/, string s)
       string[] split(/regexp/, string s, int limit)
           Split a string into substrings.  In the first variation, the string
           is split on whitespace, and any leading or trailing white space
           does not produce a null field in the result.  This is useful when
           you just want to get at the things delimited by the white space:

               split("a b c");    // returns {"a", "b", "c"}
               split(" x y z ");  // returns {"x", "y", "z"}

           In the second variation, the string is split using a regular
           expression as the delimiter:

               split(/,/, "we,are,commas");  // returns {"we", "are", "commas"}
               split(/xxx/, "AxxxBxxxC");    // returns {"A", "B", "C"}
               split(/[;,]/, "1;10,20");     // returns {"1", "10", "20"}

           When a delimiter is used, split returns a null first field if the
           string begins with the delimiter, but if the string ends with the
           delimiter no trailing null field is returned.  This provides
           compatibility with Perl's split:

               split(/xx/, "xxAxxBxxCxx");  // returns {"", "A", "B", "C"}

           You can avoid the leading null fields in the result if you put a
           "t" after the regular expression (to tell it to "trim" the result):

               split(/xx/t, "xxAxxBxxCxx");  // returns {"A", "B", "C"}

           If a "limit" argument is given, at most "limit" substrings are
           returned (limit <= 0 means no limit):

               split(/ /, "a b c d e f", 3);  // returns {"a", "b", "c d e f"}

           To allow splitting on variables or function calls that start with
           "m", the alternate regular expression delimiter syntax is
           restricted:

               split(m|/|, pathname);  // "|" and most other punctuation -- ok
                                       // but ( and ) as delimiters -- error
               split(m);               // splits the variable "m" -- ok
               split(m(arg));          // splits the result of m(arg) -- ok

           Regular expressions, and the strings to split, both can contain
           unicode characters or binary data as well as ASCII:

               split(/\0/, string_with_nulls);  // split on null
               split(/XX/, "XXXX XXXXXXXX XXXXX XX");      // unicode regexp and string

       string sprintf(string fmt, ...args)
           Format arguments and return a formatted string like sprintf(3).
           Return undef on error.

       int stat(string path, struct stat &buf)
           Call stat(2) on "path" and place the information in "buf".  Return
           0 on success, -1 on error.  See the lstat() command for the
           definition of "struct stat".

       int strchr(string s, string c)
           Return the first index of c into s, or -1 if c is not found.

       int strlen(string s)
           Return the string length.

       int strrchr(string s, string c)
           Return the last index of c into s, or -1 if c is not found.

       int symlink(string sourcePath, string targetPath)
           Create a symbolic link from sourcePath to targetPath.  Return 0 on
           success, -1 on failure.

       int system(string cmd)
       int system(string cmd, STATUS &s)
       int system(string argv[])
       int system(string argv[], STATUS &s)
       int system(cmd | argv[], string in, string &out, string &err)
       int system(cmd | argv[], string in, string &out, string &err, STATUS
       &s)
       int system(cmd | argv[], string[] in, string[] &out, string[] &err)
       int system(cmd | argv[], string[] in, string[] &out, string[] &err,
       STATUS &s)
       int system(cmd | argv[], FILE in, FILE out, FILE err);
       int system(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s);
       int system(cmd | argv[], "input", "${outf}", "errors")
       int system(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
           Execute a command and wait for it to finish (see "spawn()" for the
           asynchronous version).

           The command is executed using Tcl's "exec" which understands I/O
           re-direction and pipes, except that "command" is split into
           arguments using Bourne shell style quoting instead of Tcl quoting
           (see "shsplit").

           If the number of arguments is one or two, then the existing stdin,
           stdout, stderr channels are used.

           If the number of arguments is four or five, then the second, third,
           and fourth arguments specify stdin, stdout, stderr, respectively.
           Each can be a string variable or string array (a reference is
           required for stdout and stderr), a FILE variable which must be an
           open file handle, or a string literal which is interpreted as a
           file path name.  If you want to specify a file name from a
           variable, use the string literal "${filename}".  It is an error to
           both re-direct input/output in the command string and to specify
           the corresponding input/output argument; in such a case, the
           command is not run and "undef" is returned.

           If stdout or stderr are sent to strings or string arrays and no
           output is produced, then "out" or "err" are "undef" upon return.

           The optional last argument is a reference to the following
           structure:

               typedef struct {
                   string  argv[]; // args passed in
                   string  path;   // if defined, this is the path to the exe
                                   // if undef, the executable was not found
                   int     exit;   // if defined, the process exited with <exit>
                   int     signal; // if defined, the process was killed
                                   // by <signal>
               } STATUS;

           The global variable "stdio_status" is also set.  If the the command
           is a pipeline and a process in that pipeline fails, the returned
           status is for the first process that failed.

           If there is an error executing the command, or if the process is
           killed by a signal, undef is returned; otherwise, the return value
           is the process exit status (for a pipeline, the status of the first
           process that exited with error).

           Examples:

               // No futzing with input/output, uses stdin/out/err.
               ret = system(cmd);

               // Same thing but no quoting issues, like execve(2).
               ret = system(argv);

               // Get detailed status.
               unless (defined(ret = system(cmd, &status))) {
                   unless (defined(status.path)) {
                           warn("%s not found or bad perm\n", status.path);
                   }
                   if (defined(status.signal)) {
                           warn("%s killed with %d\n",
                               status.argv[0], status.signal);
                   }
               }

               // Taking input and sending output to string arrays.
               // The in_vec elements should not contain newlines and
               // the out/err_vec elements will not contain newlines.
               string in_vec[], out_vec[], err_vec[];
               ret = system(cmd, in_vec, &out_vec, &err_vec);

               // Taking input and sending output to files.
               string outf = sprintf("/tmp/out%d", getpid());
               ret = system(cmd, "/etc/passwd", "${outf}", "/tmp/errors");

               // Using open file handles.
               FILE in = popen("/some/producer/process", "r");
               FILE out = popen("/some/consumer/process", "w");
               FILE err = popen("cat > /dev/tty", "w");
               ret = system(argv, buf, in, out, err, &status);
               // error handling here
               pclose(in, &status);
               // error handling here
               ...

               // Mixing and matching.
               ret = system(argv, buf, &out, "/tmp/errors", &status);

       string trim(string s)
           Return a copy of the string that has been trimmed of any leading
           and trailing whitespace (spaces, tabs, newlines, and carriage
           returns).

       string typeof(<variable>)
           Return the simple type name of the given variable.  This is one of
           "int", "string", "poly", "widget", "array", "hash", or "struct"; or
           if the variable's type is a typedef, the typedef name; or if the
           variable has a class type, the class name; of if the variable is
           really a function name, "function".

       string uc(string s)
           Return a copy of the string that is in all upper case.

       void undef(<array>[index])
       void undef(<string>[index])
       void undef(<hash>{index})
       void undef(<variable>)
           In the first three forms, remove an array, string, or hash element
           from the specified variable.  In the last form, sets the variable
           to undef.  When setting a hash or array to undef, all of its old
           elements are freed (unless they were shared with some other
           variable).

       int unlink(string path)
           Delete the named file.  Return 0 on success, -1 on failure.

       void unshift(type &array[], type element1 | type elements1[], ...)
           Add one or more elements onto the beginning of "array".  You can
           insert single elements or arrays of elements.

       int waitpid(int pid, STATUS &status, int nohang)
           Given a pid returned by spawn(), wait for it, and place the exit
           information in the (optional) STATUS struct.  If "pid" is -1,
           return any process that has exited or return -1 if no more child
           processes exist; otherwise return "pid" or -1 on error.  If
           "nohang" is non-zero, returns -1 if the process does not exist or
           other error, returns 0 if the process exists and has not exited,
           and returns "pid" and updates "status" if the process has exited.

       int wait(STATUS &status)
           Same as "waitpid(-1, &status, 0)".

       void warn(string fmt, ...args)
           Output a printf-like message to stderr.  If fmt does not end with a
           newline, append " in <filename> at line <linenum>.\n"

       int write(FILE f, string buffer, int numBytes)
           Write at most numBytes to the given FILE handle from the buffer.
           Return the number of bytes written, or -1 on error.

Example code
   shapes.l
       This is something we hand to our customers to see what "shape" their
       source trees have.

           #!/usr/bin/bk tclsh
           /*
            * Determine the files/size of each directory under a bk repository.
            * Optionally transform the directory names to obscure their structure.
            *
            * The idea is that you can run this script like this:
            *
            *   bk little shapes.l <path_to_root_of_repo>
            *
            * and get a list of directories with their sizes and number of files in
            * each of them. Save the output, then run it again with -o:
            *
            *   bk little shapes.l -o <path_to_root_of_repo>
            *
            * and send the output to BitMover.
            *
            * The names of all the directories will be rot13'd and sorted (since
            * sort is a destructive transform, it makes it harder to reverse the
            * rot13). This is a weak form of obfuscation, but it lets BitMover
            * work with the directory structure without inadvertently learning
            * about the client's projects.
            *
            * The line numbers at the beginning is so that we can talk about a certain
            * directory by number without BitMover knowing the name of the directory.
            *
            *  ob@dirac.bitmover.com|src/contrib/shapes.l|20100723224240|23777
            *
            */

           string      obscure(string s);      // pathname to no-IP-leak pathname
           string      pp(float n);            // pretty print a number, like df -h
           string      rot13(string str);      // if you don't know, you don't know

           int
           main(int ac, string[] av)
           {
                   int         size, files, maxlen, n;
                   int         do_obscure = 0;
                   string      fn, root, dir, d, ob;
                   FILE        f;
                   struct      stat sb;
                   struct      dirstats {
                       int     files;
                       int     size;
                       int     total_files;
                       int     total_size;
                   } dirs{string};

                   dir = ".";
                   if (ac == 3) {
                           if (av[1] == "-o") {
                                   do_obscure = 1;
                           } else {
                                   fprintf(stderr, "usage: %s [-o] [<dir>]\n", av[0]);
                                   exit(1);
                           }
                           dir = av[2];
                   } else if (ac == 2) {
                           if (av[1] == "-o") {
                                   do_obscure = 1;
                                   dir = ".";
                           } else {
                                   dir = av[1];
                           }
                   } else if (ac > 3) {
                           fprintf(stderr, "usage: %s [-o] [<dir>]\n", av[0]);
                           exit(1);
                   }
                   if (chdir(dir)) {
                           fprintf(stderr, "Could not chdir to %s\n", dir);
                           exit(1);
                   }
                   root = `bk root`;
                   if (root == "") {
                           fprintf(stderr, "Must be run in a BitKeeper repository\n");
                           exit(1);
                   }
                   if (chdir(root)) {
                           fprintf(stderr, "Could not chdir to %s\n", root);
                           exit(1);
                   }

                   size = 0;
                   files = 0;
                   f = popen("bk sfiles", "r");
                   while (defined(fn = <f>)) {
                           dir = dirname(fn);
                           if (dir == "SCCS") {
                                   dir = ".";
                           } else {
                                    // remove SCCS and obscure
                                   dir = dirname(dir);
                           }
                           unless (defined(dirs{dir})) dirs{dir} = {0, 0, 0, 0};
                           if (maxlen < length(dir)) maxlen = length(dir);
                           dirs{dir}.files++;
                           files++;
                           if (lstat(fn, &sb)) {
                                   fprintf(stderr, "Could not stat %s\n", fn);
                                   continue;
                           }
                           dirs{dir}.size += sb.st_size;
                           size += sb.st_size;
                           // add our size/file count to each parent dir
                           for (d = dirname(dir); d != "."; d = dirname(d)) {
                                   unless (defined(dirs{d})) dirs{d} = {0,0,0,0};
                                   dirs{d}.total_size += sb.st_size;
                                   dirs{d}.total_files++;
                           }
                           dirs{"."}.total_size += sb.st_size;
                           dirs{"."}.total_files++;
                   }
                   close(f);
                   // now print it
                   printf("  N   | %-*s | FILES | SIZE    | T_FILES | T_SIZE \n",
                       maxlen, "DIRS");
                   n = 1;
                   foreach (dir in sort(keys(dirs))) {
                           ob = dir;
                           if (do_obscure) {
                                   ob = obscure(dir);
                           }
                           if (dirs{dir}.total_files > 0) {
                                   printf("%5d | %-*s | %5d | %7s | %7s | %7s\n",
                                       n, maxlen,
                                       ob, dirs{dir}.files, pp(dirs{dir}.size),
                                       dirs{dir}.total_files, pp(dirs{dir}.total_size));
                           } else {
                                   printf("%5d | %-*s | %5d | %7s | %7s | %7s\n",
                                       n, maxlen,
                                       ob, dirs{dir}.files, pp(dirs{dir}.size),
                                       "","");
                           }
                           n++;
                   }
                   printf("TOTAL: %u files, %s\n",
                       dirs{"."}.total_files, pp(dirs{"."}.total_size));
                   return (0);
           }

           /* Pretty print a number */
           string
           pp(float n)
           {
                   int         i;
                   float       num = (float)n;
                   string      sizes[] = {"b", "K", "M", "G", "T"};

                   for (i = 0; i < 5; i++) {
                           if (num < 1024.0) return (sprintf("%3.2f%s", num, sizes[i]));
                           num /= 1024.0;
                   }
           }

           /* Table for rot13 function below */
           string rot13_table{string} = {
                   "A" => "N", "B" => "O", "C" => "P", "D" => "Q", "E" => "R", "F" => "S",
                   "G" => "T", "H" => "U", "I" => "V", "J" => "W", "K" => "X", "L" => "Y",
                   "M" => "Z", "N" => "A", "O" => "B", "P" => "C", "Q" => "D", "R" => "E",
                   "S" => "F", "T" => "G", "U" => "H", "V" => "I", "W" => "J", "X" => "K",
                   "Y" => "L", "Z" => "M",     "a" => "n", "b" => "o", "c" => "p", "d" => "q",
                   "e" => "r", "f" => "s", "g" => "t", "h" => "u", "i" => "v", "j" => "w",
                   "k" => "x", "l" => "y", "m" => "z", "n" => "a", "o" => "b", "p" => "c",
                   "q" => "d", "r" => "e", "s" => "f", "t" => "g", "u" => "h", "v" => "i",
                   "w" => "j", "x" => "k", "y" => "l", "z" => "m",
           };

           /* rot13 a string */
           string
           rot13(string str)
           {
                   int         i;
                   string      ret = "";

                   for (i = 0; i < length(str); i++) {
                           ret .= rot13_table{str[i]};
                   }
                   return (ret);
           }

           /*
            * Print an obscured version of the string
            * rot13 + sort
            */
           string
           obscure(string s)
           {
                   string      p;
                   string[]    ret;
                   string[]    sp = split(s, "/");

                   foreach (p in sp) {
                           push(&ret, rot13(join("", lsort(split(p, "")))));
                   }
                   return (join("/", ret));
           }

   photos.l
           #!/usr/bin/bk tclsh
           /*
            * A rewrite of Eric Pop's fine igal program in Little.  I talked to Eric and he
            * really doesn't want anything to do with supporting igal or copycats so
            * while credit here is cool, don't stick his name on the web pages.
            * I completely understand that, people still ask me about webroff and
            * lmbench.
            *
            * First version by Larry McVoy Sun Dec 19 2010.  Public Domain.
            *
            * usage photos [options] [dir]
            *
            * TODO
            * - slideshow mode
            * - move the next/prev/index to the sides along w/ EXIF info
            */
           int bigy = 750;             // --bigy=%d for medium images
           int dates = 0;              // --date-split
           int exif = 0;               // --exif under titles
           int exif_hover = 0;         // --exif-hover, exif data in thumbnail hover
           int exif_thumbs = 0;        // --exif-thumbnails, use the camera thumbnail
           int force = 0;              // -f force regen of everything
           int names = 0;              // put names below the image
           int nav = 0;                // month/year nav
           int parallel = 1;           // -j%d for multiple processes
           int sharpen = 0;            // --sharpen to turn it on
           int thumbnails = 0;         // force regen of those
           int quiet = 1;              // turn off verbose
           string      title = "McVoy photos"; // --title=whatever
           int ysize = 120;            // -ysize=%d for thumbnails
           int rotate[];               // amount to rotate, -+90
           string      indexf = "~/.photos/index.html";
           string      slidef = "~/.photos/slide.html";

           int
           main(int ac, string av[])
           {
                   string      c;
                   string      lopts[] = {
                           "bigy:",
                           "date-split",
                           "exif",
                           "exif-thumbnails",
                           "exif-hover",
                           "force",
                           "index:",
                           "names",
                           "nav",
                           "parallel:",
                           "quiet",
                           "regen",
                           "sharpen",
                           "slide:",
                           "thumbnails",
                           "title:",
                           "ysize:",
                   };

                   if (0) ac = 0;      // lint
                   parallel = cpus();
                   dotfiles();

                   while (c = getopt(av, "fj:", lopts)) {
                           switch (c) {
                               case "bigy": bigy = (int)optarg; break;
                               case "date-split": dates = 1; break;
                               case "exif": exif = 1; break;
                               case "exif-hover": exif_hover = 1; break;
                               case "exif-thumbnails": exif_thumbs = 1; break;
                               case "f":
                               case "force":
                               case "regen":
                                   force = 1; break;
                               case "index": indexf = optarg; break;
                               case "j":
                               case "parallel": parallel = (int)optarg; break;
                               case "quiet": quiet = 1; break;
                               case "names": names = 1; break;
                               case "nav": nav = 1; break;
                               case "sharpen": sharpen = 1; break;
                               case "slide": slidef = optarg; break;
                               case "title": title = optarg; break;
                               case "thumbnails": thumbnails = 1; break;
                               case "ysize": ysize = (int)optarg; break;
                               default:
                               printf("Usage: photos.l");
                               foreach(c in lopts) {
                                   if (c =~ /(.*):/) {
                                       printf(" --%s=<val>", $1);
                                   } else {
                                       printf(" --%s", c);
                                   }
                               }
                               printf("\n");
                               return(0);
                           }
                   }
                   unless (av[optind]) {
                       dir(".");
                   } else {
                       while (av[optind]) dir(av[optind++]);
                   }
                   return (0);
           }

           void
           dir(string d)
           {
                   string      jpegs[];
                   string      tmp[];
                   string      buf;
                   int i;

                   if (chdir(d)) die("can't chdir to %s", d);
                   tmp = getdir(".", "*.jpeg");
                   unless (tmp[0]) tmp = getdir(".", "*.jpg");
                   unless (tmp[0]) tmp = getdir(".", "*.png");
                   unless (tmp[0]) tmp = getdir(".", "*.PNG");
                   unless (tmp[0]) die("No jpegs found in %s", d);
                   // XXX - should getdir do this?
                   for (i = 0; defined(tmp[i]); i++) tmp[i] =~ s|^\./||;

                   /* so we start at one not zero */
                   jpegs[0] = '.';
                   rotate[0] = 0;
                   // XXX - I want push(&jpegs, list)
                   foreach (buf in tmp) {
                           push(&jpegs, buf);
                           push(&rotate, rotation(buf));
                   }

                   slides(jpegs);
                   thumbs(jpegs);
                   html(jpegs);
           }

           /*
            * Create .thumb-$file if
            * - it does not exist
            * - .ysize is different than ysize
            * - $file is newer than thumbnail
            */
           void
           thumbs(string jpegs[])
           {
                   string      cmd[];
                   string      jpeg, file, slide;
                   int i;
                   int all = 0;
                   int my_parallel = parallel, bg = 0;
                   int pid, reaped;
                   int pids{int};

                   unless (exists(".ysize")) {
           save:               Fprintf(".ysize", "%d\n", ysize);
                   }
                   if ((int)`cat .ysize` != ysize) {
                           all = 1;
                           goto save;
                   }
                   if (force || thumbnails) all = 1;
                   if (exif_thumbs) my_parallel = 1;
                   for (i = 1; defined(jpeg = jpegs[i]); i++) {
                           file = sprintf(".thumb-%s", jpeg);
                           slide = sprintf(".slide-%s", jpeg);
                           if (!all && exists(file) && (mtime(file) > mtime(jpeg))) {
                                   continue;
                           }

                           if (exif_thumbs && do_exif(undef, jpeg)) {
                                   unlink(file);
                                   cmd = {
                                       "exif",
                                       "-e",
                                       "-o", file,
                                       jpeg
                                   };
                           } else {
                                   cmd = {
                                       "convert",
                                       "-thumbnail",
                                       "x${ysize}",
                                       "-quality", "85",
                                   };
                                   if (sharpen) {
                                           push(&cmd, "-unsharp");
                                           //push(&cmd, "0x.5");
                                           push(&cmd, "2x0.5+0.7+0");
                                   }
                                   push(&cmd, exists(slide) ? slide : jpeg);
                                   push(&cmd, file);
                           }
                           while (bg >= parallel) {
                                   reaped = 0;
                                   foreach (pid in keys(pids)) {
                                           if (waitpid(pid, undef, 1) > 0) {
                                                   reaped++;
                                                   bg--;
                                                   undef(pids{pid});
                                                   break;
                                           }
                                   }
                                   if (reaped) break;
                                   sleep(0.100);
                           }
                           unless (quiet) {
                                   printf("Creating %s from %s\n",
                                       file, exists(slide) ? slide : jpeg);
                           }
                           pid = spawn(cmd);
                           unless (defined(stdio_status.path)) {
                                   die("%s: command not found.\n", cmd[0]);
                           }
                           bg++;
                           pids{pid} = 1;
                   }
                   foreach (pid in keys(pids)) waitpid(pid, undef, 0);
           }

           /*
            * Create .slide-$file if
            * - it does not exist
            * - .bigy is different than bigy
            * - $file is newer than slide
            * - $file is bigger than bigy
            */
           void
           slides(string jpegs[])
           {
                   string      cmd[];
                   string      jpeg, file;
                   int all = 0;
                   int i;
                   int bg = 0;
                   int pid, reaped;
                   int pids{int};

                   unless (exists(".bigy")) {
           save:               Fprintf(".bigy", "%d\n", bigy);
                   }
                   if ((int)`cat .bigy` != bigy) {
                           all = 1;
                           goto save;
                   }
                   if (force) all = 1;
                   for (i = 1; defined(jpeg = jpegs[i]); i++) {
                           file = sprintf(".slide-%s", jpeg);
                           if (!all && exists(file) && (mtime(file) > mtime(jpeg))) {
                                   continue;
                           }
                           if (small(jpeg)) {
                                   unlink(file);
                                   if (link(jpeg, file)) warn("link ${jpeg} ${file}");
                                   continue;
                           }
                           cmd = {
                               "convert",
                               "+profile", "*",
                               "-scale", "x" . "${bigy}",
                               "-quality", "85",
                           };
                           if (rotate[i]) {
                                   push(&cmd, "-rotate");
                                   push(&cmd, sprintf("%d", rotate[i]));
                           }
                           if (sharpen) {
                                   push(&cmd, "-unsharp");
                                   //push(&cmd, "0x.5");
                                   push(&cmd, "2x0.5+0.7+0");
                           }
                           push(&cmd, jpeg);
                           push(&cmd, file);
                           while (bg >= parallel) {
                                   reaped = 0;
                                   foreach (pid in keys(pids)) {
                                           if (waitpid(pid, undef, 1) > 0) {
                                                   reaped++;
                                                   bg--;
                                                   undef(pids{pid});
                                                   break;
                                           }
                                   }
                                   if (reaped) break;
                                   sleep(0.150);
                           }
                           unless (quiet) {
                                   printf("Creating %s from %s\n", file, jpeg);
                           }
                           printf("%s\n", join(" ", cmd));
                           pid = spawn(cmd);
                           unless (defined(stdio_status.path)) {
                                   die("%s: command not found.\n", cmd[0]);
                           }
                           bg++;
                           pids{pid} = 1;
                   }
                   foreach (pid in keys(pids)) waitpid(pid, undef, 0);
           }

           int
           small(string file)
           {
                   string      buf;

                   // Hack to avoid exif calls on small files
                   if (size(file) < 100000) return (1);
                   if (size(file) > 200000) return (0);
                   unless (buf = `identify '${file}'`) return (0);
                   if (buf =~ /JPEG (\d+)x(\d+)/) return ((int)$2 <= bigy);
                   return (0);
           }

           string num2mon{int} = {
                   1 => "January",
                   2 => "February",
                   3 => "March",
                   4 => "April",
                   5 => "May",
                   6 => "June",
                   7 => "July",
                   8 => "August",
                   9 => "September",
                   10 => "October",
                   11 => "November",
                   12 => "December",
           };

           typedef     struct {
                   int day;    // day 1..31
                   int mon;    // month 1..12
                   int year;   // year as YYYY
                   string      sdate;  // YYYY-MM-DD
           } date;

           /*
            * Return the date either from the filename if it is one of date ones,
            * or from the exif data,
            * or fall back to mtime.
            */
           date
           f2date(string file)
           {
                   date        d;
                   string      buf;
                   FILE        f;
                   int t;

                   if (file =~ /^(\d\d\d\d)-(\d\d)-(\d\d)/) {
           match:
                           buf = (string)$3; buf =~ s/^0//; d.day = (int)buf;
                           buf = (string)$2; buf =~ s/^0//; d.mon = (int)buf;
                           d.year = (int)$1;
                           d.sdate = sprintf("%d-%02d-%02d", d.year, d.mon, d.day);
                           return (d);
                   }

                   if (f = popen("exif -t DateTime '${file}' 2>/dev/null", "r")) {
                           while (buf = <f>) {
                                   // Value: 2006:02:04 22:59:24
                                   if (buf =~ /Value: (\d\d\d\d):(\d\d):(\d\d)/) {
                                           pclose(f);
                                           goto match;
                                   }
                           }
                           pclose(f);
                           // fall through to mtime
                   }

                   if (t = mtime(file)) {
                           buf = Clock_format(t, format: "%Y:%m:%d");
                           buf =~ /(\d\d\d\d):(\d\d):(\d\d)/;
                           goto match;
                   }

                   return (undef);
           }

           /*
            * Create the html slide files and index.html
            * XXX - could stub this out if mtime(html) > mtime(.slide) etc.
            */
           void
           html(string jpegs[])
           {
                   string      template, file, stitle, ntitle, ptitle, buf;
                   string      cap = '';
                   string      date_nav = '';
                   string      dir, jpeg, escaped, thumbs = '';
                   int i, next, prev;
                   int first = 1;
                   FILE        f;
                   string      map[];
                   string      exdata;
                   date        d, d2;

                   unless (f = fopen(slidef, "rv")) die("slide.html");
                   read(f, &template, -1);
                   fclose(f);

                   for (i = 1; defined(jpeg = jpegs[i]); i++) {
                           file = sprintf("%d.html", i);
                           if (i > 1) {
                                   prev = i - 1;
                           } else {
                                   prev = length(jpegs) - 1;
                           }
                           if (jpegs[i+1]) {
                                   next = i + 1;
                           } else {
                                   next = 1;
                           }
                           undef(map);
                           stitle = jpeg;
                           stitle =~ s/\.jp.*//;
                           ntitle = jpegs[next];
                           ntitle =~ s/\.jp.*//;
                           ptitle = jpegs[prev];
                           ptitle =~ s/\.jp.*//;
                           escaped = jpeg;
                           escaped =~ s/:/%3A/g;
                           dir = `pwd`;
                           dir =~ s|.*/||;
                           map = {
                                   "%FOLDER%",
                                   dir,
                                   "%TITLE%",
                                   stitle,
                                   "%NEXT_HTML%",
                                   sprintf("%d.html", next),
                                   "%NEXT_TITLE%",
                                   ntitle,
                                   "%PREV_HTML%",
                                   sprintf("%d.html", prev),
                                   "%PREV_TITLE%",
                                   ptitle,
                                   "%NEXT_SLIDE%",
                                   sprintf(".slide-%s", jpegs[next]),
                                   "%ORIG%",
                                   escaped,
                                   "%SLIDE%",
                                   sprintf(".slide-%s", escaped),
                           };
                           push(&map, "%CAPTION%");
                           if (names || exif) cap = '<P class="center">';
                           if (names) {
                                   cap .= stitle .
                                       '&nbsp;&nbsp;&nbsp;' .
                                       sprintf("(%d/%d)\n", i, length(jpegs) - 1);
                           }
                           undef(exdata);
                           if (exif) {
                                   do_exif(&exdata, jpeg);
                                   if (names) cap .= "<br>";
                                   cap .= exdata;
                           }
                           if (names || exif) cap .= "</P>\n";
                           push(&map, cap);

                           push(&map, "%NAV%");
                           date_nav = '';
                           do_nav(&date_nav, jpeg, prev, next, 1);
                           push(&map, date_nav);

                           buf = String_map(map, template);
                           Fprintf(file, "%s\n", buf);

                           if (dates &&
                               defined(d2 = f2date(jpeg)) &&
                               (first || (d.sdate != d2.sdate))) {
                                   d = d2;
                                   unless (first) thumbs .= "</DIV>\n";
                                   buf = num2mon{d.mon};
                                   thumbs .= "<p><a name=\"${buf}_${d.day}\">";
                                   cap = "${buf} ${d.day} ${d.year}";
                                   thumbs .= cap . "</a>";
                                   cap = ".cap-${buf}-${d.day}-${d.year}";
                                   // .cap-January-09-2011, if exists, is appended
                                   if (exists(cap) && (cap = `cat ${cap}`)) {
                                           thumbs .= ': ' . cap;
                                   }
                                   thumbs .= "<br>\n<DIV class=\"center\">\n";
                           }

                           if (exif && exif_hover) stitle .= " " . exdata;
                           thumbs .= sprintf(
                               '<a href="%s">' .
                               '<img src=".thumb-%s" alt="%s" title="%s" border="0"/>' .
                               '</a>' . "\n",
                               file, escaped, stitle, stitle);
                           first = 0;
                   }

                   /* do index.html */
                   unless (f = fopen(indexf, "rv")) die("index.html");
                   read(f, &template, -1);
                   fclose(f);
                   undef(map);
                   push(&map, "%TITLE%");
                   push(&map, title);
                   push(&map, "%THUMBS%");
                   thumbs .= "</DIV>\n";
                   push(&map, thumbs);
                   date_nav = '';
                   push(&map, "%NAV%");
                   do_nav(&date_nav, jpegs[1], undef, undef, 0);
                   push(&map, date_nav);
                   buf = String_map(map, template);
                   if (exists(".index-include")) {
                           buf .= `cat .index-include`;
                   }
                   Fprintf("index.html", "%s", buf);
                   unless (f = fopen("~/.photos/photos.css", "rv")) die("photos.css");
                   read(f, &buf, -1);
                   fclose(f);
                   Fprintf("photos.css", "%s", buf);
           }

           /*
            * XXX - what this needs is a hash and then at the end I push the info
            * I want in the order I want.
            */
           int
           do_exif(string &cap, string jpeg)
           {
                   FILE        f = popen("exiftags -a '${jpeg}'", "rv");
                   string      save, buf, maker = '';
                   string      v[];
                   string      iso = undef;
                   int thumb = 0;
                   int i;
                   string      tags{string};

                   while (buf = <f>) {
                           switch (trim(buf)) {
                               case /^Equipment Make: (.*)/:
                                   maker = $1;
                                   if (maker == "OLYMPUS IMAGING CORP.") {
                                           maker = "Olympus";
                                   }
                                   if (maker == "NIKON CORPORATION") {
                                           maker = "Nikon";
                                   }
                                   break;
                               case /^Camera Model: (.*)/:
                                   save = $1;
                                   if (save =~ /${maker}/i) {
                                           tags{"camera"} = save;
                                   } else {
                                           tags{"camera"} = "${maker} ${save}";
                                   }
                                   if (save == "TG-1") tags{"lens"} = "25-100mm f2.0";
                                   if (save =~ /Canon PowerShot S95/) {
                                           tags{"lens"} = "28-105 mm";
                                   }
                                   if (save =~ /Canon PowerShot S100/) {
                                           tags{"lens"} = "24-120mm";
                                   }
                                   break;
                               case /Lens Name: (.*)/:
                                   if ($1 =~ /EF\d/) $1 =~ s/EF/EF /;
                                   if ($1 =~ /EF-S\d/) $1 =~ s/EF-S/EF-S /;
                                   if ($1 =~ / USM/) $1 =~ s/ USM//;
                                   if ($1 == "30mm") $1 = "Sigma 30mm f/1.4";
                                   if ($1 == "90mm") $1 = "Tamron 90mm macro";
                                   if ($1 == "18-200mm") $1 = "Tamron 18-200mm";
                                   if ($1 == "18-250mm") $1 = "Tamron 18-250mm";
                                   if ($1 == "18-270mm") $1 = "Tamron 18-270mm";
                                   if ($1 == "170-500mm") $1 = "Sigma 170-500mm";
                                   $1 =~ s|f/|f|;
                                   tags{"lens"} = $1;
                                   break;
                               case /Lens Size: 10.00 - 22.00 mm/:
                                   tags{"lens"} = "EF-S 10-22mm f/3.5-4.5";
                                   break;
                               case /Exposure Bias: (.*)/:
                                   if ($1 != "0 EV") {
                                           unless ($1 =~ /^-/) $1 = "+" . $1;
                                           tags{"bias"} = $1;
                                   }
                                   break;
                               case /^Exposure Time: (.*)/:
                                   save = $1;
                                   $1 =~ /(\d+)\/(\d+) sec/;
                                   if ((int)$1 > 1) {
                                           i = (int)$2/(int)$1;
                                           save = "1/${i}";
                                   }
                                   tags{"time"} = save;
                                   break;
                               case /Lens Aperture: (.*)/:
                               case /F-Number: (.*)/:
                                   $1 =~ s|/||;
                                   tags{"fstop"} = $1;
                                   break;
                               case /ISO Speed Rating: (.*)/:
                                   iso = undef;
                                   if ($1 == "Auto") {
                                           iso = "ISO ${$1}";
                                   } else if ($1 == "Unknown") {
                                           ;
                                   } else unless ((int)$1 == 0) {
                                           iso = "ISO ${$1}";
                                   }
                                   if (defined(iso)) tags{"iso"} = iso;
                                   break;
                               case /Focal Length .35mm Equiv.: (.*)/:
                               case /Focal Length: (.*)/:
                                   save = $1;
                                   if (tags{"camera"} =~ /Canon PowerShot S95/) {
                                           save =~ s/ mm//;
                                           save = (string)(int)((float)save * 4.7);
                                           save .= " mm";
                                   }
                                   if (tags{"camera"} =~ /Canon PowerShot S100/) {
                                           save =~ s/ mm//;
                                           save = (string)(int)((float)save * 4.61538);
                                           save .= " mm";
                                   }
                                   unless (defined(tags{"focal"})) {
                                           tags{"focal"} = save;
                                   }
                                   break;
                               case /Metering Mode: (.*)/:
                                   unless (defined(tags{"metering"})) {
                                           tags{"metering"} = "${$1} metering";
                                   }
                                   break;
                               case /White Balance: (.*)/:
                                   unless ($1 =~ /white balance/) $1 .= " white balance";
                                   $1 =~ s/white balance/WB/;
                                   unless (defined(tags{"balance"})) {
                                           tags{"balance"} = $1;
                                   }
                                   break;
                               case /Compression Scheme: JPEG Compression .Thumbnail./:
                                   thumb = 1;
                                   break;
                           }
                   }
                   fclose(f);
                   cap = "";
                   if (defined(tags{"camera"})) push(&v, tags{"camera"});
                   if (defined(tags{"lens"})) {
                           if (defined(tags{"focal"}) &&
                               (tags{"lens"} =~ /[0-9]-[0-9]/)) {
                                   tags{"lens"} .= " @ " . tags{"focal"};
                           }
                           push(&v, tags{"lens"});
                   }
                   if (defined(tags{"fstop"})) push(&v, tags{"fstop"});
                   if (defined(tags{"time"})) push(&v, tags{"time"});
                   if (defined(tags{"bias"})) push(&v, tags{"bias"});
                   if (defined(tags{"iso"})) push(&v, tags{"iso"});
                   if (defined(tags{"metering"})) push(&v, tags{"metering"});
                   if (defined(tags{"balance"})) push(&v, tags{"balance"});
                   if (defined(v)) cap = join(", ", v);
                   return (thumb);
           }

           int
           rotation(string file)
           {
                   string      r = `exif -m -t Orientation '${file}'`;

                   switch (r) {
                       case /right.*top/i:
                           return (90);
                       case /left.*bottom/i:
                           return (-90);
                       default:
                           return (0);
                   }
           }

           /*
            * This is called for both index nav and slide nav.
            * For index nav, unless nav is set, do nothing.
            * For slide nav, always do at least
            * prev | index | next
            * and optionally
            * prev | next | prev month | index | next month | prev year | next year
            */
           void
           do_nav(string &date_nav, string jpeg, int prev, int next, int slide)
           {
                   int i, mon, did_it;
                   string      buf, month;
                   date        d;

                   date_nav = '';
                   if (!nav && !slide) return;

                   unless (defined(d = f2date(jpeg))) return;
                   month = num2mon{d.mon}[0..2];

                   if (slide) {
                           /* <<< prev | January | next >>> */
                           date_nav .= '<a href="' . sprintf("%d.html", prev) .
                               '">&lt;&lt; prev pic</a>&nbsp;&nbsp;';
                           date_nav .= "\n";
                           unless (nav) {
                                   date_nav .= '<a href="index.html">Index</a>&nbsp;&nbsp;';
                                   date_nav .= "\n";
                           }
                           date_nav .= '<a href="' . sprintf("%d.html", next) .
                               '">next pic &gt;&gt;</a>';
                           date_nav .= "\n";

                           unless (nav) return;
                   }

                   /* <<< prev | next >>> |  <<< January >>> | <<< 2003 >>> */
                   date_nav .= "\n";
                   date_nav .= '&nbsp;&nbsp;&nbsp;&nbsp;';
                   date_nav .= "\n";

                   /* do the <<< for the prev month */
                   for (i = 0; i < 12; i++) {
                           mon = d.mon - i;
                           if (mon == 1) {
                                   buf = sprintf("../../%d/%02d/index.html", d.year-1, 12);
                           } else {
                                   buf = sprintf("../../%d/%02d/index.html", d.year,mon-1);
                           }
                           if (exists(buf)) break;
                   }
                   if (exists(buf)) date_nav .= '<a href="' . buf . '">&lt;&lt;&lt;</a>';
                   date_nav .= "\n";

                   /* do the link to index.html for this month */
                   if (slide) {
                           date_nav .= '&nbsp;&nbsp;<a href="index.html">' .
                               month . " index" . '</a>&nbsp;&nbsp;';
                   } else {
                           date_nav .= "&nbsp;&nbsp;${month}&nbsp;&nbsp;";
                   }
                   date_nav .= "\n";

                   /* do the >>> for next month */
                   for (i = 0; i < 12; i++) {
                           mon = d.mon + i;
                           if (mon == 12) {
                                   buf = sprintf("../../%d/%02d/index.html", d.year+1, 1);
                           } else {
                                   buf = sprintf("../../%d/%02d/index.html", d.year,mon+1);
                           }
                           if (exists(buf)) break;
                   }
                   if (exists(buf)) {
                           date_nav .= '<a href="' . buf . '">&gt;&gt;&gt;</a>';
                   }

                   date_nav .= "\n";
                   date_nav .= '&nbsp;&nbsp;&nbsp;&nbsp;';
                   date_nav .= "\n";

                   did_it = 0;
                   buf = sprintf("../../%d/%02d/index.html", d.year - 1, d.mon);
                   unless (exists(buf)) for (i = 1; i < 12; i++) {
                           buf = sprintf("../../%d/%02d/index.html", d.year - 1, d.mon+i);
                           if (exists(buf)) break;
                           buf = sprintf("../../%d/%02d/index.html", d.year - 1, d.mon-i);
                           if (exists(buf)) break;
                   }
                   if (exists(buf)) {
                           date_nav .= '<a href="' .
                               buf . '">&lt;&lt;&lt;</a>&nbsp;' .  "${d.year}";
                           date_nav .= "\n";
                           did_it++;
                   }
                   buf = sprintf("../../%d/%02d/index.html", d.year + 1, d.mon);
                   unless (exists(buf)) for (i = 1; i < 12; i++) {
                           buf = sprintf("../../%d/%02d/index.html", d.year + 1, d.mon+i);
                           if (exists(buf)) break;
                           buf = sprintf("../../%d/%02d/index.html", d.year + 1, d.mon-i);
                           if (exists(buf)) break;
                   }
                   if (exists(buf)) {
                           unless (did_it) date_nav .= "${d.year}";
                           date_nav .= '&nbsp;<a href="' . buf . '">&gt;&gt;&gt;</a>';
                           date_nav .= "\n";
                   }
           }

           void
           dotfiles(void)
           {
                   string      file, buf;

                   unless (isdir("~/.photos")) mkdir("~/.photos");
                   file = "~/.photos/slide.html";
                   unless (exists(file)) {
                           buf = <<'END'
           <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
           <HTML>
             <HEAD>
               <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
               <TITLE>%TITLE%</TITLE>
               <LINK rel="stylesheet" type="text/css" href="photos.css">
               <LINK rel="contents" href="index.html">
               <LINK rel="next" href="%NEXT_HTML%" title="%NEXT_TITLE%">
               <LINK rel="previous" href="%PREV_HTML%" title="%PREV_TITLE%">
               <SCRIPT type="text/javascript" language="javascript" defer>
                  <!--
                  if (document.images)    {
                     Image1          = new Image();
                     Image1.src      = "%NEXT_SLIDE%";
                  }       //-->
               </SCRIPT>
             </HEAD>

             <BODY>
               <P class="center">
                 %NAV%
               </P>
               <DIV class="center">
                 <TABLE bgcolor="#ffffff" cellspacing=0 cellpadding=4>
                   <TR>
                     <TD class="slide">
                       <A href="%ORIG%">
                       <IMG src="%SLIDE%" alt="%TITLE%"
                       title="Click here to see full size, then use your back button."
                       border=0></a>
                     </TD>
                   </TR>
                 </TABLE>
                 <P>
                 %CAPTION%
               </DIV>
             </BODY>
           </HTML>
           END;
                           Fprintf(file, "%s", buf);
                   }
                   file = "~/.photos/index.html";
                   unless (exists(file)) {
                           buf = <<'END'
           <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

           <HTML>
             <HEAD>
               <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
               <TITLE>%TITLE%</TITLE>
               <LINK rel="stylesheet" type="text/css" href="photos.css">
             </HEAD>

             <BODY>
               %TITLE%
               &nbsp;
               &nbsp;
               &nbsp;
               &nbsp;
               %NAV%
               <p>
               %THUMBS%
               <p align="center">
               %NAV%
               <P class="small">
               For each picture there are 3 sizes:
               (1) the index thumbnails you are looking at,
               (2) a mid sized picture that you get to by clicking the thumbnail,
               (3) the original that you get to by clicking the midsize.
               Legal crud: everything is copyrighted by whoever took the picture.
               In the unlikely event you want to use a picture, please ask just to make
               us feel good.
               </P>
             </BODY>
           </HTML>
           END;
                           Fprintf(file, "%s", buf);
                   }
                   file = "~/.photos/photos.css";
                   unless (exists(file)) {
                           buf = <<'END'
           .center {
             text-align: center;
           }

           .center table {
             margin-left: auto;
             margin-right: auto;
             text-align: center;
           }

           body {
             font-family: verdana, sans-serif;
             background: #000000;
             color: #DDDDDD;
           }

           a:link {
             color: #95DDFF;
             background: transparent;
           }

           a:visited {
             color: #AAAAAA;
             background: transparent;
           }

           a:hover {
             color: #BBDDFF;
             background: #555555;
           }

           .small {
             font-size: 50%;
           }

           .large {
             font-size: 200%;
           }

           .tiled {
             background-image: url(".tile.png");
             background-repeat: repeat-x;
             background-color: #000000;
             padding: 0;
           }

           .thumb {
             background-color: #000000;
             text-align: center;
             vertical-align: middle;
           }

           .slide {
             background-color: #ffffff;
             text-align: center;
             vertical-align: middle;
           }
           END;
                           Fprintf(file, "%s", buf);
                   }
           }

oss                               2025-01-27                      bk little(1)
$
help://lock
help://lock.1
help://bk-lock
help://bk-lock.1
bk lock(none)               BitKeeper User's Manual              bk lock(none)

NAME
       bk lock - lock a repository or show lockers

SYNOPSIS
       bk lock [-l|r|w|L|U] [-q] [<directory>]

DESCRIPTION
       The bk lock command can be used to lock an entire repository or to list
       the  lockers  of a repository.  If a directory is specified, the opera-
       tion applies to the repository rooted at that directory.

       Since a lock is valid only as long as the locking process exists,  when
       placing  lock the bk lock command does not exit, it goes to sleep wait-
       ing for a signal.

OPTIONS
       -l  List the lockers of a repository.
       -q  quiet, exit status only
       -r  Add a read lock (non-exclusive) and sleep until interrupted.
       -w  Add a write lock (exclusive) and sleep until interrupted.
       -L  Wait  for the repository to become locked (primarily used for test-
           ing).
       -U  Wait for the repository to  become  unlocked  (primarily  used  for
           testing).

EXIT STATUS
       If  called  with  no options or if called with the "-l" option, bk lock
       returns exit status:

       0   if the repository has no locks.
       1   if the repository has locks.
       2   if run outside of a repository.

       If called with either "-r" or "-w", bk lock returns exit  status  1  if
       unable to lock the repository.

SEE ALSO
       bk help unlock

CATEGORY
       Repository

BitKeeper Inc                         1E1                        bk lock(none)
$
help://log
help://log.1
help://bk-log
help://bk-log.1
help://dspec
help://prs
help://:I:
help://:P:
help://:AGE:
help://:ALL_TAGS:
help://:ATTACHED_ID:
help://:BAM:
help://:C:
help://:CHANGESET:
help://:COMMENTS:
help://:COMPRESSION:
help://:CSETKEY:
help://:CSETREV:
help://:D:
help://:D_:
help://:DANGLING:
help://:DI:
help://:DIFFS:
help://:DIFFS_U:
help://:DIFFS_UP:
help://:DL:
help://:DM:
help://:DOMAIN:
help://:DP:
help://:DPN:
help://:DS:
help://:DSUM:
help://:DSUMMARY:
help://:DT:
help://:Dd:
help://:Dm:
help://:Dn:
help://:Dt:
help://:Dx:
help://:Dy:
help://:ENC:
help://:EVEN:
help://:F:
help://:FLAGS:
help://:FSUM:
help://:FUDGE:
help://:FULLHOST:
help://:FULLUSER:
help://:G:
help://:GB:
help://:GCA:
help://:GCA2:
help://:GFILE:
help://:GREV:
help://:HASHCOUNT:
help://:HOST:
help://:HTML_AGE:
help://:HTML_C:
help://:ID:
help://:IMPORTER:
help://:KEY:
help://:KID:
help://:KIDS:
help://:L:
help://:LD:
help://:LI:
help://:LREV:
help://:LU:
help://:Ld:
help://:Li:
help://:Lu:
help://:MD5KEY:
help://:MERGE:
help://:MGP:
help://:MODE:
help://:MPARENT:
help://:N:
help://:NEXT:
help://:ODD:
help://:PACKAGE_ID:
help://:PARENT:
help://:PREV:
help://:PRODUCT_ID:
help://:PRS:
help://:R:
help://:RANDOM:
help://:REALHOST:
help://:REALUSER:
help://:RENAME:
help://:REPO_ID:
help://:REPOTYPE:
help://:REV:
help://:RI:
help://:ROOTKEY:
help://:RREV:
help://:RWXMODE:
help://:Rn:
help://:Rx:
help://:S:
help://:SFILE:
help://:SIBLINGS:
help://:SPN:
help://:SYMLINK:
help://:T:
help://:TAGGED:
help://:TAGS:
help://:TIME_T:
help://:TIP:
help://:TZ:
help://:Th:
help://:Tm:
help://:Ts:
help://:USER:
help://:UTC:
help://:UTC-FUDGE:
help://:VERSION:
bk log(none)                BitKeeper User's Manual               bk log(none)

NAME
       bk log - print file revision history and/or metadata

SYNOPSIS
       bk log [-dDfS] [-c<d>] [-C<r>] [-L[<url>]] [-r<r>] [<file> ... | -]

DESCRIPTION
       The  bk log command is used to extract revision history and or metadata
       from a file or set of files.  The default behavior is to print  a  sum-
       mary  of  each  revision  to  each  of  the specified files.  There are
       options to restrict the set of revisions to print, a very commonly used
       one is -r+, which restricts the set to the most recent revision.

       With no options bk log output defaults to  giving  information  on  all
       revisions  of  all  files  in the present directory that are under Bit-
       Keeper control.  Output is given as follows: the name of the  file  and
       range  of revisions is followed by a detailed account of each revision.
       Revision number, revision date and time, user who made  that  revision,
       what  the  relative  path  from root of repository is to that file, the
       comments that go with that revision, and documents if the file has been
       renamed.

OPTIONS
       -<n>             A numeric argument that limits the  number  of  deltas
                        printed per file.
       --begin=<script> The  dspec v2 language (see that section below and the
                        examples) is awk like and has optional begin/end  sec-
                        tions.   This option allows you to specify the body of
                        a begin section (if the file also has a begin  section
                        then  both  are run; order is undefined).  It is typi-
                        cally used with an on disk dspec in a dspec file  that
                        has  been  written in a way to do one thing by default
                        and another if a variable is set to non-zero.
       -c<date>         Cut-off dates.  See range specifications (below) or bk
                        help range for details.
       -C<rev>          Make the range be all revs that are the same  cset  as
                        <rev>.
       -d<spec>         Override the default output format (see below).
       --dspecf=<file>  Like -d but read the dspec from a file.
       -D               Do not skip files in the BitKeeper/deleted directory.
       -f               Print the changes in forward (oldest to newest) order.
                        The default is backward.
       -L[<url>]        Show  all deltas unique to this repository relative to
                        the (outgoing) parent or <url> if one  was  specified.
                        May not be combined with -c or -r.
       --lattice        Restrict  the  deltas  to those on the lattice between
                        the two range endpoints.  Unlike a  range,  the  lower
                        bound is included in the output.
       --longest        Restrict  the  deltas  to  those  on  the longest line
                        between the two range endpoints.  Unlike a range,  the
                        lower bound is included in the output.
       -n               Add a newline to each printed record.
       -r<rev>          Specify  a  revision,  or part of a range.  (Or key or
                        changeset revision. See bk help terms under "rev argu-
                        ment.")
       -S
       --standalone     Use with -L in a nested component when  you  want  the
                        component to act like a standalone repository.

   RANGE SPECIFICATIONS
       -r+             prints the most recent delta
       -r1.3..1.6      prints all deltas that are in 1.6's history but are not
                       in 1.3's history.
       -c2006/07..2006 prints all deltas from July 1 2006 to Dec 31 2006
       -c2006..2006    prints all deltas from Jan 1 2006 to Dec 31 2006
       -c-1d..         prints  all deltas made in the last 24 hours; similarly
                       for s, m, h, d, M, and Y  for  seconds,minutes,  hours,
                       days, months, and years.

DEFAULT OUTPUT FORMAT
       The  bk changes, and bk log commands have a default output format which
       may be modified on a per user or per  repository  basis.   The  default
       formats are named as follows:

       dspec-changes     Specifies  the  format  for  bk  changes  [-v] output
                         (without -vv).
       dspec-changes-vv  Specifies the format for bk changes -vv output  (ver-
                         bose with diffs).
       dspec-log         Specifies the format for bk log output.

       There   are  other  dspec-*  files,  if  you  want  some  fun  look  at
       dspec-*-json, if you understand those you understand that dspecs are  a
       little   programming   language.    The   shipped  files  live  in  `bk
       bin`/dspec-*

       These files can live in multiple places, this is the search  order  for
       "dspec-changes", the first one found is used:
              <repo>/BitKeeper/etc/dspec-changes
              <product>/BitKeeper/etc/dspec-changes (BitKeeper/Nested only)
              `bk dotbk`/dspec-changes
              /etc/BitKeeper/etc/dspec-changes
              `bk bin`/dspec-changes

MODIFYING THE OUTPUT FORMAT
       There  are many different pieces of information in a BitKeeper file and
       virtually all of them can be extracted using a non-default output  for-
       mat.

       To  extract specific information, a "dspec" (data specification) string
       is provided and where there are keywords surrounded by colons the  key-
       words  are  expanded much like printf(3).  This can lead to many useful
       one liners; want to see which file is the most busy in a repository?

           bk -U log -r+ -nd':DS: :GFILE' | sort -nr | head

       If you are familiar with awk(1) the processing  here  is  similar.   In
       awk,  each  line  is  a  record, here each delta is a record.  For each
       delta, you can provide a dspec which says what it is you want to  print
       from  that  delta.   Looking  at  the dspec-* files in the installation
       directory is recommended, there are  $begin/$end  sections  that  mimic
       awk.

       The  dspecs  can  contain the following set of escaped characters which
       will be replaced with the specified string:

       \b     Backspace
       \f     Form feed
       \n     Newline
       \r     Carriage return
       \t     Tab
       \123   3 digit octal value (pad with leading zeros)
       \<c>   c for any other character "c"

       In almost all cases, a trailing newline is not provided by any  of  the
       keywords  and  one  should  be  provided as needed.  The newline can be
       added in line or you can specify the -n option which will add a newline
       after each delta is processed.

       Multi-line keywords are normally printed as is, but you can format each
       line separately using a $each() loop (see ITERATIVE OUTPUT below).

   CONDITIONAL OUTPUT
       The dspec can produce output conditionally.  The following  prints  the
       revisions of foo.c that were made by joe:

           bk log -nd'$if(:USER:=joe){:REV:}' foo.c

   CONDITIONAL STATEMENTS
       $if(<expr>){<anything>}
           prints <anything> if <expr> is true.  If <expr> is a keyword, i.e.,
           :MERGE:,  then the keyword is examined and returns true if it has a
           value.  <anything> can contain keywords, i.e., :REV:.
       $unless(<expr>){<anything>}
           prints <anything> unless <expr> is true.
       $if(<expr>){<stuff if true>}$else{<stuff if false>}
           both $if and $unless can have an optional $else clause that  prints
           if the preceding clause was not printed.

   CONDITIONAL OPERATORS
       strings  <lhs>=<rhs> true if <lhs> is identical to <rhs>.
                <lhs>!=<rhs> true if <lhs> is different than <rhs>.
                <str>=~<glob> true if <str> matches <glob>.
                <str>=~</regexp/> true if <str> matches the regular expres-
                sion; /regexp/i does a case-insensitive match and /glob/g does
                a glob match.
                Note: spaces immediately before and after the operator are
                ignored.  To match against such a leading or trailing space,
                escape it.
       numbers  <lhs> -eq <rhs> equality;
                <lhs> -ge <rhs> equal or greater than;
                <lhs> -gt <rhs> greater than;
                <lhs> -le <rhs> equal or less than;
                <lhs> -lt <rhs> less than.
                Note: spaces are required on both sides of the operator.

   COMPOUND EXPRESSIONS
       As of BitKeeper release 4.1, dspecs support logical AND (A && B), logi-
       cal OR (A || B), and parenthesized subexpressions ((A && B) || (C &&
       D)).  Note: spaces immediately before and after the operator are
       ignored.  To match against such a leading or trailing space, escape it.

   ITERATIVE OUTPUT
       Some keywords, such as comments or tags, may be multi-line.  To print a
       prefix in front of each of these lines, the dspec is:

           bk log -d'$each(:C:){C  (:C:)\n}' foo.c

       This  iteration  works  for all keywords, but normally is only used for
       keywords that can contain multiple lines like ALL_TAGS, C, TAGGED,  and
       TAGS.

       The $first() builtin can be used to print only the first line of one of
       these  multi-line  keywords.   Some development efforts tend to use the
       first line of commit comments as a summary of the change; the rest  are
       more  details.  The dspec that ships with BitKeeper for bk changes uses
       this feature to implement bk changes --short.  To print the first  line
       of each comment in a changeset:

           bk changes -nd'$first(:C:)'

   VARIABLES
       When  the  bk log command is run over multiple revisions of one or more
       files, the data specification ("dspec")  is  evaluated  once  for  each
       revision, and it sometimes is useful to use dspec variables, denoted as
       '$0',  '$1',  up to '$9', to remember values across revisions or files.
       A variable is assigned a value with:

           ${0=<dspec>}

       where <dspec> is a  recursively  evaluated  data  specification.   Once
       assigned, a variable retains its value for the remainder of the command
       (or  until reassigned).  Variables start out as empty strings (evaluate
       to zero in numeric context), and when re-assigned the old value is dis-
       carded.

   DSPEC VERSION 2
       This little printf like language outgrew  itself,  having  if/then/else
       and  other control flow was too much on just one line.  We came up with
       a version 2 language that allows you to have dspecs that  look  like  a
       programming  language.   All  of  the output from BitKeeper commands is
       generated via the v2 language in external files (see dspec-* in the bin
       directory).  All of the commands that take dspecs also can take a  file
       containing the dspec; that's how the BitKeeper commands work, they just
       load those files.

       To switch into the new language a dspec has to begin like so:

           # dspec-v2

       The  language is awk like, comments start with "#" and go to the end of
       the line.  Whitespace is ignored unless it  is  inside  double  quotes,
       then  it is reproduced exactly.  Keywords are expanded inside of double
       quotes as are the escaped characters mentioned above.  Control flow and
       begin/end blocks (all the $something) are unquoted.

       Like awk, there are optional begin/end blocks:

           $begin {
                   "[\n"
           }
           $end {
                   $if($0 -eq 1) {
                           "\n"
                   }
                   "]\n"
           }

       Those are from dspec-changes-json-v which is the dspec that is used for
       bk changes -v --json which (surprise!) produces json format output.  If
       you want to understand this language that is a good file to read.

       Other than variables, which are expanded inside double quotes, none  of
       the  $word  ($if/$else/$first/$each/etc)  expand  inside double quotes.
       This can be surprising, you might think the bk  changes  --short  dspec
       is:

           ":MD5SUM: $first(:C:)\n"

       but that does not work, this will:

           ":MD5SUM: " $first(:C:) "\n"

       In  many cases, all keywords will expand in begin/end blocks, those are
       run in the context of the first/last delta selected.   If  a  range  is
       selected  that has no matching deltas (think bk changes -L for example)
       then none of the keywords will be expanded, the current system  expands
       keywords if and only if there is a valid delta in play.

       A simple dspec-v2 is the bk log output format:

           ":DPN: :REV:\n"
           "  :D_: :T::TZ: :USERHOST: +:LI: -:LD:\n"
           $each(:C:) {            # comments
                   "  (:C:)\n"
           }
           "\n"
           $if (:TAGS:) {
                   $each(:TAGS:) {
                           "  TAG: (:TAGS:)\n"
                   }
                   "\n"
           }

       That says:
       line 1: print the path name and the revision
       line  2:  indent  the  date/time/timezone user@host +lines added -lines
       deleted
       line 3-5: indent each line of the comments
       line 6: blank line
       line 7-11: if there are tags, print them with another blank line

   KEYWORDS
       Some keywords are per repository and are marked with R in the T  column
       below.   Some keywords are per file and are marked with F in the T col-
       umn below; other keywords are per delta and are marked  with  D.   Some
       keywords  only  make sense if they are changesets, they are marked with
       C.  Those keywords that can be either on a changeset or on a  file  are
       marked with D.

       Name          T   What is printed
       ==========================================================
       :AGE:         D   D's age, i.e., seven hours, two weeks, etc.
       :ALL_TAGS:    C   The tag[s] if this changeset has or ever had them
       :ATTACHED_ID: F   package id to be used for new deltas
       :BAM:         F   true if the file is managed as a BAM file
       :C:           D   D's comments
       :CHANGESET:   F   true if ChangeSet file, false for user files
       :COMMENTS:    D   comments portion of :PRS:
       :COMPRESSION: D   D's compression (gzip|none)
       :CSETKEY:     D   delta key if D is at a changeset boundary
       :CSETREV:     D   revision of first cset boundary after D
       :D:           D   D's date as YYYY/MM/DD
       :D_:          D   D's date as YYYY-MM-DD
       :DANGLING:    D   D's rev if & only if D is a dangling delta
       :DI:          D   D's includes/excludes as +I,I/-X,X (serials)
       :DIFFS:       D   D's changes in the form of traditional diffs
       :DIFFS_U:     D   D's changes in the form of unified diffs
       :DIFFS_UP:    D   D's changes in the form of unified/procedural diffs
       :DL:          D   lines inserted/deleted/unchanged in D
       :DM:          D   month part of D's date (Jan..Dec)
       :DOMAIN:      D   the domain part of the hostname of D
       :DP:          D   the serial number of the parent of D
       :DPN:         D   the pathname of g.file as of D
       :DS:          D   the serial number of D
       :DSUM:        D   D's 16 bit unsigned checksum (%05u)
       :DSUMMARY:    D   first line of :PRS:
       :DT:          D   D's type: (D|R|T) meaning (Data|Removed|Tag)
       :Dd:          D   day part of D's date as DD
       :Dm:          D   month part of D's date as MM
       :Dn:          D   serial numbers of D's includes, if any
       :Dt:          D   D's data as :DT::REV::D::T::USER::DS::DP:
       :Dx:          D   serial numbers of D's excludes, if any
       :Dy:          D   year part of D's date as YY or YYYY
       :ENC:         F   current encoding scheme (ascii|uuencode|BAM)
       :EVEN:        D   True on every other delta processed
       :F:           F   basename of the BitKeeper file
       :FLAGS:       D   file flags as of D in words (HASH, YEAR4...)
       :FSUM:        F   16 bit unsigned checksum of the s.file
       :FUDGE:       D   time stamp fudge used make time monotonic
       :FULLHOST:    D   same as :HOST: or :HOST:/:REALHOST:
       :FULLUSER:    D   same as :USER: or :USER:/:REALUSER:
       :G:           F   basename of the gfile
       :GB:          D   file as of version D
       :GCA:         D   find the graph GCA for D's parents
       :GCA2:        D   find the set GCA for D's parents
       :GFILE:       F   pathname of the gfile
       :GREV:        F   for a file with conflicts, the GCA of the unmerged tips
       :HASHCOUNT:   D   count of key/value pairs in D if & only if hash file
       :HOST:        D   hostname where D was made; could be BK_HOST
       :HTML_AGE:    D   age in a form suitable for web pages
       :HTML_C:      D   comments in a form suitable for web pages
       :ID:          D   the package id in effect when the delta was made
       :IMPORTER:    D   name of the importer of D, if D was an emailed patch
       :KEY:         D   BitKeeper key of D
       :KID:         D   D's direct kid in D's branch
       :KIDS:        D   all of D's direct kids in the graph
       :L:           D   the second field in D's rev (R.L.B.S)
       :LD:          D   lines deleted in D (%u)
       :LI:          D   lines inserted in D (%u)
       :LREV:        F   for a file with conflicts, the LOCAL unmerged tip
       :LU:          D   lines unchanged in D (%u)
       :Ld:          D   lines deleted in D (%05u)
       :Li:          D   lines inserted in D (%05u)
       :Lu:          D   lines unchanged in D (%05u)
       :MD5KEY:      D   crypto based BitKeeper key of D
       :MERGE:       D   D's rev if & only if D has a merge parent
       :MGP:         D   D's merge parent's serial number
       :MODE:        D   D's file modes as an octal (777)
       :MPARENT:     D   D's merge parent's revision
       :N:           D   Number of deltas, use instead of DS, DS may have gaps.
       :NEXT:        D   next entry after D in delta table
       :ODD:         D   True on every other delta processed
       :PACKAGE_ID:  R   per repository unique id (like bk id)
       :PARENT:      D   D's parent's revision
       :PREV:        D   previous entry before D in delta table
       :PRODUCT_ID:  R   per repository unique id (like bk -P id)
       :PRS:         D   old-style bk prs default output
       :R:           D   the first field in D's rev (R.L.B.S)
       :RANDOM:      F   random bits part of ROOTKEY
       :REALHOST:    D   real host where D was made, regardless of BK_HOST
       :REALUSER:    D   real programmer who made D, not assumed identity
       :RENAME:      D   D's path if different from parent's path
       :REPO_ID:     R   per repository unique id (like bk id -r)
       :REPOTYPE:    R   repotype: product|component|standalone
       :REV:         D   D's revision number
       :RI:          D   revision numbers of D's includes/excludes
       :ROOTKEY:     F   key of the 1.0 delta, file's internal name
       :RREV:        F   for a file with conflicts, the REMOTE unmerged tip
       :RWXMODE:     D   D's file modes as ascii (-rwxrwxrwx)
       :Rn:          D   revision numbers of D's includes
       :Rx:          D   revision numbers of D's excludes
       :S:           D   last field in D's rev (R.L.B.S)
       :SFILE:       F   pathname of s.file
       :SIBLINGS:    D   rev sibling's pointer in D
       :SPN:         D   pathname of s.file as of D
       :SYMLINK:     D   value of D's symlink target
       :T:           D   time of D as HH:MM:SS
       :TAGGED:      C   The tag[s] iff currently on this changeset
       :TAGS:        C   Tag[s] if on, or were on, this changeset (with notes)
       :TIME_T:      D   D's date as GMT time_t, TZ and Fudge adjusted
       :TIP:         D   D's rev if D is at the tip (TOT)
       :TZ:          D   offset from GMT as +/-HH:MM
       :Th:          D   hour part of D's date as HH
       :Tm:          D   minute part of D's date as MM
       :Ts:          D   seconds part of D's date as SS
       :USER:        D   programmer who made D; could be assumed identity
       :UTC:         D   D's time stamp as YYYYMMDDHHMMSS in GMT
       :UTC-FUDGE:   D   like UTC but without the date fudge
       :VERSION:     F   file format version

NOTES
       Keywords  marked with type C or D above can optionally be restricted to
       a given revision as follows:

           :KW|1.0:      # as of a literal revision
           :KW|PARENT:   # as of the current rev's parent
           :KW|MPARENT:  # as of the current rev's merge parent (if any)

       For example:

           bk log -hnd'$if(:DPN|PARENT: != :DPN:){rename :DPN|PARENT: => :DPN:}'

       Things that can go in the second part include a specific  revision  (eg
       1.0), PARENT, and MPARENT.

EXAMPLES
       To extract a key, which is a stable name for a changeset:

           bk changes -r1.234 -nd:MD5KEY:

       To count up all the deltas in all user files:

           bk -U log -nd:REV: | wc -l

       List users who have made changes in a subdirectory in the last month:

           bk -rSubDir log -c-1M.. -nd:USER: | sort -u

       To see the number of merge changesets:

           bk changes -nd'$if(:MERGE:){merge}' | wc -l

       To see the number of merges in user files:

           bk -U log -nd'$if(:MERGE:){merge}' | wc -l

       Count up lines inserted by a particular user in all non-merge deltas:

           bk -U log -nd'$if(:USER: = joe && !:MERGE:){:LI:}' |
           awk '{ lines += $1 } END { print lines }'

       The  default  dspec  for  the  bk changes command is below.  This is an
       example of a dspec-v2 style of writing dspecs, much more  pleasant  for
       complex reports.

           # dspec-v2

           # The default dspec used by 'bk changes' and 'bk changes -v'

           ":INDENT:"              # 2 spaces + 2 in component
           ":DPN:@:REV:"
           ${1=:USERHOST:}         # 1 == user || user@host
           $if (:CHANGESET: && !:COMPONENT_V:) {
               ", :Dy:-:Dm:-:Dd: :T::TZ:, $1"
               ${0=$1}                          # 0 == user of last cset
           } $else {
               $if($0 != $1){                   # print user if different
                         ", $1"
               }
           }
           $unless (:CHANGESET:) {
               " +:LI: -:LD:"                   # lines added/deleted
           }
           "\n"

           # bk changes --short is an alias for
           # bk changes --begin='${9=1}'
           # so $9 is the switch that decides between short/long form
           $if ($9 -eq 0) {                     # comments (long form)
               $each(:C:) {
                   ":INDENT:  (:C:)\n"
               }
           } $else {                            # comments (short form)
               ":INDENT:  "
               $first(:C:)
               "\n"
           }
           $each(:TAGS:) {
               "  TAG: (:TAGS:)\n"
           }
           $if ($9 -eq 0) {                     # skip merge info for --short
               $if (:MERGE:) {                  # merge shows both parents
                   ":INDENT:  MERGE: :MPARENT:\n"
               }
           }
           "\n"

SEE ALSO
       bk help range

CATEGORY
       File

BitKeeper Inc                         1E1                         bk log(none)
$
help://makepatch
help://makepatch.1
help://bk-makepatch
help://bk-makepatch.1
bk makepatch(none)          BitKeeper User's Manual         bk makepatch(none)

NAME
       bk makepatch - creates BitKeeper patches

SYNOPSIS
       bk makepatch [-vd] [-r<range>] [-]

DESCRIPTION
       The makepatch command is a low level command used to generate BitKeeper
       patches.

OPTIONS
       -B        Include  the  data  from any BAM files in the patch. Normally
                 BAM files are sent without the implied data.
       -C        Generate a patch compatible with any  supported  versions  of
                 BitKeeper.
       -d        Add  a  header  with the unified diffs to the top of the Bit-
                 Keeper patch.
       -r<range> Generate a BitKeeper patch of the changesets in <range>.
       -v        Be more verbose for each instance.
       -         Instead of specifying the range with "-r", this form  expects
                 the  revisions on the standard input, one per line, either as
                 keys or revisions.

NOTES
       In general, users do not use this command directly, it is called by  bk
       pull  or  bk  push.   If patches are to be sent to a non-BitKeeper user
       then use bk export.

       By default patches are created in the latest patch format known by this
       version of BitKeeper. With -C patches will be  compatible  with  oldest
       version of BitKeeper that is still supported.

SEE ALSO
       bk help export, bk help takepatch

CATEGORY
       Repository

BitKeeper Inc                         1E1                   bk makepatch(none)
$
help://merge
help://merge.1
help://bk-merge
help://bk-merge.1
bk merge(none)              BitKeeper User's Manual             bk merge(none)

NAME
       bk merge - three-way text based file merge

SYNOPSIS
       bk merge [-s] <local> <ancestor> <remote> <merge>
       bk merge [-s] <path/gfile>

DESCRIPTION
       The  bk  merge  command  combines changes made to <ancestor> by <local>
       with the changes made to <ancestor> by <remote> and  merges  them  into
       <merge>.  When only a gfile is given on the command line, it is assumed
       to be a file in the RESYNC tree with an unresolved merge.  In that case
       the 3 parts are extracted automatically and the merge output is written
       to stdout.  This form is mainly useful as part of pre-resolve triggers.

       If  all  changes  are made to different regions of the <ancestor>, then
       the merge is said to be free of conflicts.

       A conflict occurs if both <local> and <remote> have made changes to the
       same section of <ancestor>.  If a conflict is  found,  the  conflicting
       lines will be marked in the output as follows:

           <<<<<<< <local>
           changes made in the local repository
           =======
           changes made in the remote repository
           >>>>>>> <remote>

       It  is  up  to the caller to edit the <merge> file and resolve any con-
       flicts.

OPTIONS
       -s  Perform a set merge instead of a normal file merge.  In  this  case
           the  files are assumed to be lists of items, one item per line, and
           the merge does an automatic union  of  the  lists  and  writes  the
           result in sorted order.  Conflicts cannot occur in this mode.  This
           option is automatically used to merge these BitKeeper files:
           BitKeeper/etc/gone
           BitKeeper/etc/ignore

EXIT STATUS
       bk merge returns exit status:

       0   if there were no conflicts
       1   if there were conflicts
       2   if an error occurred

SEE ALSO
       diff3(1),  bk  help  fmtool,  bk help remerge, bk help resolve, bk help
       resolving, bk help smerge, bk help triggers

CATEGORY
       Repository
       File

BitKeeper Inc                         1E1                       bk merge(none)
$
help://merge-binaries
help://merge-binaries.1
help://bk-merge-binaries
help://bk-merge-binaries.1
bk merge-binaries(none)     BitKeeper User's Manual    bk merge-binaries(none)

NAME
       bk merge-binaries - help on merging binary conflicts

DESCRIPTION
       This  section documents the binary merge process started by the resolve
       command.  See bk resolve for details on using resolve.

       While in resolve, you can hit the return key to see a  summary  of  the
       commands.

       BitKeeper  has  no  built in mechanism to merge binaries, since it does
       not know what is in the binaries.  The built in choices  you  have  are
       outlined  in  the  resolver, and amount to choosing either the local or
       the remote version of the file.

       The built in choices do not include a file viewer since BitKeeper  does
       not  know what to use.  You can call your own file viewer.  Suppose you
       knew that the file was a gif and you wanted to look at each of them  to
       choose which one to use.  You could do a

           logo.gif>> !xv $BK_LOCAL
           logo.gif>> !xv $BK_REMOTE
           logo.gif>> ul

       to view each and then choose the local version.

       You may also call an external tool to merge changes.

           logo.gif>> !<command>

       then  <command>  will be run with the appropriate environment variables
       set.  This technique may be used to use any external merge tool.

ENVIRONMENT VARIABLES
       BK_LOCAL  pathname of a temp file containing the local version
       BK_GCA    pathname of a temp file containing the common ancestor
       BK_REMOTE pathname of a temp file containing the remote version
       BK_MERGE  pathname where the merged content should be placed

NON-BINARY FILES
       Sometimes a file may be marked as binary incorrectly, where incorrectly
       means that normal text based tools would work on this  file.   You  may
       force the file to be treated as a text file with the "t" command.  This
       drops into the normal text file resolver.

SEE ALSO
       bk help revtool, bk help resolve, bk help resolving

CATEGORY
       Overview
       Repository

BitKeeper Inc                         1E1              bk merge-binaries(none)
$
help://mv
help://mv.1
help://bk-mv
help://bk-mv.1
help://mvdir
bk mv(none)                 BitKeeper User's Manual                bk mv(none)

NAME
       bk mv - rename file[s]

SYNOPSIS
       bk mv [-f] <source-file-or-dir> [<file> ...]  <dest-file-or-dir>

DESCRIPTION
       To rename a file/directory from <A> to <B> do this:

           $ bk mv A B

       The  bk mv command will rename the checked out file (if any) as well as
       the revision control file.  Edited files are also renamed and then  re-
       edited, preserving any changes made but not yet checked in.  The rename
       will  appear  as  an  additional change to the file when you commit the
       next changeset.

       Renames propagate just like content changes, i.e., they happen automat-
       ically when you pull changes into your repository from another  reposi-
       tory unless you have also renamed the file.  In that case, the resolver
       will prompt you to choose a name.

       If  the  last argument is an existing directory, bk mv moves all listed
       files into that directory.  Otherwise, if only two files are given,  it
       renames the first as the second.  It is an error if more than two files
       are  listed  and  the  last argument is not a directory.  The intent is
       that bk mv behaves like the traditional UNIX mv command, except that it
       knows about the additional  BitKeeper  files  and  records  the  rename
       event.

NOTES
       bk  mv  will  refuse  to move BitKeeper metafiles without the -f option
       (use of which is not recommended).

       If both the <A> and <B> arguments are directories, bk mv will check the
       repository consistency.  If this check fails the  move  operation  will
       not continue.

SEE ALSO
       bk  help commit, bk help names, bk help pull, bk help push, bk help rm,
       bk help rmdir

CATEGORY
       Common
       File

BitKeeper Inc                         1E1                          bk mv(none)
$
help://names
help://names.1
help://bk-names
help://bk-names.1
bk names(none)              BitKeeper User's Manual             bk names(none)

NAME
       bk names - put BitKeeper files where they should be

SYNOPSIS
       bk names [-q] [<file> ... | -]

DESCRIPTION
       Each  BitKeeper  s.file  records  its  path relative to the root of the
       repository.  This command examines each of the listed files  and  moves
       them into their recorded location if they are not there already.

OPTIONS
       -q  Quiet mode.

CATEGORY
       Utility

BitKeeper Inc                         1E1                       bk names(none)
$
help://new
help://new.1
help://bk-new
help://bk-new.1
help://add
help://enter
bk new(none)                BitKeeper User's Manual               bk new(none)

NAME
       bk new - add a file to the repository

SYNOPSIS
       bk new [-bcq] [-M<mode>] [<file> ... | -]

DESCRIPTION
       The  bk  new  command  is used to initially place files under BitKeeper
       control.

       A useful way to add new files in the current directory is:

           bk gfiles -x *.[ch] | bk new -

       When you want to add files in the current directory and all subdirecto-
       ries, do the following:

           bk -xr. new    # same as bk gfiles -x | bk new -

       After the files are checked in, don't be  surprised  to  see  that  the
       files are no longer in your directory. The process of checking in files
       removes the files from the directory and places them in the SCCS direc-
       tories.  Once in the SCCS directory, the file can be retrieved with the
       bk  get  or  bk  edit commands.  Most versions of the UNIX make command
       know about SCCS and will automatically check  out  files  as  they  are
       needed.

OPTIONS
       -b        force  binary encoding with no keyword expansion; recommended
                 for all binary files, but will work on  text  files  as  well
                 (with  a  corresponding  increase in the size of the revision
                 history file).
       -c        Use comments saved by a previous run  of  citool,  fix,  col-
                 lapse, etc.  It is an error if there are no saved comments.
       -M<mode>  Set the permissions on the new delta to <mode>.
       -q        be quiet.

SEE ALSO
       bk  help  delta,  bk  help  edit,  bk help get, bk help ignore, bk help
       gfiles

CATEGORY
       File
       Common

BitKeeper Inc                         1E1                         bk new(none)
$
help://newroot
help://newroot.1
help://bk-newroot
help://bk-newroot.1
bk newroot(none)            BitKeeper User's Manual           bk newroot(none)

NAME
       bk newroot - change the identity of a repository

SYNOPSIS
       bk newroot [-k<randombits>] [-y<comment>]
       bk newroot

DESCRIPTION
       bk newroot is an administrative command used to generate a new identity
       for  a  repository.   It is typically used only after having repaired a
       repository.  After running bk newroot that repository will not be  able
       to push to or pull from it's parent or any other related repository.

OPTIONS
       -k<bits> Specify  the string of random bits used as part of the reposi-
                tory identity.  The string must be 16 hex digits.

       -y<comment> Specify a comment to  be  used  for  why  the  rootkey  was
                   changed.  Must be a single line.

SEE ALSO
       bk help id, bk help clone, bk help pull, bk help push, bk help terms

CATEGORY
       Admin

BitKeeper Inc                         1E1                     bk newroot(none)
$
help://obscure
help://obscure.1
help://bk-obscure
help://bk-obscure.1
bk obscure(none)            BitKeeper User's Manual           bk obscure(none)

NAME
       bk obscure - obscure BitKeeper file comments and contents

SYNOPSIS
       bk obscure

WARNING
       This  command  will  destroy  your repository; do it if and only if the
       repository in question is an unneeded copy.

DESCRIPTION
       The bk obscure command is typically used if you wish to send a  reposi-
       tory  to BitKeeper for performance analysis and/or debugging.  All data
       files have their contents and comments obscured.  The  intent  is  that
       the  obscuring of the repository data will result in a repository which
       has the same size, shape, number of deltas, number of changesets, etc.,
       but with different data.

       The current method used to obscure the data is to  sort  each  line  of
       data alphabetically, i.e.,

           Please obscure me

       turns into

           ussromleeeecbaP

       The   obscuring   is  currently  fairly  simple  and  is  theoretically
       reversible with enough compute power so this is not a means to  encrypt
       a repository.

SEE ALSO
       bk help admin

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk obscure(none)
$
help://parent
help://parent.1
help://bk-parent
help://bk-parent.1
help://remote
bk parent(none)             BitKeeper User's Manual            bk parent(none)

NAME
       bk parent - manage repository parent pointer[s]

SYNOPSIS
       bk parent [-a|-r|-s] [-1iloq] [<repository>] [<repository>]

   SETTING PARENT POINTERS
       bk parent -s [-ioq] <repository> [<repository>]

   ADDING PARENT POINTERS
       bk parent -a [-ioq] <repository> [<repository>]

   REMOVING PARENT POINTERS
       bk parent -r [-ioq] <repository> [<repository>]

   LISTING PARENT POINTERS
       bk parent [-1iloq]

DESCRIPTION
       The  bk parent command is used to set, add, adjust, remove or list par-
       ent pointers for a repository.  A parent pointer  is  a  BitKeeper  URL
       which  is  the  location  from  or to which  a repository gets or sends
       updates when running bk pull or bk push.  The typical case  is  that  a
       repository  has only one ``parent'' but it is possible for a repository
       to have multiple parent pointers and each pointer may be incoming, out-
       going, or both.

       When setting the parent pointer, the parent command is  backwards  com-
       patible with earlier versions if and only if there is currently no par-
       ent pointer or there is one and only one push/pull parent pointer.

       The parent is automatically set when a repository is cloned and will be
       named according to the access method (see bk help url for more informa-
       tion).

OPTIONS
       -1  List  only  the  first  parent found.  May be combined with "-i" or
           "-o" to list the  first  incoming  or  outgoing  parent  pointer[s]
           respectively.
       -a  Add  the  specified  parent pointer to the list of parents.  May be
           combined with "-i" or "-o" to add just  the  incoming  or  outgoing
           parent pointer[s] respectively.
       -i  Operate  only on incoming (pull) parent pointers.  May be used when
           setting, adding, adjusting, removing, or listing parents.
       -l  List the parent pointer[s] without any annotations, one  per  line.
           May be combined with "-i" or "-o" to list just the incoming or out-
           going parents respectively.
       -o  Operate  only on outgoing (push) parent pointers.  May be used when
           setting, adding, adjusting, removing, or listing parents.
       -q  Do not produce output when adding/removing/listing parents.  May be
           combined with "-i" or "-o" to query whether the repository  has  an
           incoming (pull) or outgoing (push) parent pointer, exit status will
           be  0  if  any matching parent pointers where found, otherwise exit
           status is 1.
       -r  Remove the parent pointer.  May be combined with "-i"  or  "-o"  to
           remove  just  the  incoming  or  outgoing parent pointer[s] respec-
           tively.  Using "-i" or "-o" on a bidirectional parent pointer  con-
           verts the parent pointer to unidirectional.
       -s  Set  the  parent  pointer[s]  to  the specified list, replacing any
           existing pointers.  This option is always required to override  any
           existing  parent pointers except in the case that there is only one
           bidirectional parent pointer and it  is  being  replaced  with  one
           bidirectional parent pointer (backwards compat).

BUGS
       The  term  parent  is  somewhat of a misnomer in a peer to peer system.
       Since it is quite common to  use  BitKeeper  repositories   in  a  par-
       ent/child relationship most of the time, we have stuck with the term.

SEE ALSO
       bk  help  bkd,  bk  help  changes, bk help clone, bk help pull, bk help
       push, bk help url

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk parent(none)
$
help://partition
help://partition.1
help://bk-partition
help://bk-partition.1
bk partition(none)          BitKeeper User's Manual         bk partition(none)

NAME
       bk partition - transform a single repository into a nested collection

SYNOPSIS
       bk partition [<options>] [-C<components> | -@<url>] <from> <to>

DESCRIPTION
       The partition command is used to transform a single large repository to
       product  composed  of a collection of component repositories.  The col-
       lection of component files is determined by the  component  list  file,
       which  is  a list of directories which will become component repository
       roots.

       To get the most flexibility out of using a partitioned repository,  the
       partition should be done such that few, if any, files remain in the top
       level  product.   Best is if the top level product repository is only a
       collection of component repositories.

       Partition will prune all deleted and missing files, and create an empty
       gone file.  Any file that used to be in one component and was moved  to
       another component will only appear in the most recent component.

       As part of partition, it is possible to remove the record of some files
       that  were  accidentally  added  along  the way, and or have since been
       removed and added to the gone file.  A list of keys to  be  removed  is
       stored in a prunelist file, one key per line.

       To  transform  many repositories, first transform one into a layout you
       like.  Then transform the others, using the  -@url  option  naming  the
       first post-partition repository.  Each repository partitioned after the
       first must contain all of the csets of the first repository.

OPTIONS
       -@<url>        Instead  of  specifying  components list and prune list,
                      specify a url to a repository that has been partitioned.
                      The result will be a  repository  that  can  communicate
                      with  that  url,  or  partition  will fail with messages
                      about why it can't do that.
       -C<components> Specify a file  containing  the  directories  that  will
                      become  component repository roots.  The directories are
                      listed in the file, one per line.  Lines starting with #
                      will be ignored, as well as blank lines.
       -P<prunelist>  Specify a file containing the keys to be removed  before
                      the  partitioning  begins.  This is similar to running a
                      bk csetprune before running bk partition.   The  differ-
                      ence  is  that the bk partition command will provide the
                      stable -k parameter to the csetprune enable the  result-
                      ing  repositories  to communicate with repositories that
                      have gone through the same partitioning.
       --keep-deleted Normally,  partition  prunes  all  deleted  files.   Use
                      --keep-deleted  to  keep  the deleted history as part of
                      the component the file was most recently in before being
                      deleted.
       -j<N>          Run the per-component portions of the partition in  par-
                      allel  using  N  processes.   Useful for partitioning on
                      multi-core machines.
       -q             Run quietly.

EXAMPLE
       Suppose there is a repository which has two major  subsections,  called
       doc and src respectively.  The repository has grown to be too large and
       people  working  on one part may not need the other part. The following
       steps would convert it to a product comprising many components, such as
       'doc' and 'src'.

       Create a file which defines the partition boundaries.  Call  it  compo-
       nents:

           $ cat components
           # These directory paths are the partition boundaries
           # Note that one can be under another: src and src/gnu
           # src would get everything under src that is not under src/gnu
           doc
           src
           src/gnu
           lib/graph
           lib/print
           # and the list could go on for hundreds of lines
           $

       Then  run the command to transform the original repo, called standalone
       in this example, into  a  nested  collection  of  repositories,  called
       nested.

           $ bk partition -Ccomponents standalone nested

       To  partition another repository, you can reference the first partition
       you did instead of passing in the component list.  Standalone2 must  be
       a superset of standalone for the partition to work.

           $ bk partition -@nested standalone2 nested2

CATEGORY
       Nested

BitKeeper Inc                         1E1                   bk partition(none)
$
help://patch
help://patch.1
help://bk-patch
help://bk-patch.1
bk patch(none)                                                  bk patch(none)

NAME
       bk patch - apply a diff file to an original

SYNOPSIS
       bk patch [<options>] [<originalfile> [<patchfile>]]

       but usually just

       bk patch -p<num> < <patchfile>

DESCRIPTION
       bk patch takes a patch file <patchfile> containing a difference listing
       produced by bk diff and applies those differences to one or more origi-
       nal  files,  producing patched versions.  Normally the patched versions
       are put in place of the originals.  Backups can be made; see  the  "-b"
       or "--backup" option.  The names of the files to be patched are usually
       taken  from  the patch file, but if there's just one file to be patched
       it can specified on the command line as <originalfile>.

       Upon startup, bk patch attempts to determine the type of the diff list-
       ing, unless overruled by a  "-c"  ("--context"),  "-e"  ("--ed"),  "-n"
       ("--normal"),  or "-u" ("--unified") option.  Context diffs (old-style,
       new-style, and unified) and  normal  diffs  are  applied  by  bk  patch
       itself, while ed(1) diffs are simply fed to ed via a pipe.

       bk  patch  tries  to skip any leading garbage, apply the diff, and then
       skip any trailing garbage.  Thus you could feed an article  or  message
       containing  a  diff  listing  to  bk patch, and it should work.  If the
       entire diff is indented by a consistent amount, or if  a  context  diff
       contains  lines  ending in CRLF or is encapsulated one or more times by
       prefixing "-" to lines starting with "-" as specified by  Internet  RFC
       934, this is taken into account.

       With  context diffs, and to a lesser extent with normal diffs, bk patch
       can detect when the line numbers mentioned in the patch are  incorrect,
       and attempts to find the correct place to apply each hunk of the patch.
       As a first guess, it takes the line number mentioned for the hunk, plus
       or minus any offset used in applying the previous hunk.  If that is not
       the correct place, bk patch scans both forwards and backwards for a set
       of  lines matching the context given in the hunk.  First bk patch looks
       for a place where all lines of the context match.  If no such place  is
       found, and it's a context diff, and the maximum fuzz factor is set to 1
       or more, then another scan takes place ignoring the first and last line
       of  context.  If that fails, and the maximum fuzz factor is set to 2 or
       more, the first two and last two lines  of  context  are  ignored,  and
       another  scan  is made.  (The default maximum fuzz factor is 2.)  If bk
       patch cannot find a place to install that hunk of the  patch,  it  puts
       the hunk out to a reject file, which normally is the name of the output
       file  plus a ".rej" suffix, or "#" if ".rej" would generate a file name
       that is too long (if even appending the single character "#" makes  the
       file  name too long, then "#" replaces the file name's last character).
       (The rejected hunk comes out in ordinary context diff  form  regardless
       of  the  form of the input patch.  If the input was a normal diff, many
       of the contexts are simply null.)  The line numbers on the hunks in the
       reject file may be different than in the patch file: they  reflect  the
       approximate  location  that  bk patch thinks the failed hunks belong in
       the new file rather than the old one.

       As each hunk is completed, you are told if the hunk failed, and  if  so
       which  line  (in  the new file) bk patch thought the hunk should go on.
       If the hunk is installed at a different line from the line number spec-
       ified in the diff you are told the offset.  A single large offset might
       indicate that a hunk was installed in the wrong place.   You  are  also
       told  if  a  fuzz  factor was used to make the match, in which case you
       should also be slightly  suspicious.   If  the  "--verbose"  option  is
       given, you are also told about hunks that match exactly.

       If  no  original  file  <origfile> is specified on the command line, bk
       patch tries to figure out from the leading garbage what the name of the
       file to edit is, using the following rules.

       First, bk patch takes an ordered list of candidate file names  as  fol-
       lows:

       =>  If the header is that of a context diff, bk patch takes the old and
           new  file  names  in  the header.  A name is ignored if it does not
           have enough slashes to satisfy the or option.  The  name  /dev/null
           is also ignored.
       =>  If there is an Index: line in the leading garbage and if either the
           old  and  new names are both absent or if bk patch is conforming to
           POSIX, bk patch takes the name in the Index: line.
       =>  For the purpose of the following rules, the  candidate  file  names
           are  considered to be in the order (old, new, index), regardless of
           the order that they appear in the header.

       Then bk patch selects a file name from the candidate list as follows:

       =>  If some of the named files exist, bk patch selects the  first  name
           if conforming to POSIX, and the best name otherwise.
       =>  If  bk  patch  is not ignoring RCS, ClearCase, and SCCS (see the or
           option), and no named files exist but an RCS,  ClearCase,  or  SCCS
           master is found, bk patch selects the first named file with an RCS,
           ClearCase, or SCCS master.
       =>  If  no  named  files  exist,  no RCS, ClearCase, or SCCS master was
           found, some names are given, bk patch is not conforming  to  POSIX,
           and  the  patch appears to create a file, bk patch selects the best
           name requiring the creation of the fewest directories.
       =>  If no file name results from the above heuristics,  you  are  asked
           for the name of the file to patch, and bk patch selects that name.

       To  determine the best of a nonempty list of file names, bk patch first
       takes all the names with the fewest path name components; of those,  it
       then  takes all the names with the shortest basename; of those, it then
       takes all the shortest names; finally, it  takes  the  first  remaining
       name.

       Additionally,  if the leading garbage contains a Prereq: line, bk patch
       takes the first word from the prerequisites line  (normally  a  version
       number)  and checks the original file to see if that word can be found.
       If not, bk patch asks for confirmation before proceeding.

       The upshot of all this is that you should be able to say,  while  in  a
       news interface, something like the following:

          | bk patch -d /usr/src/local/blurfl

       and patch a file in the blurfl directory directly from the article con-
       taining the patch.

       If the patch file contains more than one patch, bk patch tries to apply
       each  of  them  as if they came from separate patch files.  This means,
       among other things, that it is assumed that the name  of  the  file  to
       patch  must  be  determined for each diff listing, and that the garbage
       before each diff listing contains interesting things such as file names
       and revision level, as mentioned previously.

OPTIONS
       -b  or  --backup
           Make backup files.  That is, when patching a file, rename  or  copy
           the  original  instead of removing it.  When backing up a file that
           does not exist, an empty, unreadable backup file is  created  as  a
           placeholder  to  represent  the  nonexistent file.  See the "-V" or
           "--version-control" option for details about how backup file  names
           are determined.
       --backup-if-mismatch
           Back  up a file if the patch does not match the file exactly and if
           backups are not otherwise requested.  This is the default unless bk
           patch is conforming to POSIX.
       --no-backup-if-mismatch
           Do not back up a file if the patch does not match the file  exactly
           and if backups are not otherwise requested.  This is the default if
           bk patch is conforming to POSIX.
       -B pref  or  --prefix=pref
           Prefix <pref> to a file name when generating its simple backup file
           name.   For  example,  with "-B /junk/" the simple backup file name
           for src/patch/util.c is /junk/src/patch/util.c.
       --binary
           Read and write all files in binary mode, except for standard output
           and /dev/tty.  This option has no effect on  POSIX-conforming  sys-
           tems.   On  systems  like DOS where this option makes a difference,
           the patch should be generated by "diff -a --binary".
       -c  or  --context
           Interpret the patch file as a ordinary context diff.
       -d dir  or  --directory=dir
           Change to the directory <dir> immediately,  before  doing  anything
           else.
       -D define  or  --ifdef=define
           Use  the  "#ifdef" ...  construct to mark changes, with <define> as
           the differentiating symbol.
       --dry-run
           Print the results of applying the patches without actually changing
           any files.
       -e  or  --ed
           Interpret the patch file as an ed(1) script.
       -E  or  --remove-empty-files
           Remove output files that are empty  after  the  patches  have  been
           applied.   Normally  this option is unnecessary, since bk patch can
           examine the time stamps on the header to determine whether  a  file
           should  exist  after patching.  However, if the input is not a con-
           text diff or if bk patch is conforming to POSIX, bk patch does  not
           remove  empty  patched  files unless this option is given.  When bk
           patch removes a file, it also attempts to remove any empty ancestor
           directories.
       -f  or  --force
           Assume that the user knows exactly what he or she is doing, and  do
           not ask any questions.  Skip patches whose headers do not say which
           file  is to be patched; patch files even though they have the wrong
           version for the Prereq: line in the patch; and assume that  patches
           are not reversed even if they look like they are.  This option does
           not suppress commentary; use "-s" for that.
       -F num  or  --fuzz=num
           Set  the  maximum  fuzz  factor.  This option only applies to diffs
           that have context, and causes bk patch to ignore up  to  that  many
           lines  in looking for places to install a hunk.  Note that a larger
           fuzz factor increases the odds of a faulty patch.  The default fuzz
           factor is 2, and it may not be set to more than the number of lines
           of context in the context diff, ordinarily 3.
       -g num  or  --get=num
           This option controls the actions of bk patch when a file  is  under
           RCS or SCCS control, and does not exist or is read-only and matches
           the  default version, or when a file is under ClearCase control and
           does not exist.  If <num> is positive, bk  patch  gets  (or  checks
           out)  the  file from the revision control system; if zero, bk patch
           ignores RCS, ClearCase, and SCCS and does not get the file; and  if
           negative,  bk  patch  asks  the  user whether to get the file.  The
           default value of this option is given by the value of the PATCH_GET
           environment variable if it is set; if not,  the  default  value  is
           zero if bk patch is conforming to POSIX, negative otherwise.
       --help
           Print a summary of options and exit.
       -i patchfile  or  --input=patchfile
           Read  the patch from <patchfile>.  If <patchfile> is "-", read from
           standard input, the default.
       -l  or  --ignore-whitespace
           Match patterns loosely, in case tabs or spaces have been munged  in
           your  files.   Any sequence of one or more blanks in the patch file
           matches any sequence in the original file, and sequences of  blanks
           at  the  ends  of  lines are ignored.  Normal characters must still
           match exactly.  Each line of the context must still match a line in
           the original file.
       -n  or  --normal
           Interpret the patch file as a normal diff.
       -N  or  --forward
           Ignore patches that seem to be reversed or  already  applied.   See
           also "-R".
       -o outfile  or  --output=outfile
           Send output to <outfile> instead of patching files in place.
       -pnum  or  --strip=num
           Strip  the  smallest  prefix  containing <num> leading slashes from
           each file name found in the patch file.  A sequence of one or  more
           adjacent  slashes  is counted as a single slash.  This controls how
           file names found in the patch file are treated, in  case  you  keep
           your  files  in  a different directory than the person who sent out
           the patch.  For example, supposing the file name in the patch  file
           was

              /u/howard/src/blurfl/blurfl.c

           setting "-p0" gives the entire file name unmodified, "-p1" gives

              u/howard/src/blurfl/blurfl.c

           without the leading slash, "-p4" gives

              blurfl/blurfl.c

           and  not  specifying "-p" at all just gives you blurfl.c.  Whatever
           you end up with is looked for either in the current  directory,  or
           the directory specified by the "-d" option.
       --posix
           Conform more strictly to the POSIX standard, as follows:

           =>  Take  the  first  existing file from the list (old, new, index)
               when intuiting file names from diff headers.
           =>  Do not remove files that are empty after patching.
           =>  Do not ask whether to get files from RCS, ClearCase, or SCCS.
           =>  Require that all options precede the files in the command line.
           =>  Do not backup files when there is a mismatch.
       --quoting-style=<word>
           Use style <word> to quote output names.  The <word> should  be  one
           of the following:

           literal      Output names as-is.
           shell        Quote  names  for  the  shell  if  they  contain shell
                        metacharacters or would cause ambiguous output.
           shell-always Quote names for the shell, even if they would normally
                        not require quoting.
           c            Quote names as for a C language string.
           escape       Quote as with "c" except omit the surrounding  double-
                        quote characters.

           You  can  specify the default value of the "--quoting-style" option
           with the environment variable QUOTING_STYLE.  If  that  environment
           variable is not set, the default value is shell.
       -r rejectfile  or  --reject-file=rejectfile
           Put rejects into <rejectfile> instead of the default ".rej" file.
       -R  or  --reverse
           Assume  that  this  patch  was  created  with the old and new files
           swapped.  (Yes, I'm afraid that  does  happen  occasionally,  human
           nature  being  what  it  is.)   bk patch attempts to swap each hunk
           around before applying it.  Rejects come out in the swapped format.
           The "-R" option does not work with ed(1) diff scripts because there
           is too little information to reconstruct the reverse operation.

           If the first hunk of a patch fails, bk patch reverses the  hunk  to
           see if it can be applied that way.  If it can, you are asked if you
           want to have the "-R" option set.  If it can't, the patch continues
           to  be  applied  normally.   (Note:  this  method  cannot  detect a
           reversed patch if it is a normal diff and if the first  command  is
           an  append (i.e. it should have been a delete) since appends always
           succeed, due to the fact that  a  null  context  matches  anywhere.
           Luckily,  most patches add or change lines rather than delete them,
           so most reversed normal diffs begin with  a  delete,  which  fails,
           triggering the heuristic.)
       -s  or  --silent  or  --quiet
           Work silently, unless an error occurs.
       -t  or  --batch
           Suppress  questions like "-f", but make some different assumptions:
           skip patches whose headers do not contain file names (the  same  as
           -f);  skip patches for which the file has the wrong version for the
           Prereq: line in the patch; and assume that patches are reversed  if
           they look like they are.
       -T  or  --set-time
           Set  the  modification  and access times of patched files from time
           stamps given in context diff headers,  assuming  that  the  context
           diff  headers  use  local  time.   This  option is not recommended,
           because patches using local time cannot easily be used by people in
           other time zones, and because local time stamps are ambiguous  when
           local  clocks  move  backwards  during daylight-saving time adjust-
           ments.  Instead of using this option, generate patches with UTC and
           use the "-Z" or "--set-utc" option instead.
       -u  or  --unified
           Interpret the patch file as a unified context diff.
       -v  or  --version
           Print out the revision header and patch level of bk patch and exit.
       -V method  or  --version-control=method
           Use <method> to determine backup file names.  The method  can  also
           be  given  by the PATCH_VERSION_CONTROL (or, if that's not set, the
           VERSION_CONTROL) environment variable, which is overridden by  this
           option.   The method does not affect whether backup files are made;
           it affects only the names of any backup files that are made.

           The value of <method> is like the GNU Emacs `version-control' vari-
           able; bk patch also recognizes synonyms that are more  descriptive.
           The  valid  values  for  <method>  are  (unique  abbreviations  are
           accepted):

           existing  or  nil
               Make numbered backups of files that already have  them,  other-
               wise simple backups.  This is the default.
           numbered  or  t
               Make  numbered  backups.  The numbered backup file name for <F>
               is <F>.~<N>~ where <N> is the version number.
           simple  or  never
               Make simple backups.  The "-B" or "--prefix", "-Y" or  "--base-
               name-prefix", and "-z" or "--suffix" options specify the simple
               backup  file  name.  If none of these options are given, then a
               simple backup suffix is used; it  is  the  value  of  the  SIM-
               PLE_BACKUP_SUFFIX  environment  variable if set, and is ".orig"
               otherwise.

           With numbered or simple backups, if the backup  file  name  is  too
           long,  the backup suffix "~" is used instead; if even appending "~"
           would make the name too long, then "~" replaces the last  character
           of the file name.
       --verbose
           Output extra information about the work being done.
       -x num  or  --debug=num
           Set internal debugging flags of interest only to patch patchers.
       -Y pref  or  --basename-prefix=pref
           Prefix  <pref>  to  the basename of a file name when generating its
           simple backup file name.  For example, with "-Y .del/"  the  simple
           backup file name for src/patch/util.c is src/patch/.del/util.c.
       -z suffix  or  --suffix=suffix
           Use <suffix> as the simple backup suffix.  For example, with "-z -"
           the    simple    backup   file   name   for   src/patch/util.c   is
           src/patch/util.c-.  The backup suffix may also be specified by  the
           SIMPLE_BACKUP_SUFFIX  environment  variable, which is overridden by
           this option.
       -Z  or  --set-utc
           Set the modification and access times of patched  files  from  time
           stamps  given  in  context  diff headers, assuming that the context
           diff headers use Coordinated Universal Time (UTC,  often  known  as
           GMT).  Also see the "-T" or "--set-time" option.

           The  "-Z"  or "--set-utc" and "-T" or "--set-time" options normally
           refrain from setting a file's time if the file's original time does
           not match the time given in the patch header, or if its contents do
           not match the patch exactly.  However, if  the  "-f"  or  "--force"
           option is given, the file time is set regardless.

           Due to the limitations of bk diff output format, these options can-
           not  update  the  times  of  files whose contents have not changed.
           Also, if you use  these  options,  you  should  remove  (e.g.  with
           "make clean")  all  files that depend on the patched files, so that
           later invocations of make do not get confused by the patched files'
           times.

ENVIRONMENT
       PATCH_GET
           This specifies whether bk patch gets  missing  or  read-only  files
           from  RCS,  ClearCase,  or SCCS by default; see the "-g" or "--get"
           option.
       POSIXLY_CORRECT
           If set, bk patch conforms more strictly to the  POSIX  standard  by
           default: see the "--posix" option.
       QUOTING_STYLE
           Default value of the "--quoting-style" option.
       SIMPLE_BACKUP_SUFFIX
           Extension to use for simple backup file names instead of ".orig".
       TMPDIR, TMP, TEMP
           Directory  to put temporary files in; bk patch uses the first envi-
           ronment variable in this list that is set.  If none  are  set,  the
           default is system-dependent; it is normally /tmp on Unix hosts.
       VERSION_CONTROL or PATCH_VERSION_CONTROL
           Selects  version control style; see the "-v" or "--version-control"
           option.

FILES
       $TMPDIR/p*
           temporary files
       /dev/tty
           controlling terminal; used to get answers to questions asked of the
           user

NOTES
       bk patch uses the GNU implementation of patch(1).

NOTES FOR PATCH SENDERS
       There are several things you should bear in mind if you are going to be
       sending out patches.

       Create your patch systematically.  A good method is the  command  where
       <old>  and <new> identify the old and new directories.  The names <old>
       and <new> should not contain any slashes.  The bk diff command's  head-
       ers  should  have  dates  and times in Universal Time using traditional
       Unix format, so that patch recipients can use the "-Z"  or  "--set-utc"
       option.  Here is an example command, using Bourne shell syntax:

          LC_ALL=C TZ=UTC0 diff -Naur gcc-2.7 gcc-2.8

       Tell  your  recipients  how  to  apply  the patch by telling them which
       directory to cd to, and which bk patch  options  to  use.   The  option
       string  "-Np1" is recommended.  Test your procedure by pretending to be
       a recipient and applying your patch to a copy of the original files.

       You can save people a lot of grief by keeping a patchlevel.h file which
       is patched to increment the patch level as the first diff in the  patch
       file  you  send  out.   If you put a Prereq: line in with the patch, it
       won't let them apply patches out of order without some warning.

       You can create a file by sending out a diff that compares /dev/null  or
       an empty file dated the Epoch (1970-01-01 00:00:00 UTC) to the file you
       want to create.  This only works if the file you want to create doesn't
       exist  already  in  the target directory.  Conversely, you can remove a
       file by sending out a context diff that compares the file to be deleted
       with an empty file dated the Epoch.  The file will be removed unless bk
       patch is conforming to POSIX and  the  "-E"  or  "--remove-empty-files"
       option  is  not given.  An easy way to generate patches that create and
       remove files is to use the "-N"  option  to  bk  diff  or  "--new-file"
       option.

       If the recipient is supposed to use the option, do not send output that
       looks like this:

          diff -Naur v2.0.29/prog/README prog/README
          --- v2.0.29/prog/README   Mon Mar 10 15:13:12 1997
          +++ prog/README   Mon Mar 17 14:58:22 1997

       because  the two file names have different numbers of slashes, and dif-
       ferent versions of patch interpret  the  file  names  differently.   To
       avoid confusion, send output that looks like this instead:

          diff -Naur v2.0.29/prog/README v2.0.30/prog/README
          --- v2.0.29/prog/README   Mon Mar 10 15:13:12 1997
          +++ v2.0.30/prog/README   Mon Mar 17 14:58:22 1997

       Avoid  sending patches that compare backup file names like README.orig,
       since this might confuse bk patch into patching a backup  file  instead
       of  the  real  file.   Instead, send patches that compare the same base
       file names in different directories, e.g. old/README and new/README.

       Take care not to send out reversed patches, since it makes people  won-
       der whether they already applied the patch.

       Try  not to have your patch modify derived files (e.g. the file config-
       ure where there is a line "configure: configure.in" in your  makefile),
       since the recipient should be able to regenerate the derived files any-
       way.  If you must send diffs of derived files, generate the diffs using
       UTC,  have  the recipients apply the patch with the "-Z" or "--set-utc"
       option, and have them remove any unpatched files that depend on patched
       files (e.g. with "make clean").

       While you may be able to get away with putting 582 diff  listings  into
       one  file, it may be wiser to group related patches into separate files
       in case something goes haywire.

DIAGNOSTICS
       Diagnostics generally indicate that bk patch couldn't parse your  patch
       file.

       If the "--verbose" option is given, the message "Hmm..." indicates that
       there  is  unprocessed  text  in  the  patch  file and that bk patch is
       attempting to intuit whether there is a patch in that text and, if  so,
       what kind of patch it is.

EXIT STATUS
       bk patch returns exit status

       0   if all hunks were applied successfully
       1   if some hunks could not be applied
       2   if a serious error occurred

       When  applying a set of patches in a loop it behooves you to check this
       exit status so you don't apply a later patch  to  a  partially  patched
       file.

CAVEATS
       Context  diffs  cannot  reliably  represent the creation or deletion of
       empty files, empty directories,  or  special  files  such  as  symbolic
       links.  Nor can they represent changes to file metadata like ownership,
       permissions, or whether one file is a hard link to another.  If changes
       like  these  are  also  required,  separate  instructions (e.g. a shell
       script) to accomplish them should accompany the patch.

       bk patch cannot tell if the line numbers are off in  an  ed(1)  script,
       and  can  detect bad line numbers in a normal diff only when it finds a
       change or deletion.  A context diff using fuzz factor 3  may  have  the
       same  problem.   Until  a  suitable interactive interface is added, you
       should probably do a context diff in these cases to see if the  changes
       made sense.  Of course, compiling without errors is a pretty good indi-
       cation that the patch worked, but not always.

       bk patch usually produces the correct results, even when it has to do a
       lot  of  guessing.   However,  the results are guaranteed to be correct
       only when the patch is applied to exactly the same version of the  file
       that the patch was generated from.

COMPATIBILITY ISSUES
       The  POSIX  standard  specifies  behavior that differs from traditional
       patch behavior.  You should be aware of these differences if  you  must
       interoperate  with patch versions 2.1 and earlier, which do not conform
       to POSIX.

       In traditional
           patch, the "-p" option's operand was optional, and a bare "-p"  was
           equivalent  to "-p0."  The "-p" option now requires an operand, and
           "-p 0" is now equivalent to "-p0".  For maximum compatibility,  use
           options like "-p0" and "-p1".

           Also,  traditional patch simply counted slashes when stripping path
           prefixes; bk patch counts pathname components.  That is, a sequence
           of one or more adjacent slashes now counts as a single slash.   For
           maximum  portability, avoid sending patches containing "//" in file
           names.
       In traditional
           patch, backups were enabled  by  default.   This  behavior  is  now
           enabled with the "-b" or "--backup" option.

           Conversely, in POSIX patch, backups are never made, even when there
           is  a  mismatch.   In  bk  patch, this behavior is enabled with the
           "--no-backup-if-mismatch" option, or by conforming  to  POSIX  with
           the  "--posix" option or by setting the POSIXLY_CORRECT environment
           variable.

           The option of traditional patch is equivalent to the options of  bk
           patch.
       Traditional
           patch  used  a  complicated (and incompletely documented) method to
           intuit the name of the file to be patched from  the  patch  header.
           This  method  did  not conform to POSIX, and had a few gotchas.  bk
           patch uses a different, equally complicated (but better documented)
           method that is optionally POSIX-conforming; we hope  it  has  fewer
           gotchas.   The  two methods are compatible if the file names in the
           context diff header and the Index: line  are  all  identical  after
           prefix-stripping.   Your  patch  is  normally  compatible  if  each
           header's file names all contain the same number of slashes.
       When traditional
           patch asked the user a question, it sent the question  to  standard
           error and looked for an answer from the first file in the following
           list   that  was  a  terminal:  standard  error,  standard  output,
           /dev/tty, and standard input.  Now  bk  patch  sends  questions  to
           standard  output and gets answers from /dev/tty.  Defaults for some
           answers have been changed so that bk patch never goes into an infi-
           nite loop when using default answers.
       Traditional
           patch exited with a status value that counted  the  number  of  bad
           hunks,  or  with  status 1 if there was real trouble.  Now bk patch
           exits with status 1 if some hunks failed, or with 2  if  there  was
           real trouble.
       Limit yourself to the following options when sending instructions
           meant to be executed by anyone running bk patch, traditional patch,
           or  a  patch that conforms to POSIX.  Spaces are significant in the
           following list, and operands are required.

              -c
              -e
              -l
              -n
              -N
              -R

BUGS
       Please report bugs via email to bug-gnu-utils@gnu.org.

       bk patch could be smarter about partial  matches,  excessively  deviant
       offsets and swapped code, but that would take an extra pass.

       If code has been duplicated (for instance with #ifdef OLDCODE ... #else
       ...  #endif),  bk patch is incapable of patching both versions, and, if
       it works at all, will likely patch the wrong one, and tell you that  it
       succeeded to boot.

       If  you  apply  a patch you've already applied, bk patch thinks it is a
       reversed patch, and offers to un-apply the patch.  This could  be  con-
       strued as a feature.

COPYING
       Copyright 1984, 1985, 1986, 1988 Larry Wall.
       Copyright  1989,  1990,  1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
       Free Software Foundation, Inc.

       Permission is granted to make and distribute verbatim  copies  of  this
       manual  provided  the  copyright  notice and this permission notice are
       preserved on all copies.

       Permission is granted to copy and distribute modified versions of  this
       manual  under  the  conditions  for verbatim copying, provided that the
       entire resulting derived work is distributed under the terms of a  per-
       mission notice identical to this one.

       Permission  is granted to copy and distribute translations of this man-
       ual into another language, under the above conditions for modified ver-
       sions, except that this permission notice may be included  in  transla-
       tions approved by the copyright holders instead of in the original Eng-
       lish.

AUTHORS
       Larry  Wall  wrote  the original version of patch.  Paul Eggert removed
       patch's arbitrary limits; added support for binary files, setting  file
       times,  and deleting files; and made it conform better to POSIX.  Other
       contributors include Wayne Davison,  who  added  unidiff  support,  and
       David MacKenzie, who added configuration and backup support.

SEE ALSO
       ed(1),

       Marshall  T. Rose and Einar A. Stefferud, Proposed Standard for Message
       Encapsulation,    Internet    RFC    934     <URL:ftp://ftp.isi.edu/in-
       notes/rfc934.txt> (1985-01).  bk help diff, bk help credits

CATEGORY
       Utility

GNU                               1998/03/21                    bk patch(none)
$
help://path
help://path.1
help://bk-path
help://bk-path.1
bk path(none)               BitKeeper User's Manual              bk path(none)

NAME
       bk path - show the path that BK uses for all subprocesses

SYNOPSIS
       bk path

DESCRIPTION
       Mainly  for  debugging,  bk path displays the $PATH that controls where
       BitKeeper will look for commands.

CATEGORY
       Utility

BitKeeper Inc                         1E1                        bk path(none)
$
help://pcre
help://pcre.1
help://bk-pcre
help://bk-pcre.1
PERLRETUT(1)           Perl Programmers Reference Guide           PERLRETUT(1)

NAME
       perlretut - Perl regular expressions tutorial

DESCRIPTION
       This page provides a basic tutorial on understanding, creating and
       using regular expressions in Perl.  It serves as a complement to the
       reference page on regular expressions perlre.  Regular expressions are
       an integral part of the "m//", "s///", "qr//" and "split" operators and
       so this tutorial also overlaps with "Regexp Quote-Like Operators" in
       perlop and "split" in perlfunc.

       Perl is widely renowned for excellence in text processing, and regular
       expressions are one of the big factors behind this fame.  Perl regular
       expressions display an efficiency and flexibility unknown in most other
       computer languages.  Mastering even the basics of regular expressions
       will allow you to manipulate text with surprising ease.

       What is a regular expression?  A regular expression is simply a string
       that describes a pattern.  Patterns are in common use these days;
       examples are the patterns typed into a search engine to find web pages
       and the patterns used to list files in a directory, e.g., "ls *.txt" or
       "dir *.*".  In Perl, the patterns described by regular expressions are
       used to search strings, extract desired parts of strings, and to do
       search and replace operations.

       Regular expressions have the undeserved reputation of being abstract
       and difficult to understand.  Regular expressions are constructed using
       simple concepts like conditionals and loops and are no more difficult
       to understand than the corresponding "if" conditionals and "while"
       loops in the Perl language itself.  In fact, the main challenge in
       learning regular expressions is just getting used to the terse notation
       used to express these concepts.

       This tutorial flattens the learning curve by discussing regular
       expression concepts, along with their notation, one at a time and with
       many examples.  The first part of the tutorial will progress from the
       simplest word searches to the basic regular expression concepts.  If
       you master the first part, you will have all the tools needed to solve
       about 98% of your needs.  The second part of the tutorial is for those
       comfortable with the basics and hungry for more power tools.  It
       discusses the more advanced regular expression operators and introduces
       the latest cutting-edge innovations.

       A note: to save time, 'regular expression' is often abbreviated as
       regexp or regex.  Regexp is a more natural abbreviation than regex, but
       is harder to pronounce.  The Perl pod documentation is evenly split on
       regexp vs regex; in Perl, there is more than one way to abbreviate it.
       We'll use regexp in this tutorial.

Part 1: The basics
   Simple word matching
       The simplest regexp is simply a word, or more generally, a string of
       characters.  A regexp consisting of a word matches any string that
       contains that word:

           "Hello World" =~ /World/;  # matches

       What is this Perl statement all about? "Hello World" is a simple
       double-quoted string.  "World" is the regular expression and the "//"
       enclosing "/World/" tells Perl to search a string for a match.  The
       operator "=~" associates the string with the regexp match and produces
       a true value if the regexp matched, or false if the regexp did not
       match.  In our case, "World" matches the second word in "Hello World",
       so the expression is true.  Expressions like this are useful in
       conditionals:

           if ("Hello World" =~ /World/) {
               print "It matches\n";
           }
           else {
               print "It doesn't match\n";
           }

       There are useful variations on this theme.  The sense of the match can
       be reversed by using the "!~" operator:

           if ("Hello World" !~ /World/) {
               print "It doesn't match\n";
           }
           else {
               print "It matches\n";
           }

       The literal string in the regexp can be replaced by a variable:

           $greeting = "World";
           if ("Hello World" =~ /$greeting/) {
               print "It matches\n";
           }
           else {
               print "It doesn't match\n";
           }

       If you're matching against the special default variable $_, the "$_ =~"
       part can be omitted:

           $_ = "Hello World";
           if (/World/) {
               print "It matches\n";
           }
           else {
               print "It doesn't match\n";
           }

       And finally, the "//" default delimiters for a match can be changed to
       arbitrary delimiters by putting an 'm' out front:

           "Hello World" =~ m!World!;   # matches, delimited by '!'
           "Hello World" =~ m{World};   # matches, note the matching '{}'
           "/usr/bin/perl" =~ m"/perl"; # matches after '/usr/bin',
                                        # '/' becomes an ordinary char

       "/World/", "m!World!", and "m{World}" all represent the same thing.
       When, e.g., the quote (""") is used as a delimiter, the forward slash
       '/' becomes an ordinary character and can be used in this regexp
       without trouble.

       Let's consider how different regexps would match "Hello World":

           "Hello World" =~ /world/;  # doesn't match
           "Hello World" =~ /o W/;    # matches
           "Hello World" =~ /oW/;     # doesn't match
           "Hello World" =~ /World /; # doesn't match

       The first regexp "world" doesn't match because regexps are case-
       sensitive.  The second regexp matches because the substring 'o W'
       occurs in the string "Hello World".  The space character ' ' is treated
       like any other character in a regexp and is needed to match in this
       case.  The lack of a space character is the reason the third regexp
       'oW' doesn't match.  The fourth regexp 'World ' doesn't match because
       there is a space at the end of the regexp, but not at the end of the
       string.  The lesson here is that regexps must match a part of the
       string exactly in order for the statement to be true.

       If a regexp matches in more than one place in the string, Perl will
       always match at the earliest possible point in the string:

           "Hello World" =~ /o/;       # matches 'o' in 'Hello'
           "That hat is red" =~ /hat/; # matches 'hat' in 'That'

       With respect to character matching, there are a few more points you
       need to know about.   First of all, not all characters can be used 'as
       is' in a match.  Some characters, called metacharacters, are reserved
       for use in regexp notation.  The metacharacters are

           {}[]()^$.|*+?\

       The significance of each of these will be explained in the rest of the
       tutorial, but for now, it is important only to know that a
       metacharacter can be matched by putting a backslash before it:

           "2+2=4" =~ /2+2/;    # doesn't match, + is a metacharacter
           "2+2=4" =~ /2\+2/;   # matches, \+ is treated like an ordinary +
           "The interval is [0,1)." =~ /[0,1)./     # is a syntax error!
           "The interval is [0,1)." =~ /\[0,1\)\./  # matches
           "#!/usr/bin/perl" =~ /#!\/usr\/bin\/perl/;  # matches

       In the last regexp, the forward slash '/' is also backslashed, because
       it is used to delimit the regexp.  This can lead to LTS (leaning
       toothpick syndrome), however, and it is often more readable to change
       delimiters.

           "#!/usr/bin/perl" =~ m!#\!/usr/bin/perl!;  # easier to read

       The backslash character '\' is a metacharacter itself and needs to be
       backslashed:

           'C:\WIN32' =~ /C:\\WIN/;   # matches

       In addition to the metacharacters, there are some ASCII characters
       which don't have printable character equivalents and are instead
       represented by escape sequences.  Common examples are "\t" for a tab,
       "\n" for a newline, "\r" for a carriage return and "\a" for a bell (or
       alert).  If your string is better thought of as a sequence of arbitrary
       bytes, the octal escape sequence, e.g., "\033", or hexadecimal escape
       sequence, e.g., "\x1B" may be a more natural representation for your
       bytes.  Here are some examples of escapes:

           "1000\t2000" =~ m(0\t2)   # matches
           "1000\n2000" =~ /0\n20/   # matches
           "1000\t2000" =~ /\000\t2/ # doesn't match, "0" ne "\000"
           "cat"   =~ /\o{143}\x61\x74/ # matches in ASCII, but a weird way
                                        # to spell cat

       If you've been around Perl a while, all this talk of escape sequences
       may seem familiar.  Similar escape sequences are used in double-quoted
       strings and in fact the regexps in Perl are mostly treated as double-
       quoted strings.  This means that variables can be used in regexps as
       well.  Just like double-quoted strings, the values of the variables in
       the regexp will be substituted in before the regexp is evaluated for
       matching purposes.  So we have:

           $foo = 'house';
           'housecat' =~ /$foo/;      # matches
           'cathouse' =~ /cat$foo/;   # matches
           'housecat' =~ /${foo}cat/; # matches

       So far, so good.  With the knowledge above you can already perform
       searches with just about any literal string regexp you can dream up.
       Here is a very simple emulation of the Unix grep program:

           % cat > simple_grep
           #!/usr/bin/perl
           $regexp = shift;
           while (<>) {
               print if /$regexp/;
           }
           ^D

           % chmod +x simple_grep

           % simple_grep abba /usr/dict/words
           Babbage
           cabbage
           cabbages
           sabbath
           Sabbathize
           Sabbathizes
           sabbatical
           scabbard
           scabbards

       This program is easy to understand.  "#!/usr/bin/perl" is the standard
       way to invoke a perl program from the shell.  "$regexp = shift;" saves
       the first command line argument as the regexp to be used, leaving the
       rest of the command line arguments to be treated as files.
       "while (<>)" loops over all the lines in all the files.  For each line,
       "print if /$regexp/;" prints the line if the regexp matches the line.
       In this line, both "print" and "/$regexp/" use the default variable $_
       implicitly.

       With all of the regexps above, if the regexp matched anywhere in the
       string, it was considered a match.  Sometimes, however, we'd like to
       specify where in the string the regexp should try to match.  To do
       this, we would use the anchor metacharacters "^" and "$".  The anchor
       "^" means match at the beginning of the string and the anchor "$" means
       match at the end of the string, or before a newline at the end of the
       string.  Here is how they are used:

           "housekeeper" =~ /keeper/;    # matches
           "housekeeper" =~ /^keeper/;   # doesn't match
           "housekeeper" =~ /keeper$/;   # matches
           "housekeeper\n" =~ /keeper$/; # matches

       The second regexp doesn't match because "^" constrains "keeper" to
       match only at the beginning of the string, but "housekeeper" has keeper
       starting in the middle.  The third regexp does match, since the "$"
       constrains "keeper" to match only at the end of the string.

       When both "^" and "$" are used at the same time, the regexp has to
       match both the beginning and the end of the string, i.e., the regexp
       matches the whole string.  Consider

           "keeper" =~ /^keep$/;      # doesn't match
           "keeper" =~ /^keeper$/;    # matches
           ""       =~ /^$/;          # ^$ matches an empty string

       The first regexp doesn't match because the string has more to it than
       "keep".  Since the second regexp is exactly the string, it matches.
       Using both "^" and "$" in a regexp forces the complete string to match,
       so it gives you complete control over which strings match and which
       don't.  Suppose you are looking for a fellow named bert, off in a
       string by himself:

           "dogbert" =~ /bert/;   # matches, but not what you want

           "dilbert" =~ /^bert/;  # doesn't match, but ..
           "bertram" =~ /^bert/;  # matches, so still not good enough

           "bertram" =~ /^bert$/; # doesn't match, good
           "dilbert" =~ /^bert$/; # doesn't match, good
           "bert"    =~ /^bert$/; # matches, perfect

       Of course, in the case of a literal string, one could just as easily
       use the string comparison "$string eq 'bert'" and it would be more
       efficient.   The  "^...$" regexp really becomes useful when we add in
       the more powerful regexp tools below.

   Using character classes
       Although one can already do quite a lot with the literal string regexps
       above, we've only scratched the surface of regular expression
       technology.  In this and subsequent sections we will introduce regexp
       concepts (and associated metacharacter notations) that will allow a
       regexp to represent not just a single character sequence, but a whole
       class of them.

       One such concept is that of a character class.  A character class
       allows a set of possible characters, rather than just a single
       character, to match at a particular point in a regexp.  Character
       classes are denoted by brackets "[...]", with the set of characters to
       be possibly matched inside.  Here are some examples:

           /cat/;       # matches 'cat'
           /[bcr]at/;   # matches 'bat, 'cat', or 'rat'
           /item[0123456789]/;  # matches 'item0' or ... or 'item9'
           "abc" =~ /[cab]/;    # matches 'a'

       In the last statement, even though 'c' is the first character in the
       class, 'a' matches because the first character position in the string
       is the earliest point at which the regexp can match.

           /[yY][eE][sS]/;      # match 'yes' in a case-insensitive way
                                # 'yes', 'Yes', 'YES', etc.

       This regexp displays a common task: perform a case-insensitive match.
       Perl provides a way of avoiding all those brackets by simply appending
       an 'i' to the end of the match.  Then "/[yY][eE][sS]/;" can be
       rewritten as "/yes/i;".  The 'i' stands for case-insensitive and is an
       example of a modifier of the matching operation.  We will meet other
       modifiers later in the tutorial.

       We saw in the section above that there were ordinary characters, which
       represented themselves, and special characters, which needed a
       backslash "\" to represent themselves.  The same is true in a character
       class, but the sets of ordinary and special characters inside a
       character class are different than those outside a character class.
       The special characters for a character class are "-]\^$" (and the
       pattern delimiter, whatever it is).  "]" is special because it denotes
       the end of a character class.  "$" is special because it denotes a
       scalar variable.  "\" is special because it is used in escape
       sequences, just like above.  Here is how the special characters "]$\"
       are handled:

          /[\]c]def/; # matches ']def' or 'cdef'
          $x = 'bcr';
          /[$x]at/;   # matches 'bat', 'cat', or 'rat'
          /[\$x]at/;  # matches '$at' or 'xat'
          /[\\$x]at/; # matches '\at', 'bat, 'cat', or 'rat'

       The last two are a little tricky.  In "[\$x]", the backslash protects
       the dollar sign, so the character class has two members "$" and "x".
       In "[\\$x]", the backslash is protected, so $x is treated as a variable
       and substituted in double quote fashion.

       The special character '-' acts as a range operator within character
       classes, so that a contiguous set of characters can be written as a
       range.  With ranges, the unwieldy "[0123456789]" and "[abc...xyz]"
       become the svelte "[0-9]" and "[a-z]".  Some examples are

           /item[0-9]/;  # matches 'item0' or ... or 'item9'
           /[0-9bx-z]aa/;  # matches '0aa', ..., '9aa',
                           # 'baa', 'xaa', 'yaa', or 'zaa'
           /[0-9a-fA-F]/;  # matches a hexadecimal digit
           /[0-9a-zA-Z_]/; # matches a "word" character,
                           # like those in a Perl variable name

       If '-' is the first or last character in a character class, it is
       treated as an ordinary character; "[-ab]", "[ab-]" and "[a\-b]" are all
       equivalent.

       The special character "^" in the first position of a character class
       denotes a negated character class, which matches any character but
       those in the brackets.  Both "[...]" and "[^...]" must match a
       character, or the match fails.  Then

           /[^a]at/;  # doesn't match 'aat' or 'at', but matches
                      # all other 'bat', 'cat, '0at', '%at', etc.
           /[^0-9]/;  # matches a non-numeric character
           /[a^]at/;  # matches 'aat' or '^at'; here '^' is ordinary

       Now, even "[0-9]" can be a bother to write multiple times, so in the
       interest of saving keystrokes and making regexps more readable, Perl
       has several abbreviations for common character classes, as shown below.
       Since the introduction of Unicode, unless the "//a" modifier is in
       effect, these character classes match more than just a few characters
       in the ASCII range.

       +o   \d matches a digit, not just [0-9] but also digits from non-roman
           scripts

       +o   \s matches a whitespace character, the set [\ \t\r\n\f] and others

       +o   \w matches a word character (alphanumeric or _), not just
           [0-9a-zA-Z_] but also digits and characters from non-roman scripts

       +o   \D is a negated \d; it represents any other character than a digit,
           or [^\d]

       +o   \S is a negated \s; it represents any non-whitespace character
           [^\s]

       +o   \W is a negated \w; it represents any non-word character [^\w]

       +o   The period '.' matches any character but "\n" (unless the modifier
           "//s" is in effect, as explained below).

       +o   \N, like the period, matches any character but "\n", but it does so
           regardless of whether the modifier "//s" is in effect.

       The "//a" modifier, available starting in Perl 5.14,  is used to
       restrict the matches of \d, \s, and \w to just those in the ASCII
       range.  It is useful to keep your program from being needlessly exposed
       to full Unicode (and its accompanying security considerations) when all
       you want is to process English-like text.  (The "a" may be doubled,
       "//aa", to provide even more restrictions, preventing case-insensitive
       matching of ASCII with non-ASCII characters; otherwise a Unicode
       "Kelvin Sign" would caselessly match a "k" or "K".)

       The "\d\s\w\D\S\W" abbreviations can be used both inside and outside of
       character classes.  Here are some in use:

           /\d\d:\d\d:\d\d/; # matches a hh:mm:ss time format
           /[\d\s]/;         # matches any digit or whitespace character
           /\w\W\w/;         # matches a word char, followed by a
                             # non-word char, followed by a word char
           /..rt/;           # matches any two chars, followed by 'rt'
           /end\./;          # matches 'end.'
           /end[.]/;         # same thing, matches 'end.'

       Because a period is a metacharacter, it needs to be escaped to match as
       an ordinary period. Because, for example, "\d" and "\w" are sets of
       characters, it is incorrect to think of "[^\d\w]" as "[\D\W]"; in fact
       "[^\d\w]" is the same as "[^\w]", which is the same as "[\W]". Think
       DeMorgan's laws.

       An anchor useful in basic regexps is the word anchor "\b".  This
       matches a boundary between a word character and a non-word character
       "\w\W" or "\W\w":

           $x = "Housecat catenates house and cat";
           $x =~ /cat/;    # matches cat in 'housecat'
           $x =~ /\bcat/;  # matches cat in 'catenates'
           $x =~ /cat\b/;  # matches cat in 'housecat'
           $x =~ /\bcat\b/;  # matches 'cat' at end of string

       Note in the last example, the end of the string is considered a word
       boundary.

       You might wonder why '.' matches everything but "\n" - why not every
       character? The reason is that often one is matching against lines and
       would like to ignore the newline characters.  For instance, while the
       string "\n" represents one line, we would like to think of it as empty.
       Then

           ""   =~ /^$/;    # matches
           "\n" =~ /^$/;    # matches, $ anchors before "\n"

           ""   =~ /./;      # doesn't match; it needs a char
           ""   =~ /^.$/;    # doesn't match; it needs a char
           "\n" =~ /^.$/;    # doesn't match; it needs a char other than "\n"
           "a"  =~ /^.$/;    # matches
           "a\n"  =~ /^.$/;  # matches, $ anchors before "\n"

       This behavior is convenient, because we usually want to ignore newlines
       when we count and match characters in a line.  Sometimes, however, we
       want to keep track of newlines.  We might even want "^" and "$" to
       anchor at the beginning and end of lines within the string, rather than
       just the beginning and end of the string.  Perl allows us to choose
       between ignoring and paying attention to newlines by using the "//s"
       and "//m" modifiers.  "//s" and "//m" stand for single line and multi-
       line and they determine whether a string is to be treated as one
       continuous string, or as a set of lines.  The two modifiers affect two
       aspects of how the regexp is interpreted: 1) how the '.' character
       class is defined, and 2) where the anchors "^" and "$" are able to
       match.  Here are the four possible combinations:

       +o   no modifiers (//): Default behavior.  '.' matches any character
           except "\n".  "^" matches only at the beginning of the string and
           "$" matches only at the end or before a newline at the end.

       +o   s modifier (//s): Treat string as a single long line.  '.' matches
           any character, even "\n".  "^" matches only at the beginning of the
           string and "$" matches only at the end or before a newline at the
           end.

       +o   m modifier (//m): Treat string as a set of multiple lines.  '.'
           matches any character except "\n".  "^" and "$" are able to match
           at the start or end of any line within the string.

       +o   both s and m modifiers (//sm): Treat string as a single long line,
           but detect multiple lines.  '.' matches any character, even "\n".
           "^" and "$", however, are able to match at the start or end of any
           line within the string.

       Here are examples of "//s" and "//m" in action:

           $x = "There once was a girl\nWho programmed in Perl\n";

           $x =~ /^Who/;   # doesn't match, "Who" not at start of string
           $x =~ /^Who/s;  # doesn't match, "Who" not at start of string
           $x =~ /^Who/m;  # matches, "Who" at start of second line
           $x =~ /^Who/sm; # matches, "Who" at start of second line

           $x =~ /girl.Who/;   # doesn't match, "." doesn't match "\n"
           $x =~ /girl.Who/s;  # matches, "." matches "\n"
           $x =~ /girl.Who/m;  # doesn't match, "." doesn't match "\n"
           $x =~ /girl.Who/sm; # matches, "." matches "\n"

       Most of the time, the default behavior is what is wanted, but "//s" and
       "//m" are occasionally very useful.  If "//m" is being used, the start
       of the string can still be matched with "\A" and the end of the string
       can still be matched with the anchors "\Z" (matches both the end and
       the newline before, like "$"), and "\z" (matches only the end):

           $x =~ /^Who/m;   # matches, "Who" at start of second line
           $x =~ /\AWho/m;  # doesn't match, "Who" is not at start of string

           $x =~ /girl$/m;  # matches, "girl" at end of first line
           $x =~ /girl\Z/m; # doesn't match, "girl" is not at end of string

           $x =~ /Perl\Z/m; # matches, "Perl" is at newline before end
           $x =~ /Perl\z/m; # doesn't match, "Perl" is not at end of string

       We now know how to create choices among classes of characters in a
       regexp.  What about choices among words or character strings? Such
       choices are described in the next section.

   Matching this or that
       Sometimes we would like our regexp to be able to match different
       possible words or character strings.  This is accomplished by using the
       alternation metacharacter "|".  To match "dog" or "cat", we form the
       regexp "dog|cat".  As before, Perl will try to match the regexp at the
       earliest possible point in the string.  At each character position,
       Perl will first try to match the first alternative, "dog".  If "dog"
       doesn't match, Perl will then try the next alternative, "cat".  If
       "cat" doesn't match either, then the match fails and Perl moves to the
       next position in the string.  Some examples:

           "cats and dogs" =~ /cat|dog|bird/;  # matches "cat"
           "cats and dogs" =~ /dog|cat|bird/;  # matches "cat"

       Even though "dog" is the first alternative in the second regexp, "cat"
       is able to match earlier in the string.

           "cats"          =~ /c|ca|cat|cats/; # matches "c"
           "cats"          =~ /cats|cat|ca|c/; # matches "cats"

       Here, all the alternatives match at the first string position, so the
       first alternative is the one that matches.  If some of the alternatives
       are truncations of the others, put the longest ones first to give them
       a chance to match.

           "cab" =~ /a|b|c/ # matches "c"
                            # /a|b|c/ == /[abc]/

       The last example points out that character classes are like
       alternations of characters.  At a given character position, the first
       alternative that allows the regexp match to succeed will be the one
       that matches.

   Grouping things and hierarchical matching
       Alternation allows a regexp to choose among alternatives, but by itself
       it is unsatisfying.  The reason is that each alternative is a whole
       regexp, but sometime we want alternatives for just part of a regexp.
       For instance, suppose we want to search for housecats or housekeepers.
       The regexp "housecat|housekeeper" fits the bill, but is inefficient
       because we had to type "house" twice.  It would be nice to have parts
       of the regexp be constant, like "house", and some parts have
       alternatives, like "cat|keeper".

       The grouping metacharacters "()" solve this problem.  Grouping allows
       parts of a regexp to be treated as a single unit.  Parts of a regexp
       are grouped by enclosing them in parentheses.  Thus we could solve the
       "housecat|housekeeper" by forming the regexp as "house(cat|keeper)".
       The regexp "house(cat|keeper)" means match "house" followed by either
       "cat" or "keeper".  Some more examples are

           /(a|b)b/;    # matches 'ab' or 'bb'
           /(ac|b)b/;   # matches 'acb' or 'bb'
           /(^a|b)c/;   # matches 'ac' at start of string or 'bc' anywhere
           /(a|[bc])d/; # matches 'ad', 'bd', or 'cd'

           /house(cat|)/;  # matches either 'housecat' or 'house'
           /house(cat(s|)|)/;  # matches either 'housecats' or 'housecat' or
                               # 'house'.  Note groups can be nested.

           /(19|20|)\d\d/;  # match years 19xx, 20xx, or the Y2K problem, xx
           "20" =~ /(19|20|)\d\d/;  # matches the null alternative '()\d\d',
                                    # because '20\d\d' can't match

       Alternations behave the same way in groups as out of them: at a given
       string position, the leftmost alternative that allows the regexp to
       match is taken.  So in the last example at the first string position,
       "20" matches the second alternative, but there is nothing left over to
       match the next two digits "\d\d".  So Perl moves on to the next
       alternative, which is the null alternative and that works, since "20"
       is two digits.

       The process of trying one alternative, seeing if it matches, and moving
       on to the next alternative, while going back in the string from where
       the previous alternative was tried, if it doesn't, is called
       backtracking.  The term 'backtracking' comes from the idea that
       matching a regexp is like a walk in the woods.  Successfully matching a
       regexp is like arriving at a destination.  There are many possible
       trailheads, one for each string position, and each one is tried in
       order, left to right.  From each trailhead there may be many paths,
       some of which get you there, and some which are dead ends.  When you
       walk along a trail and hit a dead end, you have to backtrack along the
       trail to an earlier point to try another trail.  If you hit your
       destination, you stop immediately and forget about trying all the other
       trails.  You are persistent, and only if you have tried all the trails
       from all the trailheads and not arrived at your destination, do you
       declare failure.  To be concrete, here is a step-by-step analysis of
       what Perl does when it tries to match the regexp

           "abcde" =~ /(abd|abc)(df|d|de)/;

       0   Start with the first letter in the string 'a'.

       1   Try the first alternative in the first group 'abd'.

       2   Match 'a' followed by 'b'. So far so good.

       3   'd' in the regexp doesn't match 'c' in the string - a dead end.  So
           backtrack two characters and pick the second alternative in the
           first group 'abc'.

       4   Match 'a' followed by 'b' followed by 'c'.  We are on a roll and
           have satisfied the first group. Set $1 to 'abc'.

       5   Move on to the second group and pick the first alternative 'df'.

       6   Match the 'd'.

       7   'f' in the regexp doesn't match 'e' in the string, so a dead end.
           Backtrack one character and pick the second alternative in the
           second group 'd'.

       8   'd' matches. The second grouping is satisfied, so set $2 to 'd'.

       9   We are at the end of the regexp, so we are done! We have matched
           'abcd' out of the string "abcde".

       There are a couple of things to note about this analysis.  First, the
       third alternative in the second group 'de' also allows a match, but we
       stopped before we got to it - at a given character position, leftmost
       wins.  Second, we were able to get a match at the first character
       position of the string 'a'.  If there were no matches at the first
       position, Perl would move to the second character position 'b' and
       attempt the match all over again.  Only when all possible paths at all
       possible character positions have been exhausted does Perl give up and
       declare "$string =~ /(abd|abc)(df|d|de)/;" to be false.

       Even with all this work, regexp matching happens remarkably fast.  To
       speed things up, Perl compiles the regexp into a compact sequence of
       opcodes that can often fit inside a processor cache.  When the code is
       executed, these opcodes can then run at full throttle and search very
       quickly.

   Extracting matches
       The grouping metacharacters "()" also serve another completely
       different function: they allow the extraction of the parts of a string
       that matched.  This is very useful to find out what matched and for
       text processing in general.  For each grouping, the part that matched
       inside goes into the special variables $1, $2, etc.  They can be used
       just as ordinary variables:

           # extract hours, minutes, seconds
           if ($time =~ /(\d\d):(\d\d):(\d\d)/) {    # match hh:mm:ss format
               $hours = $1;
               $minutes = $2;
               $seconds = $3;
           }

       Now, we know that in scalar context, "$time =~ /(\d\d):(\d\d):(\d\d)/"
       returns a true or false value.  In list context, however, it returns
       the list of matched values "($1,$2,$3)".  So we could write the code
       more compactly as

           # extract hours, minutes, seconds
           ($hours, $minutes, $second) = ($time =~ /(\d\d):(\d\d):(\d\d)/);

       If the groupings in a regexp are nested, $1 gets the group with the
       leftmost opening parenthesis, $2 the next opening parenthesis, etc.
       Here is a regexp with nested groups:

           /(ab(cd|ef)((gi)|j))/;
            1  2      34

       If this regexp matches, $1 contains a string starting with 'ab', $2 is
       either set to 'cd' or 'ef', $3 equals either 'gi' or 'j', and $4 is
       either set to 'gi', just like $3, or it remains undefined.

       For convenience, Perl sets $+ to the string held by the highest
       numbered $1, $2,... that got assigned (and, somewhat related, $^N to
       the value of the $1, $2,... most-recently assigned; i.e. the $1, $2,...
       associated with the rightmost closing parenthesis used in the match).

   Backreferences
       Closely associated with the matching variables $1, $2, ... are the
       backreferences "\g1", "\g2",...  Backreferences are simply matching
       variables that can be used inside a regexp.  This is a really nice
       feature; what matches later in a regexp is made to depend on what
       matched earlier in the regexp.  Suppose we wanted to look for doubled
       words in a text, like 'the the'.  The following regexp finds all
       3-letter doubles with a space in between:

           /\b(\w\w\w)\s\g1\b/;

       The grouping assigns a value to \g1, so that the same 3-letter sequence
       is used for both parts.

       A similar task is to find words consisting of two identical parts:

           % simple_grep '^(\w\w\w\w|\w\w\w|\w\w|\w)\g1$' /usr/dict/words
           beriberi
           booboo
           coco
           mama
           murmur
           papa

       The regexp has a single grouping which considers 4-letter combinations,
       then 3-letter combinations, etc., and uses "\g1" to look for a repeat.
       Although $1 and "\g1" represent the same thing, care should be taken to
       use matched variables $1, $2,... only outside a regexp and
       backreferences "\g1", "\g2",... only inside a regexp; not doing so may
       lead to surprising and unsatisfactory results.

   Relative backreferences
       Counting the opening parentheses to get the correct number for a
       backreference is error-prone as soon as there is more than one
       capturing group.  A more convenient technique became available with
       Perl 5.10: relative backreferences. To refer to the immediately
       preceding capture group one now may write "\g{-1}", the next but last
       is available via "\g{-2}", and so on.

       Another good reason in addition to readability and maintainability for
       using relative backreferences is illustrated by the following example,
       where a simple pattern for matching peculiar strings is used:

           $a99a = '([a-z])(\d)\g2\g1';   # matches a11a, g22g, x33x, etc.

       Now that we have this pattern stored as a handy string, we might feel
       tempted to use it as a part of some other pattern:

           $line = "code=e99e";
           if ($line =~ /^(\w+)=$a99a$/){   # unexpected behavior!
               print "$1 is valid\n";
           } else {
               print "bad line: '$line'\n";
           }

       But this doesn't match, at least not the way one might expect. Only
       after inserting the interpolated $a99a and looking at the resulting
       full text of the regexp is it obvious that the backreferences have
       backfired. The subexpression "(\w+)" has snatched number 1 and demoted
       the groups in $a99a by one rank. This can be avoided by using relative
       backreferences:

           $a99a = '([a-z])(\d)\g{-1}\g{-2}';  # safe for being interpolated

   Named backreferences
       Perl 5.10 also introduced named capture groups and named
       backreferences.  To attach a name to a capturing group, you write
       either "(?<name>...)" or "(?'name'...)".  The backreference may then be
       written as "\g{name}".  It is permissible to attach the same name to
       more than one group, but then only the leftmost one of the eponymous
       set can be referenced.  Outside of the pattern a named capture group is
       accessible through the "%+" hash.

       Assuming that we have to match calendar dates which may be given in one
       of the three formats yyyy-mm-dd, mm/dd/yyyy or dd.mm.yyyy, we can write
       three suitable patterns where we use 'd', 'm' and 'y' respectively as
       the names of the groups capturing the pertaining components of a date.
       The matching operation combines the three patterns as alternatives:

           $fmt1 = '(?<y>\d\d\d\d)-(?<m>\d\d)-(?<d>\d\d)';
           $fmt2 = '(?<m>\d\d)/(?<d>\d\d)/(?<y>\d\d\d\d)';
           $fmt3 = '(?<d>\d\d)\.(?<m>\d\d)\.(?<y>\d\d\d\d)';
           for my $d qw( 2006-10-21 15.01.2007 10/31/2005 ){
               if ( $d =~ m{$fmt1|$fmt2|$fmt3} ){
                   print "day=$+{d} month=$+{m} year=$+{y}\n";
               }
           }

       If any of the alternatives matches, the hash "%+" is bound to contain
       the three key-value pairs.

   Alternative capture group numbering
       Yet another capturing group numbering technique (also as from Perl
       5.10) deals with the problem of referring to groups within a set of
       alternatives.  Consider a pattern for matching a time of the day, civil
       or military style:

           if ( $time =~ /(\d\d|\d):(\d\d)|(\d\d)(\d\d)/ ){
               # process hour and minute
           }

       Processing the results requires an additional if statement to determine
       whether $1 and $2 or $3 and $4 contain the goodies. It would be easier
       if we could use group numbers 1 and 2 in second alternative as well,
       and this is exactly what the parenthesized construct "(?|...)", set
       around an alternative achieves. Here is an extended version of the
       previous pattern:

           if ( $time =~ /(?|(\d\d|\d):(\d\d)|(\d\d)(\d\d))\s+([A-Z][A-Z][A-Z])/ ){
               print "hour=$1 minute=$2 zone=$3\n";
           }

       Within the alternative numbering group, group numbers start at the same
       position for each alternative. After the group, numbering continues
       with one higher than the maximum reached across all the alternatives.

   Position information
       In addition to what was matched, Perl (since 5.6.0) also provides the
       positions of what was matched as contents of the "@-" and "@+" arrays.
       "$-[0]" is the position of the start of the entire match and $+[0] is
       the position of the end. Similarly, "$-[n]" is the position of the
       start of the $n match and $+[n] is the position of the end. If $n is
       undefined, so are "$-[n]" and $+[n]. Then this code

           $x = "Mmm...donut, thought Homer";
           $x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/; # matches
           foreach $expr (1..$#-) {
               print "Match $expr: '${$expr}' at position ($-[$expr],$+[$expr])\n";
           }

       prints

           Match 1: 'Mmm' at position (0,3)
           Match 2: 'donut' at position (6,11)

       Even if there are no groupings in a regexp, it is still possible to
       find out what exactly matched in a string.  If you use them, Perl will
       set "$`" to the part of the string before the match, will set $& to the
       part of the string that matched, and will set "$'" to the part of the
       string after the match.  An example:

           $x = "the cat caught the mouse";
           $x =~ /cat/;  # $` = 'the ', $& = 'cat', $' = ' caught the mouse'
           $x =~ /the/;  # $` = '', $& = 'the', $' = ' cat caught the mouse'

       In the second match, "$`" equals '' because the regexp matched at the
       first character position in the string and stopped; it never saw the
       second 'the'.  It is important to note that using "$`" and "$'" slows
       down regexp matching quite a bit, while $& slows it down to a lesser
       extent, because if they are used in one regexp in a program, they are
       generated for all regexps in the program.  So if raw performance is a
       goal of your application, they should be avoided.  If you need to
       extract the corresponding substrings, use "@-" and "@+" instead:

           $` is the same as substr( $x, 0, $-[0] )
           $& is the same as substr( $x, $-[0], $+[0]-$-[0] )
           $' is the same as substr( $x, $+[0] )

       As of Perl 5.10, the "${^PREMATCH}", "${^MATCH}" and "${^POSTMATCH}"
       variables may be used. These are only set if the "/p" modifier is
       present.  Consequently they do not penalize the rest of the program.

   Non-capturing groupings
       A group that is required to bundle a set of alternatives may or may not
       be useful as a capturing group.  If it isn't, it just creates a
       superfluous addition to the set of available capture group values,
       inside as well as outside the regexp.  Non-capturing groupings, denoted
       by "(?:regexp)", still allow the regexp to be treated as a single unit,
       but don't establish a capturing group at the same time.  Both capturing
       and non-capturing groupings are allowed to co-exist in the same regexp.
       Because there is no extraction, non-capturing groupings are faster than
       capturing groupings.  Non-capturing groupings are also handy for
       choosing exactly which parts of a regexp are to be extracted to
       matching variables:

           # match a number, $1-$4 are set, but we only want $1
           /([+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)/;

           # match a number faster , only $1 is set
           /([+-]?\ *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?)/;

           # match a number, get $1 = whole number, $2 = exponent
           /([+-]?\ *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE]([+-]?\d+))?)/;

       Non-capturing groupings are also useful for removing nuisance elements
       gathered from a split operation where parentheses are required for some
       reason:

           $x = '12aba34ba5';
           @num = split /(a|b)+/, $x;    # @num = ('12','a','34','a','5')
           @num = split /(?:a|b)+/, $x;  # @num = ('12','34','5')

   Matching repetitions
       The examples in the previous section display an annoying weakness.  We
       were only matching 3-letter words, or chunks of words of 4 letters or
       less.  We'd like to be able to match words or, more generally, strings
       of any length, without writing out tedious alternatives like
       "\w\w\w\w|\w\w\w|\w\w|\w".

       This is exactly the problem the quantifier metacharacters "?", "*",
       "+", and "{}" were created for.  They allow us to delimit the number of
       repeats for a portion of a regexp we consider to be a match.
       Quantifiers are put immediately after the character, character class,
       or grouping that we want to specify.  They have the following meanings:

       +o   "a?" means: match 'a' 1 or 0 times

       +o   "a*" means: match 'a' 0 or more times, i.e., any number of times

       +o   "a+" means: match 'a' 1 or more times, i.e., at least once

       +o   "a{n,m}" means: match at least "n" times, but not more than "m"
           times.

       +o   "a{n,}" means: match at least "n" or more times

       +o   "a{n}" means: match exactly "n" times

       Here are some examples:

           /[a-z]+\s+\d*/;  # match a lowercase word, at least one space, and
                            # any number of digits
           /(\w+)\s+\g1/;    # match doubled words of arbitrary length
           /y(es)?/i;       # matches 'y', 'Y', or a case-insensitive 'yes'
           $year =~ /^\d{2,4}$/;  # make sure year is at least 2 but not more
                                  # than 4 digits
           $year =~ /^\d{4}$|^\d{2}$/;    # better match; throw out 3-digit dates
           $year =~ /^\d{2}(\d{2})?$/;  # same thing written differently. However,
                                        # this captures the last two digits in $1
                                        # and the other does not.

           % simple_grep '^(\w+)\g1$' /usr/dict/words   # isn't this easier?
           beriberi
           booboo
           coco
           mama
           murmur
           papa

       For all of these quantifiers, Perl will try to match as much of the
       string as possible, while still allowing the regexp to succeed.  Thus
       with "/a?.../", Perl will first try to match the regexp with the "a"
       present; if that fails, Perl will try to match the regexp without the
       "a" present.  For the quantifier "*", we get the following:

           $x = "the cat in the hat";
           $x =~ /^(.*)(cat)(.*)$/; # matches,
                                    # $1 = 'the '
                                    # $2 = 'cat'
                                    # $3 = ' in the hat'

       Which is what we might expect, the match finds the only "cat" in the
       string and locks onto it.  Consider, however, this regexp:

           $x =~ /^(.*)(at)(.*)$/; # matches,
                                   # $1 = 'the cat in the h'
                                   # $2 = 'at'
                                   # $3 = ''   (0 characters match)

       One might initially guess that Perl would find the "at" in "cat" and
       stop there, but that wouldn't give the longest possible string to the
       first quantifier ".*".  Instead, the first quantifier ".*" grabs as
       much of the string as possible while still having the regexp match.  In
       this example, that means having the "at" sequence with the final "at"
       in the string.  The other important principle illustrated here is that,
       when there are two or more elements in a regexp, the leftmost
       quantifier, if there is one, gets to grab as much of the string as
       possible, leaving the rest of the regexp to fight over scraps.  Thus in
       our example, the first quantifier ".*" grabs most of the string, while
       the second quantifier ".*" gets the empty string.   Quantifiers that
       grab as much of the string as possible are called maximal match or
       greedy quantifiers.

       When a regexp can match a string in several different ways, we can use
       the principles above to predict which way the regexp will match:

       +o   Principle 0: Taken as a whole, any regexp will be matched at the
           earliest possible position in the string.

       +o   Principle 1: In an alternation "a|b|c...", the leftmost alternative
           that allows a match for the whole regexp will be the one used.

       +o   Principle 2: The maximal matching quantifiers "?", "*", "+" and
           "{n,m}" will in general match as much of the string as possible
           while still allowing the whole regexp to match.

       +o   Principle 3: If there are two or more elements in a regexp, the
           leftmost greedy quantifier, if any, will match as much of the
           string as possible while still allowing the whole regexp to match.
           The next leftmost greedy quantifier, if any, will try to match as
           much of the string remaining available to it as possible, while
           still allowing the whole regexp to match.  And so on, until all the
           regexp elements are satisfied.

       As we have seen above, Principle 0 overrides the others. The regexp
       will be matched as early as possible, with the other principles
       determining how the regexp matches at that earliest character position.

       Here is an example of these principles in action:

           $x = "The programming republic of Perl";
           $x =~ /^(.+)(e|r)(.*)$/;  # matches,
                                     # $1 = 'The programming republic of Pe'
                                     # $2 = 'r'
                                     # $3 = 'l'

       This regexp matches at the earliest string position, 'T'.  One might
       think that "e", being leftmost in the alternation, would be matched,
       but "r" produces the longest string in the first quantifier.

           $x =~ /(m{1,2})(.*)$/;  # matches,
                                   # $1 = 'mm'
                                   # $2 = 'ing republic of Perl'

       Here, The earliest possible match is at the first 'm' in "programming".
       "m{1,2}" is the first quantifier, so it gets to match a maximal "mm".

           $x =~ /.*(m{1,2})(.*)$/;  # matches,
                                     # $1 = 'm'
                                     # $2 = 'ing republic of Perl'

       Here, the regexp matches at the start of the string. The first
       quantifier ".*" grabs as much as possible, leaving just a single 'm'
       for the second quantifier "m{1,2}".

           $x =~ /(.?)(m{1,2})(.*)$/;  # matches,
                                       # $1 = 'a'
                                       # $2 = 'mm'
                                       # $3 = 'ing republic of Perl'

       Here, ".?" eats its maximal one character at the earliest possible
       position in the string, 'a' in "programming", leaving "m{1,2}" the
       opportunity to match both "m"'s. Finally,

           "aXXXb" =~ /(X*)/; # matches with $1 = ''

       because it can match zero copies of 'X' at the beginning of the string.
       If you definitely want to match at least one 'X', use "X+", not "X*".

       Sometimes greed is not good.  At times, we would like quantifiers to
       match a minimal piece of string, rather than a maximal piece.  For this
       purpose, Larry Wall created the minimal match or non-greedy quantifiers
       "??", "*?", "+?", and "{}?".  These are the usual quantifiers with a
       "?" appended to them.  They have the following meanings:

       +o   "a??" means: match 'a' 0 or 1 times. Try 0 first, then 1.

       +o   "a*?" means: match 'a' 0 or more times, i.e., any number of times,
           but as few times as possible

       +o   "a+?" means: match 'a' 1 or more times, i.e., at least once, but as
           few times as possible

       +o   "a{n,m}?" means: match at least "n" times, not more than "m" times,
           as few times as possible

       +o   "a{n,}?" means: match at least "n" times, but as few times as
           possible

       +o   "a{n}?" means: match exactly "n" times.  Because we match exactly
           "n" times, "a{n}?" is equivalent to "a{n}" and is just there for
           notational consistency.

       Let's look at the example above, but with minimal quantifiers:

           $x = "The programming republic of Perl";
           $x =~ /^(.+?)(e|r)(.*)$/; # matches,
                                     # $1 = 'Th'
                                     # $2 = 'e'
                                     # $3 = ' programming republic of Perl'

       The minimal string that will allow both the start of the string "^" and
       the alternation to match is "Th", with the alternation "e|r" matching
       "e".  The second quantifier ".*" is free to gobble up the rest of the
       string.

           $x =~ /(m{1,2}?)(.*?)$/;  # matches,
                                     # $1 = 'm'
                                     # $2 = 'ming republic of Perl'

       The first string position that this regexp can match is at the first
       'm' in "programming". At this position, the minimal "m{1,2}?"  matches
       just one 'm'.  Although the second quantifier ".*?" would prefer to
       match no characters, it is constrained by the end-of-string anchor "$"
       to match the rest of the string.

           $x =~ /(.*?)(m{1,2}?)(.*)$/;  # matches,
                                         # $1 = 'The progra'
                                         # $2 = 'm'
                                         # $3 = 'ming republic of Perl'

       In this regexp, you might expect the first minimal quantifier ".*?"  to
       match the empty string, because it is not constrained by a "^" anchor
       to match the beginning of the word.  Principle 0 applies here, however.
       Because it is possible for the whole regexp to match at the start of
       the string, it will match at the start of the string.  Thus the first
       quantifier has to match everything up to the first "m".  The second
       minimal quantifier matches just one "m" and the third quantifier
       matches the rest of the string.

           $x =~ /(.??)(m{1,2})(.*)$/;  # matches,
                                        # $1 = 'a'
                                        # $2 = 'mm'
                                        # $3 = 'ing republic of Perl'

       Just as in the previous regexp, the first quantifier ".??" can match
       earliest at position 'a', so it does.  The second quantifier is greedy,
       so it matches "mm", and the third matches the rest of the string.

       We can modify principle 3 above to take into account non-greedy
       quantifiers:

       +o   Principle 3: If there are two or more elements in a regexp, the
           leftmost greedy (non-greedy) quantifier, if any, will match as much
           (little) of the string as possible while still allowing the whole
           regexp to match.  The next leftmost greedy (non-greedy) quantifier,
           if any, will try to match as much (little) of the string remaining
           available to it as possible, while still allowing the whole regexp
           to match.  And so on, until all the regexp elements are satisfied.

       Just like alternation, quantifiers are also susceptible to
       backtracking.  Here is a step-by-step analysis of the example

           $x = "the cat in the hat";
           $x =~ /^(.*)(at)(.*)$/; # matches,
                                   # $1 = 'the cat in the h'
                                   # $2 = 'at'
                                   # $3 = ''   (0 matches)

       0   Start with the first letter in the string 't'.

       1   The first quantifier '.*' starts out by matching the whole string
           'the cat in the hat'.

       2   'a' in the regexp element 'at' doesn't match the end of the string.
           Backtrack one character.

       3   'a' in the regexp element 'at' still doesn't match the last letter
           of the string 't', so backtrack one more character.

       4   Now we can match the 'a' and the 't'.

       5   Move on to the third element '.*'.  Since we are at the end of the
           string and '.*' can match 0 times, assign it the empty string.

       6   We are done!

       Most of the time, all this moving forward and backtracking happens
       quickly and searching is fast. There are some pathological regexps,
       however, whose execution time exponentially grows with the size of the
       string.  A typical structure that blows up in your face is of the form

           /(a|b+)*/;

       The problem is the nested indeterminate quantifiers.  There are many
       different ways of partitioning a string of length n between the "+" and
       "*": one repetition with "b+" of length n, two repetitions with the
       first "b+" length k and the second with length n-k, m repetitions whose
       bits add up to length n, etc.  In fact there are an exponential number
       of ways to partition a string as a function of its length.  A regexp
       may get lucky and match early in the process, but if there is no match,
       Perl will try every possibility before giving up.  So be careful with
       nested "*"'s, "{n,m}"'s, and "+"'s.  The book Mastering Regular
       Expressions by Jeffrey Friedl gives a wonderful discussion of this and
       other efficiency issues.

   Possessive quantifiers
       Backtracking during the relentless search for a match may be a waste of
       time, particularly when the match is bound to fail.  Consider the
       simple pattern

           /^\w+\s+\w+$/; # a word, spaces, a word

       Whenever this is applied to a string which doesn't quite meet the
       pattern's expectations such as "abc  " or "abc  def ", the regex engine
       will backtrack, approximately once for each character in the string.
       But we know that there is no way around taking all of the initial word
       characters to match the first repetition, that all spaces must be eaten
       by the middle part, and the same goes for the second word.

       With the introduction of the possessive quantifiers in Perl 5.10, we
       have a way of instructing the regex engine not to backtrack, with the
       usual quantifiers with a "+" appended to them.  This makes them greedy
       as well as stingy; once they succeed they won't give anything back to
       permit another solution. They have the following meanings:

       +o   "a{n,m}+" means: match at least "n" times, not more than "m" times,
           as many times as possible, and don't give anything up. "a?+" is
           short for "a{0,1}+"

       +o   "a{n,}+" means: match at least "n" times, but as many times as
           possible, and don't give anything up. "a*+" is short for "a{0,}+"
           and "a++" is short for "a{1,}+".

       +o   "a{n}+" means: match exactly "n" times.  It is just there for
           notational consistency.

       These possessive quantifiers represent a special case of a more general
       concept, the independent subexpression, see below.

       As an example where a possessive quantifier is suitable we consider
       matching a quoted string, as it appears in several programming
       languages.  The backslash is used as an escape character that indicates
       that the next character is to be taken literally, as another character
       for the string.  Therefore, after the opening quote, we expect a
       (possibly empty) sequence of alternatives: either some character except
       an unescaped quote or backslash or an escaped character.

           /"(?:[^"\\]++|\\.)*+"/;

   Building a regexp
       At this point, we have all the basic regexp concepts covered, so let's
       give a more involved example of a regular expression.  We will build a
       regexp that matches numbers.

       The first task in building a regexp is to decide what we want to match
       and what we want to exclude.  In our case, we want to match both
       integers and floating point numbers and we want to reject any string
       that isn't a number.

       The next task is to break the problem down into smaller problems that
       are easily converted into a regexp.

       The simplest case is integers.  These consist of a sequence of digits,
       with an optional sign in front.  The digits we can represent with "\d+"
       and the sign can be matched with "[+-]".  Thus the integer regexp is

           /[+-]?\d+/;  # matches integers

       A floating point number potentially has a sign, an integral part, a
       decimal point, a fractional part, and an exponent.  One or more of
       these parts is optional, so we need to check out the different
       possibilities.  Floating point numbers which are in proper form include
       123., 0.345, .34, -1e6, and 25.4E-72.  As with integers, the sign out
       front is completely optional and can be matched by "[+-]?".  We can see
       that if there is no exponent, floating point numbers must have a
       decimal point, otherwise they are integers.  We might be tempted to
       model these with "\d*\.\d*", but this would also match just a single
       decimal point, which is not a number.  So the three cases of floating
       point number without exponent are

          /[+-]?\d+\./;  # 1., 321., etc.
          /[+-]?\.\d+/;  # .1, .234, etc.
          /[+-]?\d+\.\d+/;  # 1.0, 30.56, etc.

       These can be combined into a single regexp with a three-way
       alternation:

          /[+-]?(\d+\.\d+|\d+\.|\.\d+)/;  # floating point, no exponent

       In this alternation, it is important to put '\d+\.\d+' before '\d+\.'.
       If '\d+\.' were first, the regexp would happily match that and ignore
       the fractional part of the number.

       Now consider floating point numbers with exponents.  The key
       observation here is that both integers and numbers with decimal points
       are allowed in front of an exponent.  Then exponents, like the overall
       sign, are independent of whether we are matching numbers with or
       without decimal points, and can be 'decoupled' from the mantissa.  The
       overall form of the regexp now becomes clear:

           /^(optional sign)(integer | f.p. mantissa)(optional exponent)$/;

       The exponent is an "e" or "E", followed by an integer.  So the exponent
       regexp is

          /[eE][+-]?\d+/;  # exponent

       Putting all the parts together, we get a regexp that matches numbers:

          /^[+-]?(\d+\.\d+|\d+\.|\.\d+|\d+)([eE][+-]?\d+)?$/;  # Ta da!

       Long regexps like this may impress your friends, but can be hard to
       decipher.  In complex situations like this, the "//x" modifier for a
       match is invaluable.  It allows one to put nearly arbitrary whitespace
       and comments into a regexp without affecting their meaning.  Using it,
       we can rewrite our 'extended' regexp in the more pleasing form

          /^
             [+-]?         # first, match an optional sign
             (             # then match integers or f.p. mantissas:
                 \d+\.\d+  # mantissa of the form a.b
                |\d+\.     # mantissa of the form a.
                |\.\d+     # mantissa of the form .b
                |\d+       # integer of the form a
             )
             ([eE][+-]?\d+)?  # finally, optionally match an exponent
          $/x;

       If whitespace is mostly irrelevant, how does one include space
       characters in an extended regexp? The answer is to backslash it '\ ' or
       put it in a character class "[ ]".  The same thing goes for pound
       signs: use "\#" or "[#]".  For instance, Perl allows a space between
       the sign and the mantissa or integer, and we could add this to our
       regexp as follows:

          /^
             [+-]?\ *      # first, match an optional sign *and space*
             (             # then match integers or f.p. mantissas:
                 \d+\.\d+  # mantissa of the form a.b
                |\d+\.     # mantissa of the form a.
                |\.\d+     # mantissa of the form .b
                |\d+       # integer of the form a
             )
             ([eE][+-]?\d+)?  # finally, optionally match an exponent
          $/x;

       In this form, it is easier to see a way to simplify the alternation.
       Alternatives 1, 2, and 4 all start with "\d+", so it could be factored
       out:

          /^
             [+-]?\ *      # first, match an optional sign
             (             # then match integers or f.p. mantissas:
                 \d+       # start out with a ...
                 (
                     \.\d* # mantissa of the form a.b or a.
                 )?        # ? takes care of integers of the form a
                |\.\d+     # mantissa of the form .b
             )
             ([eE][+-]?\d+)?  # finally, optionally match an exponent
          $/x;

       or written in the compact form,

           /^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;

       This is our final regexp.  To recap, we built a regexp by

       +o   specifying the task in detail,

       +o   breaking down the problem into smaller parts,

       +o   translating the small parts into regexps,

       +o   combining the regexps,

       +o   and optimizing the final combined regexp.

       These are also the typical steps involved in writing a computer
       program.  This makes perfect sense, because regular expressions are
       essentially programs written in a little computer language that
       specifies patterns.

   Using regular expressions in Perl
       The last topic of Part 1 briefly covers how regexps are used in Perl
       programs.  Where do they fit into Perl syntax?

       We have already introduced the matching operator in its default
       "/regexp/" and arbitrary delimiter "m!regexp!" forms.  We have used the
       binding operator "=~" and its negation "!~" to test for string matches.
       Associated with the matching operator, we have discussed the single
       line "//s", multi-line "//m", case-insensitive "//i" and extended "//x"
       modifiers.  There are a few more things you might want to know about
       matching operators.

       Prohibiting substitution

       If you change $pattern after the first substitution happens, Perl will
       ignore it.  If you don't want any substitutions at all, use the special
       delimiter "m''":

           @pattern = ('Seuss');
           while (<>) {
               print if m'@pattern';  # matches literal '@pattern', not 'Seuss'
           }

       Similar to strings, "m''" acts like apostrophes on a regexp; all other
       "m" delimiters act like quotes.  If the regexp evaluates to the empty
       string, the regexp in the last successful match is used instead.  So we
       have

           "dog" =~ /d/;  # 'd' matches
           "dogbert =~ //;  # this matches the 'd' regexp used before

       Global matching

       The final two modifiers we will discuss here, "//g" and "//c", concern
       multiple matches.  The modifier "//g" stands for global matching and
       allows the matching operator to match within a string as many times as
       possible.  In scalar context, successive invocations against a string
       will have "//g" jump from match to match, keeping track of position in
       the string as it goes along.  You can get or set the position with the
       "pos()" function.

       The use of "//g" is shown in the following example.  Suppose we have a
       string that consists of words separated by spaces.  If we know how many
       words there are in advance, we could extract the words using groupings:

           $x = "cat dog house"; # 3 words
           $x =~ /^\s*(\w+)\s+(\w+)\s+(\w+)\s*$/; # matches,
                                                  # $1 = 'cat'
                                                  # $2 = 'dog'
                                                  # $3 = 'house'

       But what if we had an indeterminate number of words? This is the sort
       of task "//g" was made for.  To extract all words, form the simple
       regexp "(\w+)" and loop over all matches with "/(\w+)/g":

           while ($x =~ /(\w+)/g) {
               print "Word is $1, ends at position ", pos $x, "\n";
           }

       prints

           Word is cat, ends at position 3
           Word is dog, ends at position 7
           Word is house, ends at position 13

       A failed match or changing the target string resets the position.  If
       you don't want the position reset after failure to match, add the
       "//c", as in "/regexp/gc".  The current position in the string is
       associated with the string, not the regexp.  This means that different
       strings have different positions and their respective positions can be
       set or read independently.

       In list context, "//g" returns a list of matched groupings, or if there
       are no groupings, a list of matches to the whole regexp.  So if we
       wanted just the words, we could use

           @words = ($x =~ /(\w+)/g);  # matches,
                                       # $word[0] = 'cat'
                                       # $word[1] = 'dog'
                                       # $word[2] = 'house'

       Closely associated with the "//g" modifier is the "\G" anchor.  The
       "\G" anchor matches at the point where the previous "//g" match left
       off.  "\G" allows us to easily do context-sensitive matching:

           $metric = 1;  # use metric units
           ...
           $x = <FILE>;  # read in measurement
           $x =~ /^([+-]?\d+)\s*/g;  # get magnitude
           $weight = $1;
           if ($metric) { # error checking
               print "Units error!" unless $x =~ /\Gkg\./g;
           }
           else {
               print "Units error!" unless $x =~ /\Glbs\./g;
           }
           $x =~ /\G\s+(widget|sprocket)/g;  # continue processing

       The combination of "//g" and "\G" allows us to process the string a bit
       at a time and use arbitrary Perl logic to decide what to do next.
       Currently, the "\G" anchor is only fully supported when used to anchor
       to the start of the pattern.

       "\G" is also invaluable in processing fixed-length records with
       regexps.  Suppose we have a snippet of coding region DNA, encoded as
       base pair letters "ATCGTTGAAT..." and we want to find all the stop
       codons "TGA".  In a coding region, codons are 3-letter sequences, so we
       can think of the DNA snippet as a sequence of 3-letter records.  The
       naive regexp

           # expanded, this is "ATC GTT GAA TGC AAA TGA CAT GAC"
           $dna = "ATCGTTGAATGCAAATGACATGAC";
           $dna =~ /TGA/;

       doesn't work; it may match a "TGA", but there is no guarantee that the
       match is aligned with codon boundaries, e.g., the substring "GTT GAA"
       gives a match.  A better solution is

           while ($dna =~ /(\w\w\w)*?TGA/g) {  # note the minimal *?
               print "Got a TGA stop codon at position ", pos $dna, "\n";
           }

       which prints

           Got a TGA stop codon at position 18
           Got a TGA stop codon at position 23

       Position 18 is good, but position 23 is bogus.  What happened?

       The answer is that our regexp works well until we get past the last
       real match.  Then the regexp will fail to match a synchronized "TGA"
       and start stepping ahead one character position at a time, not what we
       want.  The solution is to use "\G" to anchor the match to the codon
       alignment:

           while ($dna =~ /\G(\w\w\w)*?TGA/g) {
               print "Got a TGA stop codon at position ", pos $dna, "\n";
           }

       This prints

           Got a TGA stop codon at position 18

       which is the correct answer.  This example illustrates that it is
       important not only to match what is desired, but to reject what is not
       desired.

       (There are other regexp modifiers that are available, such as "//o",
       "//d", and "//l", but their specialized uses are beyond the scope of
       this introduction.  )

       Search and replace

       Regular expressions also play a big role in search and replace
       operations in Perl.  Search and replace is accomplished with the "s///"
       operator.  The general form is "s/regexp/replacement/modifiers", with
       everything we know about regexps and modifiers applying in this case as
       well.  The "replacement" is a Perl double-quoted string that replaces
       in the string whatever is matched with the "regexp".  The operator "=~"
       is also used here to associate a string with "s///".  If matching
       against $_, the "$_ =~" can be dropped.  If there is a match, "s///"
       returns the number of substitutions made; otherwise it returns false.
       Here are a few examples:

           $x = "Time to feed the cat!";
           $x =~ s/cat/hacker/;   # $x contains "Time to feed the hacker!"
           if ($x =~ s/^(Time.*hacker)!$/$1 now!/) {
               $more_insistent = 1;
           }
           $y = "'quoted words'";
           $y =~ s/^'(.*)'$/$1/;  # strip single quotes,
                                  # $y contains "quoted words"

       In the last example, the whole string was matched, but only the part
       inside the single quotes was grouped.  With the "s///" operator, the
       matched variables $1, $2, etc. are immediately available for use in the
       replacement expression, so we use $1 to replace the quoted string with
       just what was quoted.  With the global modifier, "s///g" will search
       and replace all occurrences of the regexp in the string:

           $x = "I batted 4 for 4";
           $x =~ s/4/four/;   # doesn't do it all:
                              # $x contains "I batted four for 4"
           $x = "I batted 4 for 4";
           $x =~ s/4/four/g;  # does it all:
                              # $x contains "I batted four for four"

       If you prefer 'regex' over 'regexp' in this tutorial, you could use the
       following program to replace it:

           % cat > simple_replace
           #!/usr/bin/perl
           $regexp = shift;
           $replacement = shift;
           while (<>) {
               s/$regexp/$replacement/g;
               print;
           }
           ^D

           % simple_replace regexp regex perlretut.pod

       In "simple_replace" we used the "s///g" modifier to replace all
       occurrences of the regexp on each line.  (Even though the regular
       expression appears in a loop, Perl is smart enough to compile it only
       once.)  As with "simple_grep", both the "print" and the
       "s/$regexp/$replacement/g" use $_ implicitly.

       If you don't want "s///" to change your original variable you can use
       the non-destructive substitute modifier, "s///r".  This changes the
       behavior so that "s///r" returns the final substituted string (instead
       of the number of substitutions):

           $x = "I like dogs.";
           $y = $x =~ s/dogs/cats/r;
           print "$x $y\n";

       That example will print "I like dogs. I like cats". Notice the original
       $x variable has not been affected. The overall result of the
       substitution is instead stored in $y. If the substitution doesn't
       affect anything then the original string is returned:

           $x = "I like dogs.";
           $y = $x =~ s/elephants/cougars/r;
           print "$x $y\n"; # prints "I like dogs. I like dogs."

       One other interesting thing that the "s///r" flag allows is chaining
       substitutions:

           $x = "Cats are great.";
           print $x =~ s/Cats/Dogs/r =~ s/Dogs/Frogs/r =~ s/Frogs/Hedgehogs/r, "\n";
           # prints "Hedgehogs are great."

       A modifier available specifically to search and replace is the "s///e"
       evaluation modifier.  "s///e" treats the replacement text as Perl code,
       rather than a double-quoted string.  The value that the code returns is
       substituted for the matched substring.  "s///e" is useful if you need
       to do a bit of computation in the process of replacing text.  This
       example counts character frequencies in a line:

           $x = "Bill the cat";
           $x =~ s/(.)/$chars{$1}++;$1/eg;  # final $1 replaces char with itself
           print "frequency of '$_' is $chars{$_}\n"
               foreach (sort {$chars{$b} <=> $chars{$a}} keys %chars);

       This prints

           frequency of ' ' is 2
           frequency of 't' is 2
           frequency of 'l' is 2
           frequency of 'B' is 1
           frequency of 'c' is 1
           frequency of 'e' is 1
           frequency of 'h' is 1
           frequency of 'i' is 1
           frequency of 'a' is 1

       As with the match "m//" operator, "s///" can use other delimiters, such
       as "s!!!" and "s{}{}", and even "s{}//".  If single quotes are used
       "s'''", then the regexp and replacement are treated as single-quoted
       strings and there are no variable substitutions.  "s///" in list
       context returns the same thing as in scalar context, i.e., the number
       of matches.

       The split function

       The "split()" function is another place where a regexp is used.  "split
       /regexp/, string, limit" separates the "string" operand into a list of
       substrings and returns that list.  The regexp must be designed to match
       whatever constitutes the separators for the desired substrings.  The
       "limit", if present, constrains splitting into no more than "limit"
       number of strings.  For example, to split a string into words, use

           $x = "Calvin and Hobbes";
           @words = split /\s+/, $x;  # $word[0] = 'Calvin'
                                      # $word[1] = 'and'
                                      # $word[2] = 'Hobbes'

       If the empty regexp "//" is used, the regexp always matches and the
       string is split into individual characters.  If the regexp has
       groupings, then the resulting list contains the matched substrings from
       the groupings as well.  For instance,

           $x = "/usr/bin/perl";
           @dirs = split m!/!, $x;  # $dirs[0] = ''
                                    # $dirs[1] = 'usr'
                                    # $dirs[2] = 'bin'
                                    # $dirs[3] = 'perl'
           @parts = split m!(/)!, $x;  # $parts[0] = ''
                                       # $parts[1] = '/'
                                       # $parts[2] = 'usr'
                                       # $parts[3] = '/'
                                       # $parts[4] = 'bin'
                                       # $parts[5] = '/'
                                       # $parts[6] = 'perl'

       Since the first character of $x matched the regexp, "split" prepended
       an empty initial element to the list.

       If you have read this far, congratulations! You now have all the basic
       tools needed to use regular expressions to solve a wide range of text
       processing problems.  If this is your first time through the tutorial,
       why not stop here and play around with regexps a while....  Part 2
       concerns the more esoteric aspects of regular expressions and those
       concepts certainly aren't needed right at the start.

Part 2: Power tools
       OK, you know the basics of regexps and you want to know more.  If
       matching regular expressions is analogous to a walk in the woods, then
       the tools discussed in Part 1 are analogous to topo maps and a compass,
       basic tools we use all the time.  Most of the tools in part 2 are
       analogous to flare guns and satellite phones.  They aren't used too
       often on a hike, but when we are stuck, they can be invaluable.

       What follows are the more advanced, less used, or sometimes esoteric
       capabilities of Perl regexps.  In Part 2, we will assume you are
       comfortable with the basics and concentrate on the advanced features.

   More on characters, strings, and character classes
       There are a number of escape sequences and character classes that we
       haven't covered yet.

       There are several escape sequences that convert characters or strings
       between upper and lower case, and they are also available within
       patterns.  "\l" and "\u" convert the next character to lower or upper
       case, respectively:

           $x = "perl";
           $string =~ /\u$x/;  # matches 'Perl' in $string
           $x = "M(rs?|s)\\."; # note the double backslash
           $string =~ /\l$x/;  # matches 'mr.', 'mrs.', and 'ms.',

       A "\L" or "\U" indicates a lasting conversion of case, until terminated
       by "\E" or thrown over by another "\U" or "\L":

           $x = "This word is in lower case:\L SHOUT\E";
           $x =~ /shout/;       # matches
           $x = "I STILL KEYPUNCH CARDS FOR MY 360"
           $x =~ /\Ukeypunch/;  # matches punch card string

       If there is no "\E", case is converted until the end of the string. The
       regexps "\L\u$word" or "\u\L$word" convert the first character of $word
       to uppercase and the rest of the characters to lowercase.

       Control characters can be escaped with "\c", so that a control-Z
       character would be matched with "\cZ".  The escape sequence "\Q"..."\E"
       quotes, or protects most non-alphabetic characters.   For instance,

           $x = "\QThat !^*&%~& cat!";
           $x =~ /\Q!^*&%~&\E/;  # check for rough language

       It does not protect "$" or "@", so that variables can still be
       substituted.

       "\Q", "\L", "\l", "\U", "\u" and "\E" are actually part of double-
       quotish syntax, and not part of regexp syntax proper.  They will work
       if they appear in a regular expression embedded directly in a program,
       but not when contained in a string that is interpolated in a pattern.

       With the advent of 5.6.0, Perl regexps can handle more than just the
       standard ASCII character set.  Perl now supports Unicode, a standard
       for representing the alphabets from virtually all of the world's
       written languages, and a host of symbols.  Perl's text strings are
       Unicode strings, so they can contain characters with a value (codepoint
       or character number) higher than 255.

       What does this mean for regexps? Well, regexp users don't need to know
       much about Perl's internal representation of strings.  But they do need
       to know 1) how to represent Unicode characters in a regexp and 2) that
       a matching operation will treat the string to be searched as a sequence
       of characters, not bytes.  The answer to 1) is that Unicode characters
       greater than "chr(255)" are represented using the "\x{hex}" notation,
       because \x hex (without curly braces) doesn't go further than 255.
       (Starting in Perl 5.14, if you're an octal fan, you can also use
       "\o{oct}".)

           /\x{263a}/;  # match a Unicode smiley face :)

       NOTE: In Perl 5.6.0 it used to be that one needed to say "use utf8" to
       use any Unicode features.  This is no more the case: for almost all
       Unicode processing, the explicit "utf8" pragma is not needed.  (The
       only case where it matters is if your Perl script is in Unicode and
       encoded in UTF-8, then an explicit "use utf8" is needed.)

       Figuring out the hexadecimal sequence of a Unicode character you want
       or deciphering someone else's hexadecimal Unicode regexp is about as
       much fun as programming in machine code.  So another way to specify
       Unicode characters is to use the named character escape sequence
       "\N{name}".  name is a name for the Unicode character, as specified in
       the Unicode standard.  For instance, if we wanted to represent or match
       the astrological sign for the planet Mercury, we could use

           use charnames ":full"; # use named chars with Unicode full names
           $x = "abc\N{MERCURY}def";
           $x =~ /\N{MERCURY}/;   # matches

       One can also use short names or restrict names to a certain alphabet:

           use charnames ':full';
           print "\N{GREEK SMALL LETTER SIGMA} is called sigma.\n";

           use charnames ":short";
           print "\N{greek:Sigma} is an upper-case sigma.\n";

           use charnames qw(greek);
           print "\N{sigma} is Greek sigma\n";

       A list of full names can be found in NamesList.txt in the Unicode
       standard (available at <http://www.unicode.org/Public/UNIDATA/>).

       The answer to requirement 2), as of 5.6.0, is that a regexp (mostly)
       uses Unicode characters.  (For messy backward compatibility reasons,
       most but not all semantics of a match will assume Unicode, unless,
       starting in Perl 5.14, you tell it to use full Unicode.  You can do
       this explicitly by using the "//u" modifier, or you can ask Perl to use
       the modifier implicitly for all regexes in a scope by using "use 5.012"
       (or higher) or "use feature 'unicode_strings'".)  If you want to handle
       Unicode properly, you should ensure that one of these is the case.)
       Internally, this is encoded to bytes using either UTF-8 or a native 8
       bit encoding, depending on the history of the string, but conceptually
       it is a sequence of characters, not bytes. See perlunitut for a
       tutorial about that.

       Let us now discuss Unicode character classes.  Just as with Unicode
       characters, there are named Unicode character classes represented by
       the "\p{name}" escape sequence.  Closely associated is the "\P{name}"
       character class, which is the negation of the "\p{name}" class.  For
       example, to match lower and uppercase characters,

           use charnames ":full"; # use named chars with Unicode full names
           $x = "BOB";
           $x =~ /^\p{IsUpper}/;   # matches, uppercase char class
           $x =~ /^\P{IsUpper}/;   # doesn't match, char class sans uppercase
           $x =~ /^\p{IsLower}/;   # doesn't match, lowercase char class
           $x =~ /^\P{IsLower}/;   # matches, char class sans lowercase

       (The "Is" is optional.)

       Here is the association between some Perl named classes and the
       traditional Unicode classes:

           Perl class name  Unicode class name or regular expression

           IsAlpha          /^[LM]/
           IsAlnum          /^[LMN]/
           IsASCII          $code <= 127
           IsCntrl          /^C/
           IsBlank          $code =~ /^(0020|0009)$/ || /^Z[^lp]/
           IsDigit          Nd
           IsGraph          /^([LMNPS]|Co)/
           IsLower          Ll
           IsPrint          /^([LMNPS]|Co|Zs)/
           IsPunct          /^P/
           IsSpace          /^Z/ || ($code =~ /^(0009|000A|000B|000C|000D)$/
           IsSpacePerl      /^Z/ || ($code =~ /^(0009|000A|000C|000D|0085|2028|2029)$/
           IsUpper          /^L[ut]/
           IsWord           /^[LMN]/ || $code eq "005F"
           IsXDigit         $code =~ /^00(3[0-9]|[46][1-6])$/

       You can also use the official Unicode class names with "\p" and "\P",
       like "\p{L}" for Unicode 'letters', "\p{Lu}" for uppercase letters, or
       "\P{Nd}" for non-digits.  If a "name" is just one letter, the braces
       can be dropped.  For instance, "\pM" is the character class of Unicode
       'marks', for example accent marks.  For the full list see perlunicode.

       Unicode has also been separated into various sets of characters which
       you can test with "\p{...}" (in) and "\P{...}" (not in).  To test
       whether a character is (or is not) an element of a script you would use
       the script name, for example "\p{Latin}", "\p{Greek}", or
       "\P{Katakana}".

       What we have described so far is the single form of the "\p{...}"
       character classes.  There is also a compound form which you may run
       into.  These look like "\p{name=value}" or "\p{name:value}" (the equals
       sign and colon can be used interchangeably).  These are more general
       than the single form, and in fact most of the single forms are just
       Perl-defined shortcuts for common compound forms.  For example, the
       script examples in the previous paragraph could be written equivalently
       as "\p{Script=Latin}", "\p{Script:Greek}", and "\P{script=katakana}"
       (case is irrelevant between the "{}" braces).  You may never have to
       use the compound forms, but sometimes it is necessary, and their use
       can make your code easier to understand.

       "\X" is an abbreviation for a character class that comprises a Unicode
       extended grapheme cluster.  This represents a "logical character": what
       appears to be a single character, but may be represented internally by
       more than one.  As an example, using the Unicode full names, e.g.,
       "A + COMBINING RING" is a grapheme cluster with base character "A" and
       combining character "COMBINING RING", which translates in Danish to A
       with the circle atop it, as in the word Angstrom.

       For the full and latest information about Unicode see the latest
       Unicode standard, or the Unicode Consortium's website
       <http://www.unicode.org>

       As if all those classes weren't enough, Perl also defines POSIX-style
       character classes.  These have the form "[:name:]", with "name" the
       name of the POSIX class.  The POSIX classes are "alpha", "alnum",
       "ascii", "cntrl", "digit", "graph", "lower", "print", "punct", "space",
       "upper", and "xdigit", and two extensions, "word" (a Perl extension to
       match "\w"), and "blank" (a GNU extension).  The "//a" modifier
       restricts these to matching just in the ASCII range; otherwise they can
       match the same as their corresponding Perl Unicode classes: "[:upper:]"
       is the same as "\p{IsUpper}", etc.  (There are some exceptions and
       gotchas with this; see perlrecharclass for a full discussion.) The
       "[:digit:]", "[:word:]", and "[:space:]" correspond to the familiar
       "\d", "\w", and "\s" character classes.  To negate a POSIX class, put a
       "^" in front of the name, so that, e.g., "[:^digit:]" corresponds to
       "\D" and, under Unicode, "\P{IsDigit}".  The Unicode and POSIX
       character classes can be used just like "\d", with the exception that
       POSIX character classes can only be used inside of a character class:

           /\s+[abc[:digit:]xyz]\s*/;  # match a,b,c,x,y,z, or a digit
           /^=item\s[[:digit:]]/;      # match '=item',
                                       # followed by a space and a digit
           /\s+[abc\p{IsDigit}xyz]\s+/;  # match a,b,c,x,y,z, or a digit
           /^=item\s\p{IsDigit}/;        # match '=item',
                                         # followed by a space and a digit

       Whew! That is all the rest of the characters and character classes.

   Compiling and saving regular expressions
       In Part 1 we mentioned that Perl compiles a regexp into a compact
       sequence of opcodes.  Thus, a compiled regexp is a data structure that
       can be stored once and used again and again.  The regexp quote "qr//"
       does exactly that: "qr/string/" compiles the "string" as a regexp and
       transforms the result into a form that can be assigned to a variable:

           $reg = qr/foo+bar?/;  # reg contains a compiled regexp

       Then $reg can be used as a regexp:

           $x = "fooooba";
           $x =~ $reg;     # matches, just like /foo+bar?/
           $x =~ /$reg/;   # same thing, alternate form

       $reg can also be interpolated into a larger regexp:

           $x =~ /(abc)?$reg/;  # still matches

       As with the matching operator, the regexp quote can use different
       delimiters, e.g., "qr!!", "qr{}" or "qr~~".  Apostrophes as delimiters
       ("qr''") inhibit any interpolation.

       Pre-compiled regexps are useful for creating dynamic matches that don't
       need to be recompiled each time they are encountered.  Using pre-
       compiled regexps, we write a "grep_step" program which greps for a
       sequence of patterns, advancing to the next pattern as soon as one has
       been satisfied.

           % cat > grep_step
           #!/usr/bin/perl
           # grep_step - match <number> regexps, one after the other
           # usage: multi_grep <number> regexp1 regexp2 ... file1 file2 ...

           $number = shift;
           $regexp[$_] = shift foreach (0..$number-1);
           @compiled = map qr/$_/, @regexp;
           while ($line = <>) {
               if ($line =~ /$compiled[0]/) {
                   print $line;
                   shift @compiled;
                   last unless @compiled;
               }
           }
           ^D

           % grep_step 3 shift print last grep_step
           $number = shift;
                   print $line;
                   last unless @compiled;

       Storing pre-compiled regexps in an array @compiled allows us to simply
       loop through the regexps without any recompilation, thus gaining
       flexibility without sacrificing speed.

   Composing regular expressions at runtime
       Backtracking is more efficient than repeated tries with different
       regular expressions.  If there are several regular expressions and a
       match with any of them is acceptable, then it is possible to combine
       them into a set of alternatives.  If the individual expressions are
       input data, this can be done by programming a join operation.  We'll
       exploit this idea in an improved version of the "simple_grep" program:
       a program that matches multiple patterns:

           % cat > multi_grep
           #!/usr/bin/perl
           # multi_grep - match any of <number> regexps
           # usage: multi_grep <number> regexp1 regexp2 ... file1 file2 ...

           $number = shift;
           $regexp[$_] = shift foreach (0..$number-1);
           $pattern = join '|', @regexp;

           while ($line = <>) {
               print $line if $line =~ /$pattern/;
           }
           ^D

           % multi_grep 2 shift for multi_grep
           $number = shift;
           $regexp[$_] = shift foreach (0..$number-1);

       Sometimes it is advantageous to construct a pattern from the input that
       is to be analyzed and use the permissible values on the left hand side
       of the matching operations.  As an example for this somewhat
       paradoxical situation, let's assume that our input contains a command
       verb which should match one out of a set of available command verbs,
       with the additional twist that commands may be abbreviated as long as
       the given string is unique. The program below demonstrates the basic
       algorithm.

           % cat > keymatch
           #!/usr/bin/perl
           $kwds = 'copy compare list print';
           while( $command = <> ){
               $command =~ s/^\s+|\s+$//g;  # trim leading and trailing spaces
               if( ( @matches = $kwds =~ /\b$command\w*/g ) == 1 ){
                   print "command: '@matches'\n";
               } elsif( @matches == 0 ){
                   print "no such command: '$command'\n";
               } else {
                   print "not unique: '$command' (could be one of: @matches)\n";
               }
           }
           ^D

           % keymatch
           li
           command: 'list'
           co
           not unique: 'co' (could be one of: copy compare)
           printer
           no such command: 'printer'

       Rather than trying to match the input against the keywords, we match
       the combined set of keywords against the input.  The pattern matching
       operation "$kwds =~ /\b($command\w*)/g" does several things at the same
       time. It makes sure that the given command begins where a keyword
       begins ("\b"). It tolerates abbreviations due to the added "\w*". It
       tells us the number of matches ("scalar @matches") and all the keywords
       that were actually matched.  You could hardly ask for more.

   Embedding comments and modifiers in a regular expression
       Starting with this section, we will be discussing Perl's set of
       extended patterns.  These are extensions to the traditional regular
       expression syntax that provide powerful new tools for pattern matching.
       We have already seen extensions in the form of the minimal matching
       constructs "??", "*?", "+?", "{n,m}?", and "{n,}?".  Most of the
       extensions below have the form "(?char...)", where the "char" is a
       character that determines the type of extension.

       The first extension is an embedded comment "(?#text)".  This embeds a
       comment into the regular expression without affecting its meaning.  The
       comment should not have any closing parentheses in the text.  An
       example is

           /(?# Match an integer:)[+-]?\d+/;

       This style of commenting has been largely superseded by the raw,
       freeform commenting that is allowed with the "//x" modifier.

       Most modifiers, such as "//i", "//m", "//s" and "//x" (or any
       combination thereof) can also be embedded in a regexp using "(?i)",
       "(?m)", "(?s)", and "(?x)".  For instance,

           /(?i)yes/;  # match 'yes' case insensitively
           /yes/i;     # same thing
           /(?x)(          # freeform version of an integer regexp
                    [+-]?  # match an optional sign
                    \d+    # match a sequence of digits
                )
           /x;

       Embedded modifiers can have two important advantages over the usual
       modifiers.  Embedded modifiers allow a custom set of modifiers to each
       regexp pattern.  This is great for matching an array of regexps that
       must have different modifiers:

           $pattern[0] = '(?i)doctor';
           $pattern[1] = 'Johnson';
           ...
           while (<>) {
               foreach $patt (@pattern) {
                   print if /$patt/;
               }
           }

       The second advantage is that embedded modifiers (except "//p", which
       modifies the entire regexp) only affect the regexp inside the group the
       embedded modifier is contained in.  So grouping can be used to localize
       the modifier's effects:

           /Answer: ((?i)yes)/;  # matches 'Answer: yes', 'Answer: YES', etc.

       Embedded modifiers can also turn off any modifiers already present by
       using, e.g., "(?-i)".  Modifiers can also be combined into a single
       expression, e.g., "(?s-i)" turns on single line mode and turns off case
       insensitivity.

       Embedded modifiers may also be added to a non-capturing grouping.
       "(?i-m:regexp)" is a non-capturing grouping that matches "regexp" case
       insensitively and turns off multi-line mode.

   Looking ahead and looking behind
       This section concerns the lookahead and lookbehind assertions.  First,
       a little background.

       In Perl regular expressions, most regexp elements 'eat up' a certain
       amount of string when they match.  For instance, the regexp element
       "[abc}]" eats up one character of the string when it matches, in the
       sense that Perl moves to the next character position in the string
       after the match.  There are some elements, however, that don't eat up
       characters (advance the character position) if they match.  The
       examples we have seen so far are the anchors.  The anchor "^" matches
       the beginning of the line, but doesn't eat any characters.  Similarly,
       the word boundary anchor "\b" matches wherever a character matching
       "\w" is next to a character that doesn't, but it doesn't eat up any
       characters itself.  Anchors are examples of zero-width assertions:
       zero-width, because they consume no characters, and assertions, because
       they test some property of the string.  In the context of our walk in
       the woods analogy to regexp matching, most regexp elements move us
       along a trail, but anchors have us stop a moment and check our
       surroundings.  If the local environment checks out, we can proceed
       forward.  But if the local environment doesn't satisfy us, we must
       backtrack.

       Checking the environment entails either looking ahead on the trail,
       looking behind, or both.  "^" looks behind, to see that there are no
       characters before.  "$" looks ahead, to see that there are no
       characters after.  "\b" looks both ahead and behind, to see if the
       characters on either side differ in their "word-ness".

       The lookahead and lookbehind assertions are generalizations of the
       anchor concept.  Lookahead and lookbehind are zero-width assertions
       that let us specify which characters we want to test for.  The
       lookahead assertion is denoted by "(?=regexp)" and the lookbehind
       assertion is denoted by "(?<=fixed-regexp)".  Some examples are

           $x = "I catch the housecat 'Tom-cat' with catnip";
           $x =~ /cat(?=\s)/;   # matches 'cat' in 'housecat'
           @catwords = ($x =~ /(?<=\s)cat\w+/g);  # matches,
                                                  # $catwords[0] = 'catch'
                                                  # $catwords[1] = 'catnip'
           $x =~ /\bcat\b/;  # matches 'cat' in 'Tom-cat'
           $x =~ /(?<=\s)cat(?=\s)/; # doesn't match; no isolated 'cat' in
                                     # middle of $x

       Note that the parentheses in "(?=regexp)" and "(?<=regexp)" are non-
       capturing, since these are zero-width assertions.  Thus in the second
       regexp, the substrings captured are those of the whole regexp itself.
       Lookahead "(?=regexp)" can match arbitrary regexps, but lookbehind
       "(?<=fixed-regexp)" only works for regexps of fixed width, i.e., a
       fixed number of characters long.  Thus "(?<=(ab|bc))" is fine, but
       "(?<=(ab)*)" is not.  The negated versions of the lookahead and
       lookbehind assertions are denoted by "(?!regexp)" and
       "(?<!fixed-regexp)" respectively.  They evaluate true if the regexps do
       not match:

           $x = "foobar";
           $x =~ /foo(?!bar)/;  # doesn't match, 'bar' follows 'foo'
           $x =~ /foo(?!baz)/;  # matches, 'baz' doesn't follow 'foo'
           $x =~ /(?<!\s)foo/;  # matches, there is no \s before 'foo'

       The "\C" is unsupported in lookbehind, because the already treacherous
       definition of "\C" would become even more so when going backwards.

       Here is an example where a string containing blank-separated words,
       numbers and single dashes is to be split into its components.  Using
       "/\s+/" alone won't work, because spaces are not required between
       dashes, or a word or a dash. Additional places for a split are
       established by looking ahead and behind:

           $str = "one two - --6-8";
           @toks = split / \s+              # a run of spaces
                         | (?<=\S) (?=-)    # any non-space followed by '-'
                         | (?<=-)  (?=\S)   # a '-' followed by any non-space
                         /x, $str;          # @toks = qw(one two - - - 6 - 8)

   Using independent subexpressions to prevent backtracking
       Independent subexpressions are regular expressions, in the context of a
       larger regular expression, that function independently of the larger
       regular expression.  That is, they consume as much or as little of the
       string as they wish without regard for the ability of the larger regexp
       to match.  Independent subexpressions are represented by "(?>regexp)".
       We can illustrate their behavior by first considering an ordinary
       regexp:

           $x = "ab";
           $x =~ /a*ab/;  # matches

       This obviously matches, but in the process of matching, the
       subexpression "a*" first grabbed the "a".  Doing so, however, wouldn't
       allow the whole regexp to match, so after backtracking, "a*" eventually
       gave back the "a" and matched the empty string.  Here, what "a*"
       matched was dependent on what the rest of the regexp matched.

       Contrast that with an independent subexpression:

           $x =~ /(?>a*)ab/;  # doesn't match!

       The independent subexpression "(?>a*)" doesn't care about the rest of
       the regexp, so it sees an "a" and grabs it.  Then the rest of the
       regexp "ab" cannot match.  Because "(?>a*)" is independent, there is no
       backtracking and the independent subexpression does not give up its
       "a".  Thus the match of the regexp as a whole fails.  A similar
       behavior occurs with completely independent regexps:

           $x = "ab";
           $x =~ /a*/g;   # matches, eats an 'a'
           $x =~ /\Gab/g; # doesn't match, no 'a' available

       Here "//g" and "\G" create a 'tag team' handoff of the string from one
       regexp to the other.  Regexps with an independent subexpression are
       much like this, with a handoff of the string to the independent
       subexpression, and a handoff of the string back to the enclosing
       regexp.

       The ability of an independent subexpression to prevent backtracking can
       be quite useful.  Suppose we want to match a non-empty string enclosed
       in parentheses up to two levels deep.  Then the following regexp
       matches:

           $x = "abc(de(fg)h";  # unbalanced parentheses
           $x =~ /\( ( [^()]+ | \([^()]*\) )+ \)/x;

       The regexp matches an open parenthesis, one or more copies of an
       alternation, and a close parenthesis.  The alternation is two-way, with
       the first alternative "[^()]+" matching a substring with no parentheses
       and the second alternative "\([^()]*\)"  matching a substring delimited
       by parentheses.  The problem with this regexp is that it is
       pathological: it has nested indeterminate quantifiers of the form
       "(a+|b)+".  We discussed in Part 1 how nested quantifiers like this
       could take an exponentially long time to execute if there was no match
       possible.  To prevent the exponential blowup, we need to prevent
       useless backtracking at some point.  This can be done by enclosing the
       inner quantifier as an independent subexpression:

           $x =~ /\( ( (?>[^()]+) | \([^()]*\) )+ \)/x;

       Here, "(?>[^()]+)" breaks the degeneracy of string partitioning by
       gobbling up as much of the string as possible and keeping it.   Then
       match failures fail much more quickly.

   Conditional expressions
       A conditional expression is a form of if-then-else statement that
       allows one to choose which patterns are to be matched, based on some
       condition.  There are two types of conditional expression:
       "(?(condition)yes-regexp)" and "(?(condition)yes-regexp|no-regexp)".
       "(?(condition)yes-regexp)" is like an 'if () {}' statement in Perl.  If
       the "condition" is true, the "yes-regexp" will be matched.  If the
       "condition" is false, the "yes-regexp" will be skipped and Perl will
       move onto the next regexp element.  The second form is like an
       'if () {} else {}' statement in Perl.  If the "condition" is true, the
       "yes-regexp" will be matched, otherwise the "no-regexp" will be
       matched.

       The "condition" can have several forms.  The first form is simply an
       integer in parentheses "(integer)".  It is true if the corresponding
       backreference "\integer" matched earlier in the regexp.  The same thing
       can be done with a name associated with a capture group, written as
       "(<name>)" or "('name')".  The second form is a bare zero-width
       assertion "(?...)", either a lookahead, a lookbehind, or a code
       assertion (discussed in the next section).  The third set of forms
       provides tests that return true if the expression is executed within a
       recursion ("(R)") or is being called from some capturing group,
       referenced either by number ("(R1)", "(R2)",...) or by name
       ("(R&name)").

       The integer or name form of the "condition" allows us to choose, with
       more flexibility, what to match based on what matched earlier in the
       regexp. This searches for words of the form "$x$x" or "$x$y$y$x":

           % simple_grep '^(\w+)(\w+)?(?(2)\g2\g1|\g1)$' /usr/dict/words
           beriberi
           coco
           couscous
           deed
           ...
           toot
           toto
           tutu

       The lookbehind "condition" allows, along with backreferences, an
       earlier part of the match to influence a later part of the match.  For
       instance,

           /[ATGC]+(?(?<=AA)G|C)$/;

       matches a DNA sequence such that it either ends in "AAG", or some other
       base pair combination and "C".  Note that the form is "(?(?<=AA)G|C)"
       and not "(?((?<=AA))G|C)"; for the lookahead, lookbehind or code
       assertions, the parentheses around the conditional are not needed.

   Defining named patterns
       Some regular expressions use identical subpatterns in several places.
       Starting with Perl 5.10, it is possible to define named subpatterns in
       a section of the pattern so that they can be called up by name anywhere
       in the pattern.  This syntactic pattern for this definition group is
       "(?(DEFINE)(?<name>pattern)...)".  An insertion of a named pattern is
       written as "(?&name)".

       The example below illustrates this feature using the pattern for
       floating point numbers that was presented earlier on.  The three
       subpatterns that are used more than once are the optional sign, the
       digit sequence for an integer and the decimal fraction.  The DEFINE
       group at the end of the pattern contains their definition.  Notice that
       the decimal fraction pattern is the first place where we can reuse the
       integer pattern.

          /^ (?&osg)\ * ( (?&int)(?&dec)? | (?&dec) )
             (?: [eE](?&osg)(?&int) )?
           $
           (?(DEFINE)
             (?<osg>[-+]?)         # optional sign
             (?<int>\d++)          # integer
             (?<dec>\.(?&int))     # decimal fraction
           )/x

   Recursive patterns
       This feature (introduced in Perl 5.10) significantly extends the power
       of Perl's pattern matching.  By referring to some other capture group
       anywhere in the pattern with the construct "(?group-ref)", the pattern
       within the referenced group is used as an independent subpattern in
       place of the group reference itself.  Because the group reference may
       be contained within the group it refers to, it is now possible to apply
       pattern matching to tasks that hitherto required a recursive parser.

       To illustrate this feature, we'll design a pattern that matches if a
       string contains a palindrome. (This is a word or a sentence that, while
       ignoring spaces, interpunctuation and case, reads the same backwards as
       forwards. We begin by observing that the empty string or a string
       containing just one word character is a palindrome. Otherwise it must
       have a word character up front and the same at its end, with another
       palindrome in between.

           /(?: (\w) (?...Here be a palindrome...) \g{-1} | \w? )/x

       Adding "\W*" at either end to eliminate what is to be ignored, we
       already have the full pattern:

           my $pp = qr/^(\W* (?: (\w) (?1) \g{-1} | \w? ) \W*)$/ix;
           for $s ( "saippuakauppias", "A man, a plan, a canal: Panama!" ){
               print "'$s' is a palindrome\n" if $s =~ /$pp/;
           }

       In "(?...)" both absolute and relative backreferences may be used.  The
       entire pattern can be reinserted with "(?R)" or "(?0)".  If you prefer
       to name your groups, you can use "(?&name)" to recurse into that group.

   A bit of magic: executing Perl code in a regular expression
       Normally, regexps are a part of Perl expressions.  Code evaluation
       expressions turn that around by allowing arbitrary Perl code to be a
       part of a regexp.  A code evaluation expression is denoted "(?{code})",
       with code a string of Perl statements.

       Be warned that this feature is considered experimental, and may be
       changed without notice.

       Code expressions are zero-width assertions, and the value they return
       depends on their environment.  There are two possibilities: either the
       code expression is used as a conditional in a conditional expression
       "(?(condition)...)", or it is not.  If the code expression is a
       conditional, the code is evaluated and the result (i.e., the result of
       the last statement) is used to determine truth or falsehood.  If the
       code expression is not used as a conditional, the assertion always
       evaluates true and the result is put into the special variable $^R.
       The variable $^R can then be used in code expressions later in the
       regexp.  Here are some silly examples:

           $x = "abcdef";
           $x =~ /abc(?{print "Hi Mom!";})def/; # matches,
                                                # prints 'Hi Mom!'
           $x =~ /aaa(?{print "Hi Mom!";})def/; # doesn't match,
                                                # no 'Hi Mom!'

       Pay careful attention to the next example:

           $x =~ /abc(?{print "Hi Mom!";})ddd/; # doesn't match,
                                                # no 'Hi Mom!'
                                                # but why not?

       At first glance, you'd think that it shouldn't print, because obviously
       the "ddd" isn't going to match the target string. But look at this
       example:

           $x =~ /abc(?{print "Hi Mom!";})[dD]dd/; # doesn't match,
                                                   # but _does_ print

       Hmm. What happened here? If you've been following along, you know that
       the above pattern should be effectively (almost) the same as the last
       one; enclosing the "d" in a character class isn't going to change what
       it matches. So why does the first not print while the second one does?

       The answer lies in the optimizations the regex engine makes. In the
       first case, all the engine sees are plain old characters (aside from
       the "?{}" construct). It's smart enough to realize that the string
       'ddd' doesn't occur in our target string before actually running the
       pattern through. But in the second case, we've tricked it into thinking
       that our pattern is more complicated. It takes a look, sees our
       character class, and decides that it will have to actually run the
       pattern to determine whether or not it matches, and in the process of
       running it hits the print statement before it discovers that we don't
       have a match.

       To take a closer look at how the engine does optimizations, see the
       section "Pragmas and debugging" below.

       More fun with "?{}":

           $x =~ /(?{print "Hi Mom!";})/;       # matches,
                                                # prints 'Hi Mom!'
           $x =~ /(?{$c = 1;})(?{print "$c";})/;  # matches,
                                                  # prints '1'
           $x =~ /(?{$c = 1;})(?{print "$^R";})/; # matches,
                                                  # prints '1'

       The bit of magic mentioned in the section title occurs when the regexp
       backtracks in the process of searching for a match.  If the regexp
       backtracks over a code expression and if the variables used within are
       localized using "local", the changes in the variables produced by the
       code expression are undone! Thus, if we wanted to count how many times
       a character got matched inside a group, we could use, e.g.,

           $x = "aaaa";
           $count = 0;  # initialize 'a' count
           $c = "bob";  # test if $c gets clobbered
           $x =~ /(?{local $c = 0;})         # initialize count
                  ( a                        # match 'a'
                    (?{local $c = $c + 1;})  # increment count
                  )*                         # do this any number of times,
                  aa                         # but match 'aa' at the end
                  (?{$count = $c;})          # copy local $c var into $count
                 /x;
           print "'a' count is $count, \$c variable is '$c'\n";

       This prints

           'a' count is 2, $c variable is 'bob'

       If we replace the " (?{local $c = $c + 1;})" with " (?{$c = $c + 1;})",
       the variable changes are not undone during backtracking, and we get

           'a' count is 4, $c variable is 'bob'

       Note that only localized variable changes are undone.  Other side
       effects of code expression execution are permanent.  Thus

           $x = "aaaa";
           $x =~ /(a(?{print "Yow\n";}))*aa/;

       produces

          Yow
          Yow
          Yow
          Yow

       The result $^R is automatically localized, so that it will behave
       properly in the presence of backtracking.

       This example uses a code expression in a conditional to match a
       definite article, either 'the' in English or 'der|die|das' in German:

           $lang = 'DE';  # use German
           ...
           $text = "das";
           print "matched\n"
               if $text =~ /(?(?{
                                 $lang eq 'EN'; # is the language English?
                                })
                              the |             # if so, then match 'the'
                              (der|die|das)     # else, match 'der|die|das'
                            )
                           /xi;

       Note that the syntax here is "(?(?{...})yes-regexp|no-regexp)", not
       "(?((?{...}))yes-regexp|no-regexp)".  In other words, in the case of a
       code expression, we don't need the extra parentheses around the
       conditional.

       If you try to use code expressions with interpolating variables, Perl
       may surprise you:

           $bar = 5;
           $pat = '(?{ 1 })';
           /foo(?{ $bar })bar/; # compiles ok, $bar not interpolated
           /foo(?{ 1 })$bar/;   # compile error!
           /foo${pat}bar/;      # compile error!

           $pat = qr/(?{ $foo = 1 })/;  # precompile code regexp
           /foo${pat}bar/;      # compiles ok

       If a regexp has (1) code expressions and interpolating variables, or
       (2) a variable that interpolates a code expression, Perl treats the
       regexp as an error. If the code expression is precompiled into a
       variable, however, interpolating is ok. The question is, why is this an
       error?

       The reason is that variable interpolation and code expressions together
       pose a security risk.  The combination is dangerous because many
       programmers who write search engines often take user input and plug it
       directly into a regexp:

           $regexp = <>;       # read user-supplied regexp
           $chomp $regexp;     # get rid of possible newline
           $text =~ /$regexp/; # search $text for the $regexp

       If the $regexp variable contains a code expression, the user could then
       execute arbitrary Perl code.  For instance, some joker could search for
       "system('rm -rf *');" to erase your files.  In this sense, the
       combination of interpolation and code expressions taints your regexp.
       So by default, using both interpolation and code expressions in the
       same regexp is not allowed.  If you're not concerned about malicious
       users, it is possible to bypass this security check by invoking
       "use re 'eval'":

           use re 'eval';       # throw caution out the door
           $bar = 5;
           $pat = '(?{ 1 })';
           /foo(?{ 1 })$bar/;   # compiles ok
           /foo${pat}bar/;      # compiles ok

       Another form of code expression is the pattern code expression.  The
       pattern code expression is like a regular code expression, except that
       the result of the code evaluation is treated as a regular expression
       and matched immediately.  A simple example is

           $length = 5;
           $char = 'a';
           $x = 'aaaaabb';
           $x =~ /(??{$char x $length})/x; # matches, there are 5 of 'a'

       This final example contains both ordinary and pattern code expressions.
       It detects whether a binary string 1101010010001... has a Fibonacci
       spacing 0,1,1,2,3,5,...  of the 1's:

           $x = "1101010010001000001";
           $z0 = ''; $z1 = '0';   # initial conditions
           print "It is a Fibonacci sequence\n"
               if $x =~ /^1         # match an initial '1'
                           (?:
                              ((??{ $z0 })) # match some '0'
                              1             # and then a '1'
                              (?{ $z0 = $z1; $z1 .= $^N; })
                           )+   # repeat as needed
                         $      # that is all there is
                        /x;
           printf "Largest sequence matched was %d\n", length($z1)-length($z0);

       Remember that $^N is set to whatever was matched by the last completed
       capture group. This prints

           It is a Fibonacci sequence
           Largest sequence matched was 5

       Ha! Try that with your garden variety regexp package...

       Note that the variables $z0 and $z1 are not substituted when the regexp
       is compiled, as happens for ordinary variables outside a code
       expression.  Rather, the code expressions are evaluated when Perl
       encounters them during the search for a match.

       The regexp without the "//x" modifier is

           /^1(?:((??{ $z0 }))1(?{ $z0 = $z1; $z1 .= $^N; }))+$/

       which shows that spaces are still possible in the code parts.
       Nevertheless, when working with code and conditional expressions, the
       extended form of regexps is almost necessary in creating and debugging
       regexps.

   Backtracking control verbs
       Perl 5.10 introduced a number of control verbs intended to provide
       detailed control over the backtracking process, by directly influencing
       the regexp engine and by providing monitoring techniques.  As all the
       features in this group are experimental and subject to change or
       removal in a future version of Perl, the interested reader is referred
       to "Special Backtracking Control Verbs" in perlre for a detailed
       description.

       Below is just one example, illustrating the control verb "(*FAIL)",
       which may be abbreviated as "(*F)". If this is inserted in a regexp it
       will cause it to fail, just as it would at some mismatch between the
       pattern and the string. Processing of the regexp continues as it would
       after any "normal" failure, so that, for instance, the next position in
       the string or another alternative will be tried. As failing to match
       doesn't preserve capture groups or produce results, it may be necessary
       to use this in combination with embedded code.

          %count = ();
          "supercalifragilisticexpialidoceous" =~
              /([aeiou])(?{ $count{$1}++; })(*FAIL)/i;
          printf "%3d '%s'\n", $count{$_}, $_ for (sort keys %count);

       The pattern begins with a class matching a subset of letters.  Whenever
       this matches, a statement like "$count{'a'}++;" is executed,
       incrementing the letter's counter. Then "(*FAIL)" does what it says,
       and the regexp engine proceeds according to the book: as long as the
       end of the string hasn't been reached, the position is advanced before
       looking for another vowel. Thus, match or no match makes no difference,
       and the regexp engine proceeds until the entire string has been
       inspected.  (It's remarkable that an alternative solution using
       something like

          $count{lc($_)}++ for split('', "supercalifragilisticexpialidoceous");
          printf "%3d '%s'\n", $count2{$_}, $_ for ( qw{ a e i o u } );

       is considerably slower.)

   Pragmas and debugging
       Speaking of debugging, there are several pragmas available to control
       and debug regexps in Perl.  We have already encountered one pragma in
       the previous section, "use re 'eval';", that allows variable
       interpolation and code expressions to coexist in a regexp.  The other
       pragmas are

           use re 'taint';
           $tainted = <>;
           @parts = ($tainted =~ /(\w+)\s+(\w+)/; # @parts is now tainted

       The "taint" pragma causes any substrings from a match with a tainted
       variable to be tainted as well.  This is not normally the case, as
       regexps are often used to extract the safe bits from a tainted
       variable.  Use "taint" when you are not extracting safe bits, but are
       performing some other processing.  Both "taint" and "eval" pragmas are
       lexically scoped, which means they are in effect only until the end of
       the block enclosing the pragmas.

           use re '/m';  # or any other flags
           $multiline_string =~ /^foo/; # /m is implied

       The "re '/flags'" pragma (introduced in Perl 5.14) turns on the given
       regular expression flags until the end of the lexical scope.  See
       "re/"'/flags' mode"" for more detail.

           use re 'debug';
           /^(.*)$/s;       # output debugging info

           use re 'debugcolor';
           /^(.*)$/s;       # output debugging info in living color

       The global "debug" and "debugcolor" pragmas allow one to get detailed
       debugging info about regexp compilation and execution.  "debugcolor" is
       the same as debug, except the debugging information is displayed in
       color on terminals that can display termcap color sequences.  Here is
       example output:

           % perl -e 'use re "debug"; "abc" =~ /a*b+c/;'
           Compiling REx `a*b+c'
           size 9 first at 1
              1: STAR(4)
              2:   EXACT <a>(0)
              4: PLUS(7)
              5:   EXACT <b>(0)
              7: EXACT <c>(9)
              9: END(0)
           floating `bc' at 0..2147483647 (checking floating) minlen 2
           Guessing start of match, REx `a*b+c' against `abc'...
           Found floating substr `bc' at offset 1...
           Guessed: match at offset 0
           Matching REx `a*b+c' against `abc'
             Setting an EVAL scope, savestack=3
              0 <> <abc>             |  1:  STAR
                                      EXACT <a> can match 1 times out of 32767...
             Setting an EVAL scope, savestack=3
              1 <a> <bc>             |  4:    PLUS
                                      EXACT <b> can match 1 times out of 32767...
             Setting an EVAL scope, savestack=3
              2 <ab> <c>             |  7:      EXACT <c>
              3 <abc> <>             |  9:      END
           Match successful!
           Freeing REx: `a*b+c'

       If you have gotten this far into the tutorial, you can probably guess
       what the different parts of the debugging output tell you.  The first
       part

           Compiling REx `a*b+c'
           size 9 first at 1
              1: STAR(4)
              2:   EXACT <a>(0)
              4: PLUS(7)
              5:   EXACT <b>(0)
              7: EXACT <c>(9)
              9: END(0)

       describes the compilation stage.  STAR(4) means that there is a starred
       object, in this case 'a', and if it matches, goto line 4, i.e.,
       PLUS(7).  The middle lines describe some heuristics and optimizations
       performed before a match:

           floating `bc' at 0..2147483647 (checking floating) minlen 2
           Guessing start of match, REx `a*b+c' against `abc'...
           Found floating substr `bc' at offset 1...
           Guessed: match at offset 0

       Then the match is executed and the remaining lines describe the
       process:

           Matching REx `a*b+c' against `abc'
             Setting an EVAL scope, savestack=3
              0 <> <abc>             |  1:  STAR
                                      EXACT <a> can match 1 times out of 32767...
             Setting an EVAL scope, savestack=3
              1 <a> <bc>             |  4:    PLUS
                                      EXACT <b> can match 1 times out of 32767...
             Setting an EVAL scope, savestack=3
              2 <ab> <c>             |  7:      EXACT <c>
              3 <abc> <>             |  9:      END
           Match successful!
           Freeing REx: `a*b+c'

       Each step is of the form "n <x> <y>", with "<x>" the part of the string
       matched and "<y>" the part not yet matched.  The "|  1:  STAR" says
       that Perl is at line number 1 in the compilation list above.  See
       "Debugging Regular Expressions" in perldebguts for much more detail.

       An alternative method of debugging regexps is to embed "print"
       statements within the regexp.  This provides a blow-by-blow account of
       the backtracking in an alternation:

           "that this" =~ m@(?{print "Start at position ", pos, "\n";})
                            t(?{print "t1\n";})
                            h(?{print "h1\n";})
                            i(?{print "i1\n";})
                            s(?{print "s1\n";})
                                |
                            t(?{print "t2\n";})
                            h(?{print "h2\n";})
                            a(?{print "a2\n";})
                            t(?{print "t2\n";})
                            (?{print "Done at position ", pos, "\n";})
                           @x;

       prints

           Start at position 0
           t1
           h1
           t2
           h2
           a2
           t2
           Done at position 4

BUGS
       Code expressions, conditional expressions, and independent expressions
       are experimental.  Don't use them in production code.  Yet.

SEE ALSO
       This is just a tutorial.  For the full story on Perl regular
       expressions, see the perlre regular expressions reference page.

       For more information on the matching "m//" and substitution "s///"
       operators, see "Regexp Quote-Like Operators" in perlop.  For
       information on the "split" operation, see "split" in perlfunc.

       For an excellent all-around resource on the care and feeding of regular
       expressions, see the book Mastering Regular Expressions by Jeffrey
       Friedl (published by O'Reilly, ISBN 1556592-257-3).

AUTHOR AND COPYRIGHT
       Copyright (c) 2000 Mark Kvale All rights reserved.

       This document may be distributed under the same terms as Perl itself.

   Acknowledgments
       The inspiration for the stop codon DNA example came from the ZIP code
       example in chapter 7 of Mastering Regular Expressions.

       The author would like to thank Jeff Pinyan, Andrew Johnson, Peter
       Haworth, Ronald J Kimball, and Joe Smith for all their helpful
       comments.

perl v5.14.2                      2013-07-18                      PERLRETUT(1)
$
help://pending
help://pending.1
help://bk-pending
help://bk-pending.1
bk pending(none)            BitKeeper User's Manual           bk pending(none)

NAME
       bk pending - list deltas which need to be in a changeset

SYNOPSIS
       bk pending [-S] [-q]

DESCRIPTION
       The  bk  pending command shows changes that have been checked into your
       local work area, but not yet committed to a  changeset.   You  have  to
       commit to a changeset in order to send the change to other work areas.

       To see what needs to be committed to a change set, run:

           $ bk pending

OPTIONS
       -S
       --standalone  Limit  the  list  to  the current component.  This has no
                     effect in a traditional standalone repository, but  in  a
                     nested  collection,  processes just the current component
                     and not the entire nested collection.
       -q            No output.  Return 0 if there are pending files or  1  if
                     there are not.

NOTE
       This command is roughly the same as

           $ bk -e gfiles -pA | bk -P log ... -

       or, in the presence of the -S option,

           $ bk -R gfiles -pA | bk -R log ... -

SEE ALSO
       bk help commit, bk help changes, bk help log, bk help gfiles

CATEGORY
       Repository

BitKeeper Inc                         1E1                     bk pending(none)
$
help://port
help://port.1
help://bk-port
help://bk-port.1
bk port(none)               BitKeeper User's Manual              bk port(none)

NAME
       bk port - pull changes from a different nested collection or standalone

SYNOPSIS
       bk port [-CiqRsTu] [-c<n>] [-E<env>=<var>] [-r<rev>] <from>

DESCRIPTION
       bk  port  is  used  to  pull  changes from a related repository that is
       either in a different product or is a  standalone  repository.   It  is
       similar  to  bk  pull  but  differs  in that it can pull across product
       boundaries.

       If the destination is attached to a product, that  product  must  be  a
       portal.

       Changes are retrieved and automatically applied, if possible.  You will
       only  be  asked  to resolve conflicts by hand if a file has overlapping
       changes (changes where both repositories have touched the same line  in
       the same file).

       To see what would be ported run

           bk changes -SR <from>

OPTIONS
       -C            Do  not  commit  the  ported changeset[s] to the product.
                     Use this option when you wish to combine the  port  event
                     with other changes to the product.
       -c<n>         try  to  get  the  remote lock <n> times before giving up
                     (default forever).
       -E<env>=<val> Export environment variable to remote site.  The environ-
                     ment variable must start with BKU_.
       -i            Turn off automerge feature in  resolve.   For  each  file
                     with  parallel  work,  you  are  prompted  to examine the
                     changes and either manually or automatically merge  them.
                     Mutually exclusive with "-s".
       -q            Be quiet.
       -R            Do  not  run  resolve  at  all.   You must run bk resolve
                     later.
       -r<rev>       Pull up to and including this revision, but exclude later
                     changes.  (Or key or  changeset  revision.  See  bk  help
                     terms under 'rev argument')
       -s            Pass  "-s"  to  resolve ("-s" means do not do interactive
                     resolve of any conflicts, leave that for  later.)   Mutu-
                     ally exclusive with "-i".
       -T            Pass  "-T"  to  resolve  ("-T"  means  do not use the GUI
                     tools.)
       -u            Do not complete the port if there are  local  changesets,
                     i.e., insist that this operation is an update operation.

SEE ALSO
       bk  help  bkd, bk help changes, bk help parent, bk help portal, bk help
       pull, bk help resolve, bk help triggers, bk help unpull

CATEGORY
       Nested

BitKeeper Inc                         1E1                        bk port(none)
$
help://portal
help://portal.1
help://bk-portal
help://bk-portal.1
bk portal(none)             BitKeeper User's Manual            bk portal(none)

NAME
       bk portal - set or show the portal status of a nested collection

SYNOPSIS
       bk portal [-q] .
       bk portal [-q] -r

DESCRIPTION
       The bk portal command either reports whether the nested collection is a
       portal or it changes that nested collection to a portal.

       A  portal  nested  collection is part of BitKeeper's product line func-
       tionality.  There should be one, and only one, portal  for  any  nested
       collection.

       With  an argument of ".", this command marks the nested collection as a
       portal.  With no argument, the command prints the portal status.   With
       -q,  the exit status indicates portal status; 0 means it is, 1 means it
       is not.

       A component in a portal may be the destination of a  bk  port  command;
       non-portals  may  not be such a destination.  External repositories may
       be attached to a portal; non-portal attaches are not  allowed.   It  is
       suggested that creating and modifying aliases is done in the portal.

       For  any  given set of clones of a nested collection, only one instance
       should be a portal.  If multiple instances are marked  as  portals  the
       following are examples of problems that can, and likely will, occur:

       =>  The  same external repository could be attached multiple times.  To
           get rid of the name conflict when  these  collide  means  that  the
           product  will  need  to be run through bk csetprune which means the
           resulting instance will no longer interact with older instances.

       =>  The same changesets can be ported into  the  history  at  different
           points  in  time, creating what is called the "poly problem", where
           the same component changeset[s] belong to multiple product  change-
           sets.

RESTRICTIONS
       Inside  of  a portal, commands that would remove information are disal-
       lowed.  bk undo, bk collapse, bk unpopulate are examples of  such  com-
       mands.   It is common that many other clones depend on the portal to be
       a "safe" container of changes so removing information is not allowed by
       default.

       If it happens that a changeset gets pushed to a portal that really must
       be removed, then remove the portal status, undo (or unpull) the change-
       set, and put the portal status back.

OPTIONS
       -r  Unmark the current product as a portal.
       -q  Run silently.

SEE ALSO
       bk help attach, bk help gate, bk help port

CATEGORY
       Nested

BitKeeper Inc                         1E1                      bk portal(none)
$
help://prompt
help://prompt.1
help://bk-prompt
help://bk-prompt.1
bk prompt(none)             BitKeeper User's Manual            bk prompt(none)

NAME
       bk prompt - prompt a user with a message

SYNOPSIS
       bk prompt [<opts>] [<message>]

DESCRIPTION
       bk  prompt  is  used to prompt a user with a message, get a positive or
       negative response, and exit accordingly.

       This interface may be used for either command line or  graphical  envi-
       ronments.

       If  the  environment variable BK_GUI is set, then the graphical version
       will be used instead of the command line version.  All of the BitKeeper
       GUI tools set this variable automatically such  that  any  call  to  bk
       prompt  from  inside  the  graphical  tools  will result in a graphical
       prompt, including the execution of any user supplied triggers.

       If the environment variable BK_MSG_GEOM is set, the graphical tool will
       use the value of this variable to locate itself  on  the  screen.   The
       format  of  the variable must be in the form +x+y where <x> and <y> are
       screen coordinates.  bk citool sets this  variable  automatically  such
       that the prompt will be at the same x/y location as the upper left cor-
       ner of citool.

OPTIONS
       -c        Only for command line prompts, print the message and exit 0.
       -e        Indicates that the prompt is an error message.
       -f<file>  Specifies  the  file  contain  the  message  to be displayed.
                 Unless this option or the -p option is present, the last com-
                 mand line argument must be present and is used  as  the  mes-
                 sage.
       -g        Override  the BK_GUI variable and force a command line prompt
                 if called in a graphical context.
       -i        Indicates that the prompt is an informational message.
       -n<no>    If set, specifies the message for the label in the  graphical
                 tool which is to be used if the user does not agree.  Default
                 is "NO".  Not used in command line context.
       -o        OK  only, clears the default "NO" value.  Not used in command
                 line context.
       -p<prog>  If set, specifies a program which, when run, will produce the
                 message contents.
       -t<title> If set, specifies the title of the graphical  tool.   Default
                 is "BitKeeper Message".  Not used in command line context.
       -y<yes>   If  set, specifies the message for the label in the graphical
                 tool, or the prompt in the command line tool, which is to  be
                 used if the user does agree.  Default is "OK".
       -w        Indicates that the prompt is a warning message.

EXIT STATUS
       bk prompt returns exit status:

       0   if the user said yes
       1   if the user said no
       2   if an error occurred

SEE ALSO
       bk help citool, bk help triggers

CATEGORY
       File

BitKeeper Inc                         1E1                      bk prompt(none)
$
help://pull
help://pull.1
help://bk-pull
help://bk-pull.1
bk pull(none)               BitKeeper User's Manual              bk pull(none)

NAME
       bk pull - update a repository from its parent[s]

SYNOPSIS
       bk pull [-iqRsTuv] [-c<n>] [-r<rev>] [<parent> ...]

DESCRIPTION
       bk  pull updates a repository from its incoming parent[s].  Changes are
       retrieved and automatically applied, if possible.   You  will  only  be
       asked  to  resolve  conflicts by hand if a file has overlapping changes
       (changes where both repositories have touched the same line in the same
       file).

       To see what would be pulled run

           bk changes -aR

       bk pull normally runs  resolve,  the  tool  which  applies  the  pulled
       changes,  automatically.   Resolve  will look at each change, make sure
       there are no conflicts that it can't merge, and apply the change.   You
       may  have  to  (or  want  to) run resolve manually.  If you do not want
       automatic merges, i.e., you want to diff them by  hand,  then  use  the
       "-i"  option.  If resolve was run automatically and it found conflicts,
       the changes have not been applied; you will need to run an  interactive
       resolve to merge and apply the changes.

       You  can  override  the  default  parent by specifying a different one.
       Doing so changes the parent for the duration of this command only.

       If you've pulled in error you may use bk unpull to remove  the  change-
       sets  introduced  by  the pull.  Please read the bk unpull man page for
       important information about what is and is not unpulled.

SAFETY
       In non-nested BitKeeper, after you have pulled from a given repository,
       it is safe to delete the sending side as all the changes  it  contained
       have been transferred. This is not necessarily true in a nested collec-
       tion  since the set of components populated in the sending side and the
       set of components populated in the receiving  side  might  not  be  the
       same.

       In  order  to  solve  this problem, BitKeeper utilizes gates, which are
       repositories that you set up as permanent (e.g.  integration  reposito-
       ries  or  masters).  The URLs for the gates are remembered by BitKeeper
       and used when pulling from non-gate repositories.

       When pulling from a nested repository, if the sending side of the  pull
       is not a gate, BitKeeper will default to 'safe' mode. In safe mode, all
       components  populated  in  the sending side that are not found in gates
       are transferred to the receiving side.  This  preserves  the  attribute
       that  pulling  from  a repository transfers all unique information thus
       allowing the sending side of the pull to be deleted.

       When pulling from a gate, BitKeeper defaults to unsafe  mode.  In  this
       mode,  only the components that are populated in the receiving side are
       included in the pull. ChangeSets made to components in the sending side
       (the gate) that are not populated in the receiving  side  will  not  be
       transferred.  In  this case, removing the sending side (the gate) could
       result in lost work. Only mark as gates repositories that you know  are
       not going to be deleted.

       When  pulling  in  safe  mode, BitKeeper will try hard not to break the
       aliases in the sending side while  at  the  same  time  minimizing  the
       amount  of  information  that  needs to be transferred to the receiving
       side. This means that if the sending side has many  aliases  populated,
       and  only some of those would be sufficient to account for all the com-
       ponents with unique work, only those aliases would be transferred.

       An example: suppose the sending side has components A and B,  with  new
       work  in  both.   Suppose the receiving repository just has A.  Pulling
       from the sending side is considered "unsafe" when only the A csets  are
       sent but "safe" when the A csets and B component are sent.

OPTIONS
       --auto-populate automatically  populate missing components as needed to
                       perform a "safe" pull.

       --auto-port automatically turn the pull into a port  if  needed.
                   Only  works  in standalone repositories. Useful when
                   multiple parents are a combination of standalone and
                   components.
       --batch     Pass "--batch" to resolve ("--batch" means do not do
                   interactive resolve of any conflicts, leave that for
                   later.)  Mutually exclusive with "-i".
       -c<n>       try to get the remote lock <n> times  before  giving
                   up (default forever).
       -E<env>=<val>
                   Export  environment  variable  to  remote site.  The
                   environment variable must start with BKU_.
       -i          Turn off automerge feature  in  resolve.   For  each
                   file with parallel work, you are prompted to examine
                   the  changes  and  either  manually or automatically
                   merge them.  Mutually exclusive with "--batch".
       -q          Be quiet.
       -R          Do not run resolve at all.  You must run bk  resolve
                   later.
       -r<rev>     Pull  up to and including this revision, but exclude
                   later changes.  (Or key or changeset  revision.  See
                   bk help terms under 'rev argument')
       --safe      In a nested collection, using this option means that
                   the  source repository may be safely removed after a
                   successful pull.  Either  the  destination  received
                   everything  that  the  source had, or the non-pulled
                   components were found in a safe location  (a  gate).
                   This  option  is  implied when pulling from a nested
                   collection that is not a gate.  This option  has  no
                   effect  in a traditional standalone repository.  See
                   also --unsafe below.
       --stats     After finishing the  pull,  print  statistics  about
                   what  was  pulled. The format is compatible with the
                   output of bk diff --stats-only.  This option can  be
                   permanently turned on with the stats_after_pull con-
                   figuration  variable.  See  bk  help config for more
                   information.
       -T          Pass "-T" to resolve ("-T" means do not use the  GUI
                   tools.)
       -u          Do  not complete the pull if there are local change-
                   sets, i.e., insist that this operation is an  update
                   operation.
       --unsafe    In a nested collection, using this option means that
                   the  source  repository may contain work that is not
                   pulled into the destination.   --unsafe  means  pull
                   updates  only to the components and/or aliases popu-
                   lated in the destination.  This option has no effect
                   in a traditional standalone repository.  This option
                   is implied when  pulling  from  a  gate.   See  also
                   --safe above.
       -v          Be verbose by listing each file.

SEE ALSO
       bk  help  bkd, bk help changes, bk help gate, bk help parent, bk
       help push, bk help resolve, bk help triggers, bk help unpull

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                        bk pull(none)
$
help://push
help://push.1
help://bk-push
help://bk-push.1
bk push(none)               BitKeeper User's Manual              bk push(none)

NAME
       bk push - send local changes to parent repository

SYNOPSIS
       bk push [-aqT] [-E<env>=<var>] [-c<n>] [<parent> ...]

DESCRIPTION
       bk  push  sends changes in the current repository back to its parent[s]
       if and only if the current repository is  a  superset  of  the  parent.
       When  a parent has changes not found in the current repository, bk push
       will fail and you will need to do a bk pull, merge those  changes,  and
       retry  the  push.   The reason is that the parent is typically a shared
       resource and should not be locked for merging.

       If there is no new work in the parent, then all changes  in  the  child
       will be sent to the parent and auto-applied.

       To see what would be pushed run

           bk changes -aL

       You  can  override  the  default  parent by specifying a different one.
       Doing so changes the parent[s] for the duration of this command only.

       You can override the no-merge policy by going to the parent and doing a
       bk pull and specify the child as the bk parent.

OPTIONS
       -a            If the parent is ahead of your repository, turn the  push
                     into a pull to merge the new work in your repository.
       -c<n>         Try  to  get  the  remote lock <n> times before giving up
                     (default forever).
       -E<env>=<val> Export environment variable to remote site.
       -q            Run quietly.
       -T            Pass "-T" to bk resolve ("-T" means do not  use  the  GUI
                     tools)  during the pull operation (requires "-a" and that
                     the parent is a superset).

SEE ALSO
       bk help pull, bk help parent, bk help changes, bk help resolve, bk help
       triggers

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                        bk push(none)
$
help://pwd
help://pwd.1
help://bk-pwd
help://bk-pwd.1
bk pwd(none)                BitKeeper User's Manual               bk pwd(none)

NAME
       bk pwd - print directory name

SYNOPSIS
       bk pwd [-PRs] [<dir>]

DESCRIPTION
       The  bk  pwd  command is used to print the pathname to a directory.  If
       <dir> is supplied then that is the directory in question, otherwise the
       current working directory is used.  By default, the  full  pathname  to
       the directory is printed.

OPTIONS
       -P  Print  the relative path from the root of the product repository to
           the directory (when in a nested collection.  If not, same as -R).

       -R  Print the relative path from the root  of  the  repository  to  the
           directory.

       -s  Print the short form (aka 8.3 form) of the path.  (Windows only).

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk pwd(none)
$
help://r2c
help://r2c.1
help://bk-r2c
help://bk-r2c.1
bk r2c(none)                BitKeeper User's Manual               bk r2c(none)

NAME
       bk r2c - convert file revision to ChangeSet revision

SYNOPSIS
       bk r2c [-S] -r<rev> <file>

DESCRIPTION
       This command takes a revision and a filename and converts the specified
       revision into the changeset revision which contains the file revision.

OPTIONS
       -S
       --standalone  If  run in a component of a nested collection, convert to
                     component changeset, not the product changeset.   If  run
                     in a traditional repository or in the product of a nested
                     collection, this option has no effect.

EXAMPLES
       See the changeset that contains the tip delta of foo.c:

           $ bk changes -vr`bk r2c -r+ foo.c`

       Same thing, in a nested collection, for the product and component[s]:

           $ bk -P changes -vr`bk r2c -r+ foo.c`

SEE ALSO
       bk help c2r

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk r2c(none)
$
help://range
help://range.1
help://bk-range
help://bk-range.1
help://date
help://dates
help://ranges
bk range(none)              BitKeeper User's Manual             bk range(none)

NAME
       bk range - demo program to show ranges & dates

SYNOPSIS
       bk range [-qS] [-L[<url>] [-c<range> | -r<rev>] [<file> ... | -]

DESCRIPTION
       Many  commands  may take as arguments date ranges or graph differences.
       The graph difference between revision <B> and revision <A> is  the  set
       of  deltas  in  <B>'s  history  that are not in <A>'s history.  You may
       specify  deltas  by  revision  number  (1.2),  delta   key   ('amy@bit-
       keeper.com|man/man1/bk-terms.1|20020714011327|59990'),  a symbolic name
       (@tag), changeset revision (@1.33), or changeset  key  (@'lm@disks.bit-
       keeper.com|ChangeSet|20020912140445|17593').    The   graph  difference
       between revisions <B> and <A> is represented by the notation  <A>..<B>,
       as in:

           bk changes -r1.1820.2.1..1.1822

       See "graph difference" in bk help terms for more information.

       Dates are always specified as ranges; you can specify a date range this
       way:

           bk log -c1998..2002

       The date format is "<YYYY>/<MM>/<DD> <HH>:<M>:<SS>" with missing fields
       either  rounded  up  or  rounded down.  If you do not want to quote the
       date string, you can use a non-digit character, such as hyphen ("-") in
       its place, for example,  "2001/07/19-12:00:00".   Optionally,  you  can
       append  a time zone offset of the form -ZH:ZM for negative offsets from
       GMT or +ZH:ZM for positive offsets.  Date rounding  is  context  sensi-
       tive:  the starting date is rounded down and the ending date is rounded
       up,       so       2001..2001       is        the        same        as
       2001/01/01-00:00:00..2001/12/31-23:59:59.   A  single  date  is used as
       both     endpoints     so     2005/12     is      the      same      as
       2005/12/01-00:00:00..2005/12/31-23:59:59.

       Note: the mixing of dates and revisions is deprecated.

       If  there  is  only one date specified, without a revision, then a very
       useful form of the date is to specify a recent period of time, such as

           bk log -c-1d..

       which will display the last 24 hours worth of changes.  This works  the
       same way for Years/Months/days/hours/minutes/seconds, i.e.,

           In the last year:       log -c-1Y.. (or -1y..)
           In the last month:      log -c-1M..
           In the last week:       log -c-1W.. (or -1w..)
           In the last day:        log -c-1D.. (or -1d..)
           In the last hour:       log -c-1h..
           In the last minute:     log -c-1m..
           In the last second:     log -c-1s..

       If you leave off the multiplier, 1 is assumed.

       While  you  may not build up specific dates as -1Y2m3d, you can specify
       fractions, i.e., to get the last 6 months worth, try

           bk log -c-.5Y..

       Dates can also be in the form of symbolic tags (ChangeSet  file  only).
       If  you  tagged a changeset with Alpha and another changeset with Beta,
       you can type:

           bk changes -cAlpha..Beta
           bk log -r@Alpha..@Beta foo.c

       Ranges need not include both endpoints.  If you wanted  to  see  every-
       thing from Beta forward, you could type:

           bk changes -cBeta..

       A  single  "-r", because it is the first revision seen, rounds down and
       means 1.1.  To get the most recent delta, type "-r+".

OPTIONS
       -c<range>    Specify deltas by a date range
       --lattice    Restrict the deltas to those on the  lattice  between  the
                    two  range  endpoints.  Unlike a range, the lower bound is
                    included in the output.
       --longest    Restrict the deltas to those on the longest  line  between
                    the  two range endpoints.  Unlike a range, the lower bound
                    is included in the output.
       -q           run quietly; default is to warn about all files  which  do
                    not match the range
       -r<rev>      Specify deltas by revision number
       -S
       --standalone Use with -L in a nested component when you want the compo-
                    nent to act like a standalone repository.

SEE ALSO
       bk  help  annotate, bk help changes, bk help get, bk help diff, bk help
       log, bk help terms

CATEGORY
       Overview
       File

BitKeeper Inc                         1E1                       bk range(none)
$
help://receive
help://receive.1
help://bk-receive
help://bk-receive.1
bk receive(none)            BitKeeper User's Manual           bk receive(none)

NAME
       bk receive - receive a BitKeeper patch

SYNOPSIS
       bk receive [<takepatch_options>] [<repository>]

DESCRIPTION
       Use  when  applying  a BitKeeper patch you received via email.  You can
       take a BitKeeper patch and pipe the  whole  email  message  through  bk
       receive.  Headers and footers are stripped automatically.

       When someone sends you a patch with the following command:

           $ bk send -rbeta.. you@your.host.com

       You  will  receive  an email message which needs to be saved so you can
       feed it to the bk receive command:

           $ bk receive ~/mypackage < patch

       Many Unix email programs (pine, elm, etc) will allow you to pipe a mes-
       sage directly to a program. For example, when you are reading a message
       in pine, you can hit the '|' key, and you will be prompted with a  mes-
       sage asking you for a program name where the message should be piped.

       Remember that if you are getting the very first patch, you need to cre-
       ate  a new repository by adding the -i option.  BitKeeper does not cre-
       ate repositories by default.

       Specifying the repository is optional; if it is unspecified, bk receive
       tries to use the current working directory.

       Patches may be wrapped. If they are you will see something like

           ## Wrapped with uu ##

       near the top of the patch.  BitKeeper knows how to unwrap patches which
       it wrapped.  We currently support only uuencoded wrappers,  but  it  is
       trivial to create different ones, see bk wrap for more information.

       Once  a  patch  is  run through bk receive, run bk resolve to apply the
       changes.

OPTIONS
       All options are passed through to bk takepatch.  With  no  options,  bk
       takepatch  is  completely  silent.   If  you  want  to see the progress
       reports you see with bk pull, add -vv to the options.

       -a  Apply the changes (call bk resolve.)
       -c  Do not accept conflicts with this patch.
       -i  Initial patch, create a new repository.
       -v  Verbose level, more is more verbose, -vv is suggested.

SEE ALSO
       bk help range, bk help send, bk help takepatch, bk help wrap

CATEGORY
       File

BitKeeper Inc                         1E1                     bk receive(none)
$
help://regex
help://regex.1
help://bk-regex
help://bk-regex.1
bk regex(none)              BitKeeper User's Manual             bk regex(none)

NAME
       bk regex - demo program to show regular expressions in BitKeeper

SYNOPSIS
       bk regex <regex> <string> [<string ...>]

DESCRIPTION
       Some  commands,  most notably bk grep, can take a regular expression as
       an argument.  This man page describes the BitKeeper version of  regular
       expressions.   This command may be used to match a regex against one or
       more strings to see examples of how  the  regular  expression  matching
       works.

       Regular  expressions are used to search text for approximate (or exact)
       matches.  Knowing how regular expressions work can be useful, they  are
       quite  powerful.  Suppose that the words "foo," "bar," and "blech" were
       considered inappropriate in your source  tree;  the  following  command
       would find all files which contain any of those words:

           bk -U grep 'foo|bar|blech'

       BitKeeper  is compatible with the PERL regular expression syntax. For a
       quick start on PCRE, please see bk help pcre

CATEGORY
       Utility

BitKeeper Inc                         1E1                       bk regex(none)
$
help://relink
help://relink.1
help://bk-relink
help://bk-relink.1
help://hardlink
bk relink(none)             BitKeeper User's Manual            bk relink(none)

NAME
       bk relink - recreate broken hard links

SYNOPSIS
       bk relink [-q] <from> [<from2 ...>] <to>
       bk relink [-q]

DESCRIPTION
       The relink command is used to conserve disk space.  It is typical for a
       single  user to have many repositories, each one representing a differ-
       ent work in progress.  It is also typical to use the "-l" option to  bk
       clone  to  create  hard-linked  repositories.  A hard-linked repository
       uses much less space than a copied repository.  As files are  modified,
       the  links  are  broken.  As the same set of changes come into a set of
       repositories, the links could be restored.  That  is  what  the  relink
       command does.

       The  relink  command looks at each BitKeeper file in the <from> reposi-
       tory and if it is the same as the same file in the <to> repository,  it
       replaces the file in the <from> repository with a hard link to the file
       in the <to> repository.

       If  no  repositories are specified, then <from> defaults to the current
       repository and <to> defaults to all parent[s] of  the  current  reposi-
       tory.

OPTIONS
       -q  Run quietly.

WARNINGS
       While  hard-linked repositories are less disk intensive than replicated
       repositories, they are also more vulnerable to disk or file system cor-
       ruption.  It is advisable to always have at least one recent copy of  a
       repository, rather than 100% hard-linked repositories.

       It  is  possible  to  break  all  the links by recomputing the per file
       checksums:

           bk repocheck
           bk -A admin -z

NOTE
       This command works only on filesystems which support  hard  links,  and
       only if both repositories are in the same file system.

       On  recent  (2014)  versions of Ubuntu (and other Linux distributions),
       the use of hardlinks has been  curtailed  for  security  reasons.   See
       http://man7.org/linux/man-pages/man5/proc.5.html  and  search  for pro-
       tected_hardlinks.  The relink command will fail in this case.

SEE ALSO
       bk help clone

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk relink(none)
$
help://remerge
help://remerge.1
help://bk-remerge
help://bk-remerge.1
bk remerge(none)            BitKeeper User's Manual           bk remerge(none)

NAME
       bk remerge - redo the last merge

SYNOPSIS
       bk remerge [-T] <file> [<file> ...]

DESCRIPTION
       The  bk remerge looks at the specified file[s] and tries to remerge the
       last merge.  Each file may not be edited with  modifications  and  must
       have a merge as the most recent delta; files not meeting these require-
       ments are skipped.

       The  merged file is left as the current working file after the merge is
       completed.  The merge may be graphical (default) or text based.  In the
       latter case, the marked up file is left as the  working  file  and  you
       must manually edit it to complete the merge.

OPTIONS
       -T  Use a text based merge tool.

SEE ALSO
       bk help fm3tool, bk help smerge

CATEGORY
       File

BitKeeper Inc                         1E1                     bk remerge(none)
$
help://renames
help://renames.1
help://bk-renames
help://bk-renames.1
bk renames(none)            BitKeeper User's Manual           bk renames(none)

NAME
       bk renames - list file renames contained in one or more changesets

SYNOPSIS
       bk renames [-S] -r<rev>
       bk renames [-S] -r<rev>,<rev>

DESCRIPTION
       Show a listing of files that have been renamed as
       <oldname> -> <newname>

       The  optional  -S  flag will limit the listing to the current component
       repository.

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk renames(none)
$
help://renametool
help://renametool.1
help://bk-renametool
help://bk-renametool.1
bk renametool(none)         BitKeeper User's Manual        bk renametool(none)

NAME
       bk renametool - graphical tool for finding renames

SYNOPSIS
       bk renametool < <filelist>

DESCRIPTION
       The bk renametool command is a graphical interface for finding renames.
       bk  renametool  is  invoked automatically by the bk import command when
       importing patches.

       The purpose of this tool is to maintain revision  history  across  file
       renames.   A  repository which is managed entirely by BitKeeper manages
       revision history across file renames. However, a system managed by Bit-
       Keeper, but which imports traditional patches (i.e.  diff -Nur).  needs
       some help because patches do not directly record renames.

       Conceptually, a patch rename is seen as a deletion of one  file  and  a
       creation  of  another file.  When BitKeeper imports a patch, it detects
       the set of created and deleted files.  These files are then fed  to  bk
       renametool where you are given the chance to find files which are actu-
       ally renames and record that information.

       When  bk renametool starts up, you are looking at several text windows.
       The goal is to match up files in the create window with  files  in  the
       delete window.  You can click on files in each window and the tool will
       show  you diffs.  When you find two files which you think are the same,
       you can click the "rename" button to rename them and remove  them  from
       the  lists.  The "guess" button tries to find matches for you, based on
       the basename of the files.  When you  click  on  a  created  file,  the
       "guess"  button  is  invoked  once automatically.  You can click on the
       "guess" button again to find the next potential match.

       After you have matched up every file there is to match up, click  "cre-
       ate  all"  and "delete all" to finish up any stragglers, and then click
       apply.

BINDINGS
       Home       Scroll both diff windows to the top
       End        Scroll both diff windows to the bottom
       PageUp     Scroll both diff windows one screen up
       PageDown   Scroll both diff windows one screen down
       UpArrow    Scroll both diff windows one line up
       DownArrow  Scroll both diff windows one line down
       LeftArrow  Scroll both diff windows to the left
       RightArrow Scroll both diff windows to the right

       These bindings are the same as clicking the associated buttons:

       SPACE, n   Next diff
       a          Apply the actions in the Resolved files window
       C          Create all files in the Created files window
       c          Create the highlighted file in the Created files window
       D          Delete all files in the Deleted files window
       d          Delete the highlighted file in the Deleted files window
       g          Guess what the match might be
       h          Show history of the highlighted file in  the  Deleted  files
                  window
       p          Previous diff
       Control-q  Quit without applying any changes
       r          Rename the two marked files
       u          Undo the highlighted file in the Resolved files window

SEE ALSO
       bk help config-gui, bk help renames

CATEGORY
       GUI-tools

BitKeeper Inc                         1E1                  bk renametool(none)
$
help://renumber
help://renumber.1
help://bk-renumber
help://bk-renumber.1
bk renumber(none)           BitKeeper User's Manual          bk renumber(none)

NAME
       bk renumber - regenerate the revision history numbers

SYNOPSIS
       bk renumber [-nq] [<file> ... | -]

DESCRIPTION
       This  command  exists primarily because Sun's Teamware had some bugs at
       one point and put nonsensical revision numbers in the s.files.   Fortu-
       nately,  SCCS does not really care about the revision numbers, it main-
       tains the graph structure elsewhere.   This  program  uses  that  other
       information to start over and renumber the entire graph.

OPTIONS
       -n  do not do anything, dry run.
       -q  be quiet.

CATEGORY
       Utility

BitKeeper Inc                         1E1                    bk renumber(none)
$
help://repocheck
help://repocheck.1
help://bk-repocheck
help://bk-repocheck.1
bk repocheck(none)          BitKeeper User's Manual         bk repocheck(none)

NAME
       bk repocheck - check repository for consistency

SYNOPSIS
       bk repocheck [-qS] [--check_opts="options"]

DESCRIPTION
       bk  repocheck is used to make sure that a repository is in a consistent
       state.  It works in traditional  standalone  repositories  as  well  as
       nested collections.

       If  you  suspect  there might be a problem with your repository, run bk
       repocheck.  If you send email for support, please include the output of
       the following:

           bk version
           bk config
           bk repocheck

       This command is implemented on top of bk check.  The default, when run-
       ning a nested collection, is to run in parallel;  in  that  case  check
       output is suppressed unless there are errors.

OPTIONS
       --check-opts=<opts>
                     This  long option may be used to pass any valid option to
                     bk check.  The format must include the leading  -  or  --
                     for  each  option  and each option must be separated by a
                     space like so:

                         --check-opts='-fv -e'

       -q            Run quietly.
       -S            Just check the current repo.  This has  no  effect  in  a
                     traditional  standalone  repository, but in a nested col-
                     lection, this will check just the current repository, not
                     the entire nested collection.

SEE ALSO
       bk help check, bk help support

CATEGORY
       Repository

BitKeeper Inc                         1E1                   bk repocheck(none)
$
help://repogca
help://repogca.1
help://bk-repogca
help://bk-repogca.1
bk repogca(none)            BitKeeper User's Manual           bk repogca(none)

NAME
       bk repogca - show greatest common ancestor across a set of repositories

SYNOPSIS
       bk repogca [-d<spec>] [-5kS] [<repo> <repo> ...]

DESCRIPTION
       This  command  will print the latest revision in the current repository
       that exists in all of the the remote repositories either listed on  the
       command line or implied in the parent pointer[s].  By default, `bk par-
       ent` is the remote repository.

OPTIONS
       -d<spec>        Use  <spec>  as  the  specification  for displaying the
                       revision.
       --dspecf=<file> Like -d but read the dspec from a file.
       -5              A short hand for asking for a spec of ":MD5KEY:".
       -k              A short hand for asking for a spec of ":KEY:".
       -S              In a component in a nested collection, produce the repo
                       gca of the component instead of the  repo  gca  of  the
                       product.

EXAMPLES
       To  generate a traditional patch for the changes that exist only in the
       local repository:

           bk export -tpatch -r`bk repogca`,+ > patch

       To throw away all local work that doesn't exist in a remote repository:

           bk undo -a`bk repogca URL`

       Warning: This might also throw away some local csets which  also  exist
       in the remote repository.  That can happen if there are multiple common
       ancestors  on  different branches.  The ancestor chosen is the one cre-
       ated most recently.

SEE ALSO
       bk help gca, bk help log

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk repogca(none)
$
help://repos
help://repos.1
help://bk-repos
help://bk-repos.1
bk repos(1)                 BitKeeper User's Manual                bk repos(1)

NAME
       bk repos - command description

SYNOPSIS
       bk repos [-a | -m] [--check-all] [-q] [-v]
       bk repos [-c] <repo_path>
       bk repos [--raw]

DESCRIPTION
       BitKeeper remembers where repositories are by keeping a list of reposi-
       tory locations. When repositories are created (bk clone or bk setup) or
       are  checked  (bk  repocheck),  this  list is updated with the pathname
       along with some other metadata.

       The bk repos command shows and updates this list  of  repository  loca-
       tions.

       With  no  options,  the command will simply list repositories in alpha-
       betic order.  Prior to the output, repositories are checked  for  exis-
       tence and those found to be missing are pruned.

OPTIONS
       --check-all   Validate  that  all  the saved repository locations exist
                     and update their metadata.  Without the -q option, output
                     the updated list.
       -q            Allow the list to be updated but do not output anything.
       --raw         Output the list of repository locations without  checking
                     that  each still exists.  Useful in performance sensitive
                     (NFS) environments where testing each repository location
                     may be expensive.
       -a            Sort the output on access time.  Access time  is  defined
                     as  the time of any bk command having been run inside the
                     repository.
       -m            Sort the output on modification time.  Modification  time
                     is defined as the timestamp of the tip changeset.
       -c<repo_path> Update the list entry for this repository.
       -v            Output  all  of the data associated with each repository.
                     The format is:

                         PATH|ATIME|MTIME|MD5ROOTKEY

SEE ALSO
       bk help clone, bk help setup, bk help repocheck, bk help id

CATEGORY
       Utility

BitKeeper Inc                         1E1                          bk repos(1)
$
help://repotype
help://repotype.1
help://bk-repotype
help://bk-repotype.1
bk repotype(none)           BitKeeper User's Manual          bk repotype(none)

NAME
       bk repotype - display repository type

SYNOPSIS
       bk repotype [-q] [<directory>]

DESCRIPTION
       This command will print the type of the repository which is one of tra-
       ditional,  product, or component.  All repositories created by versions
       of BitKeeper prior to bk-5.0 are traditional standalone repositories.

       If a directory is specified then BitKeeper will change to  that  direc-
       tory before running the command.

OPTIONS
       Run quietly, exit status only.

EXIT STATUS
       When run without -q the exit status is 0 for all valid repositories and
       is 3 otherwise.  When run with -q bk repotype returns exit status:

       0   if run on a product repository
       1   if run on a component repository
       2   if run on a traditional (standalone) repository
       3   if run on a non-repository or if some other error occurs.

CATEGORY
       Utility

SEE ALSO
BitKeeper Inc                         1E1                    bk repotype(none)
$
help://resolve
help://resolve.1
help://bk-resolve
help://bk-resolve.1
bk resolve(none)            BitKeeper User's Manual           bk resolve(none)

NAME
       bk resolve - merge and/or apply new work after a pull

SYNOPSIS
       bk resolve [<options>] [<file> ...]

DESCRIPTION
       After  a  bk pull, use resolve to merge and/or apply new work.  Resolve
       is automatically run by the bk pull and bk push  commands  but  may  be
       rerun to finish a previously uncompleted resolve.

       In order to preview the new changesets before merging, run bk csets and
       that  will  run  csettool on the list of changes (which may be found in
       RESYNC/BitKeeper/etc/csets-in).

       Resolve traverses all files in the repository (or the specified set  of
       files),  prompting  you with a list of files needing to be merged.  The
       following are the stages when resolving files:

       => create and rename conflicts
       => mode conflicts (file permissions)
       => file flag conflicts
       => file content conflicts
       => symbol "conflicts" (local and remote added  the  "alpha"  symbol  to
          different deltas)

       When there are no conflicts left to be merged, resolve groups any merge
       changes into a changeset and moves everything into your repository.

       While it is OK to quit out of resolve without finishing, the repository
       will be locked and remain locked until you return to resolve and finish
       up the merge process.

       For detailed help on the merge process, see bk help resolving.

OPTIONS
       -a          Automerge.   This  will  run a diff3-like merge of all non-
                   overlapping lines.   If  there  are  overlapping  lines  in
                   merged files, the merge will fail and the files will not be
                   resolved;  you  have  to run resolve again without the "-a"
                   option to finish the resolve.
       -A          Auto advance.  Normally, when doing an interactive resolve,
                   the resolution is not complete until you tell the system to
                   commit the file ("C" in the content  resolve  menu).   This
                   allows for several false starts on a merge, you can use "m"
                   to merge, decide that you didn't like it, and use "m" again
                   to try over.  If "-A" is used, any sort of merge which com-
                   pletes is immediately used and the resolver advances to the
                   next file.
       -c          No conflicts.  This option tells resolve to complete if and
                   only if new non-conflicting work appears in the patch.
       -l<log>     Log  operations  to  <log>  (or stderr if no destination is
                   specified).  This option is to provide  for  audit  trails;
                   support is not yet complete.
       -m<merge>   Use  <merge> as the merge program called when you press "m"
                   in the content resolver.  The merge program takes four file
                   arguments: the local version of the file, the ancestor ver-
                   sion of the file, the remote version of the file,  and  the
                   merged  file.   It is the job of the merge program to merge
                   the changes into the merge file.
       -q          Be quiet.
       -r          Re-merge.  If you started to resolve, exited the  resolver,
                   and  then  restarted, files already merged will be skipped.
                   This options allows you to re-merge files which need  help,
                   yet  allows you to skip past the ones you are happy with by
                   hitting "C" in the resolve menu.
       --batch     do not do interactive resolve of  any  conflicts,  do  only
                   whatever can be automerged and then exit. (This was the old
                   -s option).  Implies "-a".
       -T          Text-only.  Enables  the text-based resolve menu when doing
                   the final commit instead of using citool.
       -x<glob>    Exclude (don't resolve) files  matching  the  glob  pattern
                   specified.   This  option  may be specified multiple times.
                   See RESOLVING SUBSETS section below.
       -y<comment> Use <comment> as  the  changeset  check-in  message.   This
                   option  is  typically  set  by  the  calling program, i.e.,
                   bk pull.  If <comment> is not present, resolve will  prompt
                   for one at commit time.

RESOLVING SUBSETS
       Include  and/or exclude patterns may be used to control which files are
       resolved.  This may be useful when unrelated changes by different engi-
       neers are being merged.  To see which files will need to be merged  run
       bk conflicts.

       There  may  be  multiple include and/or exclude patterns.  The patterns
       are a file glob the same as used by bk ignore.   Patterns  are  matched
       against  the  partial pathname from the root of the repository.  If the
       partial pathname matches any of the exclude patterns then the  file  is
       skipped.   If  there  are  one or more include patterns but the partial
       pathname does not match any of the include patterns then  the  file  is
       skipped.  Exclude processing takes precedence over include processing.

       If  there  are  renames  in the update and files which need renames are
       selected then the resolver will force the resolution of  those  renames
       first.   Currently, the include/exclude selection process is applied to
       the name used after the rename resolution, which can be confusing.   It
       may  be  easiest  to  run  the  rename resolution passes first with "bk
       resolve -12", list the conflicts with  bk  conflicts,  and  then  rerun
       resolve selecting the files to be resolved.

       bk  resolve  must  be run without specifying any subset of the files in
       order to fully complete.

PASSES
       The resolver currently has four passes (phases), each with a  different
       function.   A  given pass must be completed before the next pass can be
       started.  Using options listed below, the user can specify which passes
       are to be run on a particular invocation of the resolver.  By  default,
       the resolver attempts to complete all four passes.

       The first pass looks through both the incoming and local changes to see
       if  any  files  have  been  renamed.  If there are files that have been
       renamed, they are marked and put  in  a  special  BK-managed  namespace
       where they await rename processing.

       In  the second pass, the files marked and saved in pass 1 are inspected
       to see if there are any rename conflicts.   That  is,  if  a  file  was
       renamed  in  both  the  local  and remote repositories with a different
       pathname in each.  If this is the case, the user is prompted to resolve
       the conflict.  In the other cases, the resolver can infer  the  correct
       pathname and relocates the file out of the special BK-managed namespace
       and  into  the  proper place in the resolver working directory (usually
       named RESYNC).

       The third pass examines all files looking for content conflicts.   Con-
       tent  conflicts  arise when either the contents, symbolic link destina-
       tion, or file modes have been changed both  in  the  local  and  remote
       repositories.  These changes can be automatically resolved without user
       input  as  long  as the changes don't overlap.  In the case where auto-
       matic resolution is unsuccessful, the user is prompted to  resolve  the
       conflict manually.

       After all the conflicts have been resolved, the fourth pass attempts to
       apply  the  changes  to the local repository by moving the files out of
       the resolver working directory and into the local repository.  If  this
       cannot  be  completed  for  some  reason (permission problems, modified
       files in the local repository, etc.), the operation  is  aborted.   Any
       changes  made  to  the  local  repository are removed, and the resolver
       working directory is left intact.  The user can then fix  the  problems
       that caused the error, then re-run the resolver to apply the changes to
       the local repository.

SEE ALSO
       bk  help  conflicts, bk help csets, bk help pull, bk help push, bk help
       resolving

CATEGORY
       Repository

BitKeeper Inc                         1E1                     bk resolve(none)
$
help://resolving
help://resolving.1
help://bk-resolving
help://bk-resolving.1
help://merging
bk resolving(none)          BitKeeper User's Manual         bk resolving(none)

NAME
       bk resolving - help on resolving conflicts

DESCRIPTION
       This  section  documents  the merge process started by the resolve com-
       mand.  See bk resolve for details on using resolve.

       While in resolve, you can press ENTER to see a summary of the commands.

       The bk resolve command prompts you on each file that has conflicts.   A
       conflict is defined as two deltas made in parallel in different reposi-
       tories.   If  the conflict does not have any overlapping lines, then it
       may have been automerged, depending if bk resolve was run with the "-a"
       option.

       There are other sorts of conflicts besides  the  typical  file  content
       conflicts.   BitKeeper manages file names, permissions, flags, and sym-
       bolic tags in the same way as it manages  file  contents.   That  means
       that  you  can  have a permissions conflict if, for example, one person
       changed the file to 0755 mode and another changed it to 0777 mode.

       The resolve process for all conflicts is fairly similar.  For each type
       of conflict on each file, you will be prompted for an action.  To  view
       a  brief summary of the conflict and a list of available actions, press
       ENTER (or ?  or help).  The choices usually  include  a  more  detailed
       explanation  of  the situation; we try to consistently make this avail-
       able as the "x" command (as in eXplain).

       Some of the available actions allow you to diff the  files,  view  file
       history, and merge using graphical tools, etc.  See the command summary
       for the full list.

MULTIPLE USERS
       Only  one  user is allowed to run the resolver at any given time.  If a
       second user attempts to run bk resolve, they will get an error  message
       indicating that another user is already running the resolver.

       It  is also possible to have multiple users resolve a set of conflicts.
       A typical way to do this is to use the bk conflicts command  to  get  a
       list  of  files  that  need manual resolving along with a list of users
       responsible for the conflicting changes.  Then each  user  takes  turns
       invoking the resolver on the list of files for which they are responsi-
       ble,  checking  in  the changes as they go.  After the conflicts in the
       individual files have been resolved and checked in, the bk resolve com-
       mand is run with no arguments in order to finish the process and commit
       a changeset.  The changes for each file will be attributed to the  user
       that  committed that particular file.  The changeset will be attributed
       to the user that does the final commit of the changeset.

       In this context, as well as the  single  user  case,  it  is  sometimes
       desirable  to  quit  the resolver and restart it at a later time.  When
       the resolver is re-invoked, it will not ask the user to re-merge  files
       that  have  already been resolved and will continue where the user left
       off on the previous invocation.  This process can be repeated  as  many
       times as desired until all conflicts have been resolved.

VIEW DIFFERENCES AND HISTORY
       To  see the diffs use the "d" command.  For side-by-side diffs, use the
       "sd" command.  You can also diff one or the other branches against  the
       common ancestor using "dr" or "dl".  Type "D" to get a graphical, color
       coded side-by-side diff browser.

       There  are  also built-in commands to show the history of the file (see
       "h", "hl", "hr").  In addition,  "p"  starts  the  the  graphical  file
       browser  which  allows  you  to view the difference between versions by
       clicking the left button on the earlier rev and the right button  on  a
       later  rev.  The bottom of the screen will show the diffs.  If you type
       Return at the prompt, the three revisions forming the merge are part of
       the help message.

MERGING CONTENTS
       When in resolve, there are four different files for each  merge.   They
       are:

       local  The version of the file in the local repository.
       remote The version of the file in the other repository.
       merge  The merged file.
       GCA    A common ancestor of the local/remote versions.

       Your goal is to generate the merge file using one of the methods below.

       The easiest and most popular merge method is to use the "m" command for
       cases  where  there  are  no  overlapping lines. This method performs a
       three-way diff and merge and  warns  you  when  there  are  overlapping
       lines.   If  there  are overlaps, you have to edit the merged file (use
       the "e" command), find the conflict markers which look like  "<<<<"  or
       ">>>>",  and  manually  fix  the conflicts.  This command requires care
       since non-overlapping lines does not mean that the merge makes semantic
       sense.

       If the merge looks complicated, a good approach is to start up the file
       browser with "p" and then start up a side-by-side filemerge  with  "f".
       Then  walk  through the diffs, picking and choosing with blocks of code
       to use.  If you get confused about who added what, you can  go  to  the
       history tool browser (bk revtool) and left click on the common ancestor
       and  right click on each of the two tips of the trunk/branch to see who
       added what.

       It is also possible to use a combination of  graphical  tools  and  the
       automatic  merge.  You can type "p" to run the file browser, "D" to run
       difftool, "m" to do the merge, and then "e" to edit  the  merged  file.
       The  file browser is run in the background so you can look at the vari-
       ous changes as described above.  Warning: if you are running your  edi-
       tor  and the file merge program, then both are working on the same out-
       put file and whichever one writes it last, overwrites any earlier  ver-
       sions.

       You  may  also  call  an  external  tool to merge changes.  When in the
       resolver, if you say

           file.c>> !<command>

       then <command> will be run with  the  following  environment  variables
       set:

       BK_LOCAL  pathname of a temp file containing the local version
       BK_GCA    file containing the common ancestor
       BK_REMOTE pathname of a temp file containing the remote version
       BK_MERGE  pathname where the merged content should be placed

COMMIT
       The  merge  process  is not complete until you commit the file with the
       "C" command at the resolve prompt.  This means you can merge repeatedly
       until you are happy with the results.  Each time you  merge  and  save,
       however, you overwrite the previous merge attempt.

       When you are happy with your merged file, click done in filemerge, exit
       the  file  browser,  and  type "C" at the prompt to commit the file and
       move on to the next one.

SEE ALSO
       bk help conflicts, bk help fm3tool, bk help fmtool, bk help  merge,  bk
       help resolve, bk help revtool, bk help smerge

CATEGORY
       Overview
       Repository

BitKeeper Inc                         1E1                   bk resolving(none)
$
help://revtool
help://revtool.1
help://bk-revtool
help://bk-revtool.1
help://bk-sccstool.1
help://bk-sccstool
help://sccstool
bk revtool(none)            BitKeeper User's Manual           bk revtool(none)

NAME
       bk revtool - BitKeeper graphical history browser

SYNOPSIS
       bk revtool [-l<local>] [-r<remote>] <file>
       bk revtool [-r<rev>] [-S] [-/<string>/] [+<number>] [<file>]

DESCRIPTION
       bk  revtool  is  one of the primary tools used when doing code reviews,
       tracking down bugs, and when following the progress of a project.

       bk revtool shows checkin comments and the graph history of a project or
       file.  bk revtool may be used to view  any  revision  controlled  file,
       including  the  ChangeSet  file.  When no filename is given, the entire
       package history is shown.  In a nested collection, the  default  is  to
       show  the  product  changesets.   If  you wish to look at a component's
       changesets, go to that directory and run

           $ bk revtool -S
           or
           $ bk revtool --standalone

       The default behaviour for files, when double clicking on a line to view
       the changeset that created that line, is to zoom all the way out to the
       product changeset.  If you wish to restrict your view to the  component
       changesets:

           $ bk revtool -S some_file.c
           or
           $ bk revtool --standalone some_file.c

       bk  revtool  has an upper window which shows the graph of revision his-
       tory and a lower window which can show either the checkin  comments  or
       differences between versions.

HISTORY AND DIFFERENCES
       Upon  startup,  the  bottom window displays the recent revision history
       for the file or project. If a line number (+<number>) or search  string
       (-/<string>/)  is  specified on the command line along with a file name
       an annotated listing of the filename will be displayed instead.

       If a search string is given, the first occurrence of the search  string
       on or after the given line number will be highlighted and the text will
       be  scrolled  so  that  it  is  in view; if no line number is given the
       search begins with the first line. If a line number is given without  a
       search  string,  that  line  will  be  highlighted  and centered on the
       screen.

       To view the comments for just one revision, left  click  once  on  that
       revision in the graph.

       To  see  the  differences  between  two revisions, left click the older
       revision and right click on the newer revision.  The  differences  will
       be  displayed in the lower text window.  You can right click on another
       revision and diff again.  The default  diff  format  is  "-u"  (unified
       diffs).   The  text shown for the file is annotated with the user name,
       the latest revision that modified the line and the  revision  (if  any)
       that  deleted or excluded the line in the other version.  This helps to
       isolate which revision in a range removed a line.

       To see the contents of a file, double click the left  mouse  button  on
       the  revision  node in the graph.  The text shown for the file is anno-
       tated with the user name and the  latest  revision  that  modified  the
       line. The file text is generated with the "bk annotate -Aur" command.

       Once  the  annotated  file  listing is shown, you can then click on the
       text to view the checkin comments associated with the chosen line. Dou-
       ble clicking on an annotated line brings up bk csettool and  shows  all
       of  the  other  files  that  were modified in the same changeset as the
       selected line.

       To get a side-by-side view of the differences, select the two revisions
       and click on the "Diff tool" button.

CHANGESETS
       When operating on the ChangeSet file, the behavior is slightly  differ-
       ent.   Double-clicking  a revision displays the revision history of the
       changeset and the history of the changes to each file contained in that
       changeset.

       If you click left/right on a range of changesets, you will get the his-
       tory of the entire range of changesets.  To see  the  history  and  the
       differences  in detail, you can click on the "View changeset" button to
       bring up the changeset browser tool, bk csettool.  Typical usage is  to
       browse the ChangeSet file with bk revtool and drill down using bk cset-
       tool.

       When  viewing the ChangeSet file, nodes that have a tag associated with
       them will have a colored outline around them.  See  bk  config-gui  for
       more information.

BINDINGS
       The  scrollbars  can  be  used to orient the view of either window.  In
       addition, there are the following keyboard bindings:

       LeftArrow          Scroll graph window left 1 line.
       RightArrow         Scroll graph window right 1 line.
       Shift-LeftArrow    Scroll graph window left 1 screen.
       Shift-RightArrow   Scroll graph window right 1 screen.
       Shift-UpArrow      Scroll graph window up 1 line.
       Shift-DownArrow    Scroll graph window down 1 line
       Shift-PageUp       Scroll graph window up 1 screen.
       Shift-PageDown     Scroll graph window down 1 screen.
       Shift-Home         Scroll graph window to the first revision.
       Shift-End          Scroll graph window to the last revision.
       UpArrow            Scroll text window up 1 line (also Control-y).
       DownArrow          Scroll text window down 1 line (also Control-e).
       PageUp             Scroll text window up 1 screen (also Control-b).
       PageDown           Scroll text window down 1 screen (also Control-f).
       Home               Scroll text window to the top.
       End                Scroll text window to the bottom.
       s                  Show the raw SCCS file.
       a                  Show an annotated listing of the selected node.
       C                  Run bk csettool.  If the selected node in the  graph
                          is  for  a  changeset,  that  changeset will be dis-
                          played. If the selected node is a file, the  change-
                          set that introduces the selected version of the file
                          will  be displayed. If no node is selected this will
                          do nothing.
       c                  Show an annotated listing of  all  versions  of  the
                          file.  The data shown is the union of all lines ever
                          added  to  the  file  in  any  version,  deletes are
                          ignored.  Lines which were created at  a  particular
                          spot  in  the  file tend to be grouped together.  If
                          the line is not in the tip revision, this will  also
                          list which revision deleted or exclude the line.
       d                  Show  the  differences between the selected item and
                          its parent. If a graph node is selected, the differ-
                          ence between it and its parent are  shown.  However,
                          if  a  line  within  the  annotated  file listing is
                          selected, the difference between the selected  revi-
                          sion and its parent are shown.
       h                  Show the entire revision history comments.
       t                  Show  only  csets  that  have  a tag associated with
                          them.
       /                  Search the text window for a string.
       ?                  Reverse search.
       n                  Search for the next occurrence of the string.
       Control-q          Quit bk revtool.

SEE ALSO
       bk help Basics-Overview, bk help config-gui

CATEGORY
       Common
       GUI-tools
       Repository

BitKeeper Inc                         1E1                     bk revtool(none)
$
help://rm
help://rm.1
help://bk-rm
help://bk-rm.1
bk rm(none)                 BitKeeper User's Manual                bk rm(none)

NAME
       bk rm - remove BitKeeper file[s]

SYNOPSIS
       bk rm [-f] <file> [<file> ...]

DESCRIPTION
       To delete a file, do this:

           $ bk rm foo.c

       Removing  the  file  actually moves it to the BitKeeper/deleted/ direc-
       tory.  All future operations will ignore the file unless  you  name  it
       explicitly, but it will still exist in the repository and will still be
       propagated by bk pull and/or bk push.  Edited files may not be deleted,
       you must check them in first.

       If  you wish to obliterate all traces of a file, use the bk gone facil-
       ity.

       To resurrect the file, use bk unrm.

           bk unrm foo.c

NOTES
       bk rm will not remove directories, use bk rmdir for that.

       bk rm will refuse to remove BitKeeper metafiles without the "-f" option
       (the use of which is not recommended except in the case of triggers).

SEE ALSO
       bk help gone, bk help rmdir, bk help unrm

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                          bk rm(none)
$
help://rmdir
help://rmdir.1
help://bk-rmdir
help://bk-rmdir.1
bk rmdir(none)              BitKeeper User's Manual             bk rmdir(none)

NAME
       bk rmdir - remove a BitKeeper directory

SYNOPSIS
       bk rmdir <dir>

DESCRIPTION
       This command is used to delete entire subsections of a BitKeeper repos-
       itory.

       To delete a directory called A, do this:

           $ bk rmdir A

       This will call bk rm on each of the files in that subtree after verify-
       ing  that  there are no extra files, and no modified files in that sub-
       tree.

       The files are recoverable, none  of  the  BitKeeper  commands  actually
       remove  the  files, they are just moved to the BitKeeper/deleted direc-
       tory.

SEE ALSO
       bk help mv, bk help rm

CATEGORY
       File

BitKeeper Inc                         1E1                       bk rmdir(none)
$
help://rmgone
help://rmgone.1
help://bk-rmgone
help://bk-rmgone.1
bk rmgone(none)             BitKeeper User's Manual            bk rmgone(none)

NAME
       bk rmgone - remove files having keys in the gone file

SYNOPSIS
       bk rmgone [-nqS]

DESCRIPTION
       The bk rmgone command removes the sfiles and any gfiles associated with
       the keys listed in the gone file.

       Sfiles  may  be  removed and their keys added to the gone file with the
       gone command.  When the ChangeSet containing changes to the  gone  file
       is  pushed/pulled from another repository BitKeeper will issue warnings
       indicating that you have files matching things in the gone  file.   The
       bk  rmgone command may be used to remove the files in question and thus
       permanently stopping the warnings.

OPTIONS
       -n           Dry run.  Just print out the files that would be removed.
       -q           Run quietly.
       -S
       --standalone In a nested collection  the  bk  rmgone  command  normally
                    remove  all sfiles marked as gone in all components.  With
                    this option only the current component is checked for gone
                    sfiles.

WARNING
       This command cannot be undone.

SEE ALSO
       bk help gone

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk rmgone(none)
$
help://root
help://root.1
help://bk-root
help://bk-root.1
bk root(none)               BitKeeper User's Manual              bk root(none)

NAME
       bk root - print the path name to the root of the repository

SYNOPSIS
       bk root [-S] [<directory | file>]

DESCRIPTION
       This  command  prints  the full pathname to the root of the repository.
       The following commands are equivalent:

           bk root
           bk -P pwd

       If a directory or file is specified, bk  root  will  try  to  find  the
       project root of that file or directory.

       If bk root is run anywhere in nested collection, it will print the root
       of the product.  To print the root of a component use the -S option.

CATEGORY
       Admin

BitKeeper Inc                         1E1                        bk root(none)
$
help://rset
help://rset.1
help://bk-rset
help://bk-rset.1
bk rset(none)               BitKeeper User's Manual              bk rset(none)

NAME
       bk rset - list files in a cset or the difference between two csets

SYNOPSIS
       bk rset [-ahSU] [-s<alias>] -l<rev> | -R<rev> | -r<r1..r2>

DESCRIPTION
       bk rset is a tool that generates information about a particular change-
       set  (-l)  or  the differences between two changesets (-r/-R) in a form
       that can be passed to other tools (see examples below).

       The format is some variation of <pathname>|<revs> where the rev is usu-
       ally in the MD5 key format.  Because MD5 keys  are  long  (here's  one:
       37d3f5a9b3lm8Qx0jP8XDL8ULRE19A)  we  don't show actual keys, instead we
       show <md5A>..<md5B> in example output.

       To see the difference between a changeset and its parent:

           $ bk rset -R1.201
           ChangeSet|1.200..1.201
           src/Makefile|<md5A>..<md5B>

OPTIONS
       -a            Show deleted files which are normally suppressed.
       -h            Show the "historic" paths of the file as well as the cur-
                     rent path.  This makes  the  output  look  like  <current
                     path>|<start  path>|<rev>|<end  path>|<rev>.   The output
                     has three file names:   current,  starting,  and  ending;
                     corresponding  to  the  current pathname, the pathname of
                     the file at the start of the first changeset listed,  and
                     the  pathname  of the file at the end of the last change-
                     set.
                     For merge changesets, the format gets 2 more  fields  for
                     any  file  that  has different revs in the history of the
                     two parents, where neither rev is in the history  of  the
                     other.   For  these files, the output looks like <current
                     path>|<start1   path>|<rev1>|<start2    path>|<rev2>|<end
                     path>|<rev>.
       -l<rev>       list  the entire repository as of changeset <rev>.  Mutu-
                     ally exclusive with "-R".
       -r<r1..r2>    List the differences between changeset <r1> and changeset
                     <r1>.
       -R<rev>       List the differences between the  parent  or  parents  of
                     <rev> and <rev>.
       -s<alias>     In a nested collection, rset can recurse into some or all
                     of  the populated components.  Using the -s<alias> option
                     limits the repositories processed to those  specified  by
                     <alias>.   If  this option is repeated the implied subset
                     is the union of all specified components.  If no  <alias>
                     is specified that is taken to be the same as -sHERE.
       -S
       --standalone  Just  run  rset  on  the  current component.  This has no
                     effect in a traditional standalone repository, but  in  a
                     nested  collection,  processes just the current component
                     and not the entire nested collection.
       -U            User files only (like bk -U).  Does not list ChangeSet or
                     anything under BitKeeper/.

EXAMPLES
       Rset is a helper tool, it is used by other tools that want to show  you
       a  view  of  history.   For example, bk difftool -rbk-5.0..bk-6.0 calls
       rset to get the set of files to display.

       Quite a few of the BitKeeper commands can accept rset  input  to  drive
       them, some examples:

           bk rset -R+ | bk log -
           bk rset -UR+ | bk diff -

       The  documentation below is for script writers who may want to use rset
       to drive bk directly.

       To list all the files at their current location (less deleted files, -a
       will add those):

           $ bk rset -l+
           ChangeSet|+
           BitKeeper/etc/config|<md5>
           RELEASE-NOTES|<md5>
            ...
           src/gui/ChangeSet|<md5>
           src/gui/BitKeeper/etc/config|<md5>
           src/gui/csettool.tcl|<md5>
            ...

       Show the difference between a merge changeset and its parents:

           $ bk rset -R1.2104
           ChangeSet|1.2103,1.2058.7.1..1.2104
           src/libc/ChangeSet|<md5A>,<md5B>..<md5C>
           src/libc/utils/dirs.c|<md5A>,<md5B>..<md5C>
           src/libc/utils/fileops.c|<md5A>,<md5B>..<md5C>
            ...

       Show what is the difference between two changesets,  in  just  the  GUI
       components,  showing  historical  paths.   Note that this format is not
       parsed by most BitKeeper commands.  Also note in the example below sev-
       eral of the .tcl files have been renamed to .l files.

           $ bk rset -sGUI -h -rbk-6.0.2..bk-6.0.3
           src/gui/ChangeSet|src/gui/ChangeSet|<md5A>|src/gui/ChangeSet|<md5B>
           src/gui/common.l|src/gui/common.tcl|<md5A>|src/gui/common.l|<md5B>
           src/gui/difflib.l|src/gui/difflib.tcl|<md5A>|src/gui/difflib.l|<md5B>
           src/gui/fmtool.l|src/gui/fmtool.tcl|<md5A>|src/gui/fmtool.l|<md5B>
           src/gui/tcltk/Makefile|src/gui/tcltk/Makefile|<md5A>|src/gui/tcltk/Makefile|<md5B>
            ...

       Show the difference between a merge change  and  its  parents,  showing
       historic  paths.   For  files which changed on both sides of the merge,
       there will be 7 fields instead of 5.

           $ bk rset -h -R1.2503
           ChangeSet|ChangeSet|1.2502|ChangeSet|1.2468.1.270|ChangeSet|1.2503
           src/changes.c|src/changes.c|<md5A>|src/changes.c|<md5B>|src/changes.c|<md5C>
           src/sccs.h|src/sccs.h|<md5A>|src/sccs.h|<md5B>|src/sccs.h|<md5C>
           src/slib.c|src/slib.c|<md5A>|src/slib.c|<md5B>|src/slib.c|<md5C>
           src/t/ChangeSet|src/t/ChangeSet|<md5A>|src/t/ChangeSet|<md5B>|src/t/ChangeSet|<md5C>
            ...

SEE ALSO
       diff(1), patch(1), bk help export, bk help log, bk help range, bk  help
       terms

CATEGORY
       Utility

BitKeeper Inc                         1E1                        bk rset(none)
$
help://sane
help://sane.1
help://bk-sane
help://bk-sane.1
bk sane(none)               BitKeeper User's Manual              bk sane(none)

NAME
       bk sane - check for various BitKeeper requirements

SYNOPSIS
       bk sane

DESCRIPTION
       Run  this command from within a repository to check whether the reposi-
       tory is configured correctly.  bk sane checks  for  a  valid  hostname,
       username,  and  permissions  on  various  metadata directories, and the
       ability to lock the idcache.  If everything is sane, the command  exits
       with  a 0 exit status and no output.  If there are problems, a detailed
       error message is displayed on stderr and  a  non-zero  exit  status  is
       returned.

       When submitting bug reports, please include the output of this command.

SEE ALSO
       bk help sendbug

CATEGORY
       Admin

BitKeeper Inc                         1E1                        bk sane(none)
$
help://sccslog
help://sccslog.1
help://bk-sccslog
help://bk-sccslog.1
bk sccslog(none)            BitKeeper User's Manual           bk sccslog(none)

NAME
       bk sccslog - list deltas sorted by date across all files

SYNOPSIS
       bk sccslog [-bDfnS] [-c<d>] [-d<d>] [-L[<u>]] [-r<r>] [<file> ... | -]

DESCRIPTION
       bk  sccslog is used to get a time sorted listing of changes over all of
       the specified or implied files.  It is similar to bk log, with the dif-
       ference being that bk log respects file  boundaries,  i.e.,  lists  all
       changes in a file before going on, but bk sccslog sorts the changes and
       prints each change in time order, ignoring file boundaries.  It is use-
       ful to go to a directory and type:

           bk sccslog -c-1M..

       to see what has happened in all of the files there in the last month.

       By default, bk sccslog runs the output through your pager, which can be
       controlled with $PAGER.

OPTIONS
       -b              Show basenames instead of full pathnames.
       -c<dates>       Cut off dates.  See Range Specifications (below) or for
                       details.
       -D              Factor out duplicate comments and print the results as

                           libdiff.c, gnupatch.c:
                             add --minimal to calls to diff(1).

       -d<dspec>       Format  output  according  to  the  data  specification
                       string.  See bk log documentation  for  information  on
                       data specifications.
       --dspecf=<file> Like -d but read the dspec from a file.
       -f              Print the changes in forwards order (oldest to newest).
                       The default is backwards order.
       -L[<url>]       Show  all  deltas unique to this repository relative to
                       the (outgoing) parent or <url> if  one  was  specified.
                       May not be combined with -c, -C, or -r.
       -n              Add  a newline to each printed record (sometimes useful
                       with "-d").
       -r<r>           Specify a revision or a range.
       -S
       --standalone    Use  with  -L  in  a nested component when you want the
                       component to act like a standalone repository.

   RANGE SPECIFICATIONS
       -r+             prints the most recent delta
       -r1.3..1.6      prints all deltas that are in 1.6's  history,  but  are
                       not in 1.3's history.
       -c1992/07..1992 prints all deltas from July 1 '92 to Dec 31 '92
       -c1992..1992    prints all deltas from Jan 1 '92 to Dec 31 '92

SEE ALSO
       bk help changes, bk help log, bk help range

CATEGORY
       File

BitKeeper Inc                         1E1                     bk sccslog(none)
$
help://send
help://send.1
help://bk-send
help://bk-send.1
bk send(none)               BitKeeper User's Manual              bk send(none)

NAME
       bk send - send a BitKeeper patch

SYNOPSIS
       bk send [-dfqS] [-w<wr>] [-r<revs>] [-s<subject>] [-u<URL>] <u@h.ca>| -

DESCRIPTION
       The  bk  send  interface may be used to send changes through electronic
       mail.  In general, the bk push and bk pull interfaces are  the  easiest
       way to keep two repositories synchronized, but bk send requires only an
       email transport.

       To send the whole repository, do:

           $ bk send user@host.com

       BitKeeper will generate the (huge) patch and mail it to user@host.com.

       If you happen to know that you want to send changes that occurred after
       a  specific  changeset (and you know that the other repository has that
       changeset), you can do this:

           $ bk send -rbeta.. -s'Changes since beta' user@host.com

       or

           $ bk send -r1.10.. user@host.com

       Send remembers the changesets it has sent in BitKeeper/log/send-address
       where address is like user@host.com.  When you don't specify a list  of
       changesets  to send, "send" will look in the log file and send only the
       new changesets.  So the easiest thing to do is to always use  the  same
       email address and just say:

           $ bk send user@host.com

       If  you  lose the log file and you want to seed it with the changes you
       know have been sent, the command to do that is:

           $ cd BitKeeper/log
           $ bk changes -r<revs> -nd:KEY: > send-user@host.com

       An alternative to the log file approach, which may only be used if  you
       have  connectivity  to  the remote repository, is to talk to the remote
       repository to find out what needs to be sent.  The following will  send
       all the changes you have that the remote does not have:

           $ bk send -ubk://thunk.org:5000 tytso@mit.edu

       You  may wrap patches so that they do not get corrupted by mailers.  We
       currently support wrapping with uuencode.   The  following  (contrived)
       command  sends  a  wrapped patch and applies it in /tmp/foo (which must
       exist):

           $ bk send -wuu -r..1.5 - | bk receive /tmp/foo

OPTIONS
       -d          Prepend the patch with unified diffs.  This is because some
                   people like looking at the diffs to decide if they want the
                   patch or not.
       -f          send the patch even if BitKeeper believes the remote repos-
                   itory is up to date.
       -q          Be quiet.
       -r<revs>    Specify the list of changesets to send.
       -s<subject> Specify a subject line for the patch email.  Without  "-s",
                   the default subject line "BitKeeper patch" is used.
       -S          When used in a nested collection, send a patch only for the
                   component at the current working directory.
       -u<URL>     Instead  of  consulting the send log, connect to the remote
                   repository specified by the URL, figure out what  needs  to
                   be sent, and send it to the specified email address.
       -w<wr>      Wrap  the  patch  with <WR> before sending it.  The current
                   set of wrappers are:

                   b64       base-64 encoding
                   gzip_b64  gzip and base-64 encoding
                   gzip_uu   gzip and uuencode
                   uu        uuencode

SEE ALSO
       bk help range, bk help receive, bk help wrap

CATEGORY
       File

BitKeeper Inc                         1E1                        bk send(none)
$
help://sendbug
help://sendbug.1
help://bk-sendbug
help://bk-sendbug.1
bk sendbug(none)            BitKeeper User's Manual           bk sendbug(none)

NAME
       bk sendbug - file a bug report

SYNOPSIS
       bk sendbug [-T] [<email@host>]

DESCRIPTION
       File a bug or request for enhancement (RFE) against a project.

       The  default  behavior  is  to display the graphical version of sendbug
       when the DISPLAY environment variable is set (UNIX) or if it is run  on
       a  Windows operating system.  To use a text editor rather than the GUI,
       use the "-T" option.

       If email address is specified, the bug  will  be  sent  to  that  email
       address.

       This  command  should  be used to file a bug report rather then sending
       mail to one of the developers.

       The BitKeeper bug database is online at http://db.bitkeeper.com.

       The bug database is also available via email, consult the web page  for
       more information.

OPTIONS
       -T  Use  a  text  editor rather than the default graphical tool to fill
           out a bug report.

ENVIRONMENT
       REPLYTO submitter's email address

EXAMPLE
       An example text template looks like this:

       Bug/RFE:
               [bug is obvious, RFE is request for enhancement]

       Severity:
               [5 - no big deal, 1 - can't use BitKeeper until this is fixed]

       Priority:
               [5 - fix whenever, 1 - fix RIGHT NOW]

       Program:
               [cset, get, delta, etc.  If you know which caused the problem]

       Release:
               beta10-pre1

       OS:
               [Linux, IRIX, NT, etc]
       Etc.

       and the filled out report should look like this  (note  that  the  data
       goes after the tags, not on the same line):

       Bug/RFE:
               bug

       Severity:
               1

       Priority:
               1

       Program:
               sendbug

       Release:
               pre-2.0-2

       OS:
               All
       Etc.

CATEGORY
       Admin

BitKeeper Inc                         1E1                     bk sendbug(none)
$
help://service
help://service.1
help://bk-service
help://bk-service.1
bk service(none)            BitKeeper User's Manual           bk service(none)

NAME
       bk service - manage a bkd as a Windows service

SYNOPSIS
       bk service install [<name>] [<bkdargs>]
       bk service uninstall [-a] [<name>]
       bk service status [-a] <name>
       bk service list

DESCRIPTION
       The  BitKeeper  daemon, bkd, is used to synchronize and query reposito-
       ries.  See bk help bkd for information on the BitKeeper daemon.

       bk service is used to install (and start), uninstall (after  stopping),
       query  the  status  of  a  named  BitKeeper  daemon  (bkd), or list all
       installed daemons.  The main reason for using this interface is to  get
       a service that will be restarted on each boot.

MULTIPLE DAEMONS
       It is possible to install more than one BitKeeper daemon, which is use-
       ful  if  you want different permissions on different repositories.  All
       daemons must have a name, and the name must be unique across the set of
       BitKeeper daemons.  The default name is "BKD".  The names are stored in
       the registry and we suggest a single word, using mixed case if you want
       to a name like "MyBitkeeperDaemon".

       Some commands take an optional "-a" instead of a name which means oper-
       ate on all installed BitKeeper daemons.

PERMISSIONS
       By default, an installed service is run as LocalSystem which is a  sys-
       tem  user,  not  the  user who installed the service.  This can lead to
       problems if the BKD is used to serve up  repositories  created  by  the
       user with permissions restrictive enough that the LocalSystem user can-
       not access some or all the files in the repository.

       There are two ways around this problem, either create all the reposito-
       ries  through  the  BKD so they are all owned by LocalSystem, or change
       the service to be run as the user who owns the repositories,  described
       below.

RUNNING AS A SPECIFIC USER
       =>  The  user  account  must  have  a password.  If not, go to "Control
           Panel->User Accounts", select the  user,  and  create  a  password.
           Close that window.
       =>  The  user  account must be allowed to log on as a service.  This is
           not  on  by  default,  so  go  to  "Control   Panel->Administrative
           Tools->Local  Security  Policy->Local Policies" and double click on
           "User Rights Assignments".  Find "Log on as a service"  and  double
           click  that.   Click  "Add  User or Group" and add the user.  Close
           that window.
       =>  The service needs to be modified to run as the user.  Go  to  "Con-
           trol  Panel->Administrative  Tools->Services",  find  the BitKeeper
           daemon, double-click it.  Click "Stop" to stop  the  service,  then
           click  the  "Log On" tab, change from "Local System account" to the
           user, entering the password as well.   Click  "Apply".   Click  the
           "General"  tab  and then click "Start".  The daemon will restart as
           the selected user.

       After installing a service it is a good idea to test that it  works  by
       trying a clone, pull, and/or changes from a client.

NOTES
       This interface works only on Windows.

       Environment  variables  must  be  explicitly  passed on the bkd options
       list, i.e.,

           bk service DOCS -EBK_USER=docs -p8000

       The bkd service does not work when started from a network drive.

       The bkd service does not work when started from a subst'ed drive.

       bk uninstall may require a reboot in order  to  completely  remove  the
       service.

SEE ALSO
       bk help bkd, bk help Howto-bkd

CATEGORY
       Repository
       Admin

BitKeeper Inc                         1E1                     bk service(none)
$
help://set
help://set.1
help://bk-set
help://bk-set.1
bk set(none)                BitKeeper User's Manual               bk set(none)

NAME
       bk set - set operations

SYNOPSIS
       bk set [-adeklnosSx] [-r<rev>] [-t[<type>]] [<file>]

DESCRIPTION
       The  bk  set command performs set operations on a BitKeeper file.  This
       command provides the following  set  operations:  union,  intersection,
       difference and symmetric difference.  It also provides the member func-
       tion  (is  this element a member of the set?) as well as the list func-
       tion (list all sets which contain this member).

       If the file is not specified, it defaults to the ChangeSet file.

OUTPUT OPTIONS
       The default output is a list of revisions, one per  line.   The  output
       may  be  restricted  to  only  tagged revisions, and may be forced into
       revision, tag, or key format.  Note that only the  ChangeSet  file  may
       have  tags, which means that combining tag output format with a regular
       file has unexpected results.

       -k  list all answers as keys, not as tags or revisions.
       -n  prefix each output line with the filename, i.e., ChangeSet|1.3,  so
           that the output may be fed to other programs, such as bk log.
       -t  list all answers as tags where possible, else revisions.
       -tt list  only those answers which are tagged and list those as the tag
           not the revision.
       -tr list only those answers which are tagged but list  those  as  revi-
           sions.
       -tk list only those answers which are tagged but list those as keys.

SPECIFYING SETS
       If  a  revision  is specified for a set argument, the set is the set of
       deltas which make up that revision.  For example, in a  simple  history
       without  branches,  revision  1.5  implies the set {1.1, 1.2, 1.3, 1.4,
       1.5}.  A revision may be specified as a revision, as a symbolic tag, or
       as a BitKeeper key.  It may also be specified as a "-", for the  second
       set  only,  in  which  case it expects a list of revisions (or keys) on
       stdin, one per line.

SET OPERATIONS
   UNION (<setA> | <setB>)
       bk set [<output opts>] -o <setA> <setB> [<file>]

       The union operation, familiar to programmers as a "bitwise  or",  lists
       all members which occur in either set.

   INTERSECTION (<setA> & <setB>)
       bk set [<output opts>] -a <setA> <setB> [<file>]

       The  intersection operator, familiar to programmers as a "bitwise and",
       lists all members which occur in both sets.

   DIFFERENCE (~<setA> & <setB>)
       bk set [<output opts>] -d <setA> <setB> [<file>]

       The difference operator lists all members in  setB  which  are  not  in
       setA.   This is the most useful of the set operations, see the examples
       below.

   SYMMETRIC DIFFERENCE (<setA> ^ <setB>)
       bk set [<output opts>] -x <setA> <setB> [<file>]

       The symmetric  difference  operator,  familiar  to  programmers  as  an
       "exclusive  or",  lists  all members which occur in only one of the two
       sets.

   ELEMENT
       bk set [<output opts>] -e -r<rev> <setA> [<file>]

       The element operator treats the specified revision as a single element,
       not as an implied set, and lists the element if it is in the set.

   LIST
       bk set -l -r<rev> [<file>]

       The list operator treats the specified revision as  a  single  element,
       not  as an implied set, and lists all sets (as revisions) which contain
       the element as part of their set.  It is typically used to see if a bug
       fix is in a particular release.  If the  changeset  has  been  excluded
       from  a  later  changeset, the later changeset and its descendants will
       not be listed.

   SET
       bk set -s -r<rev> [<file>]

       The set operator treats the specified revision as a set, and lists  all
       elements of that set.

NESTED
       The set command will look at the product changeset file by default.

       -S  perform the set operation on the current component.

EXAMPLES
       A  good  use of this command is the generation of release notes.  To do
       so, pick the starting and ending points and do this:

           $ bk set -d -rbk-2.0 -rbk-2.0.1 | bk changes -
           ChangeSet@1.1425.5.19, 2001-10-12 15:18:06, lm@work
             utils.c:
               Remove debugging.
               Sleep 50 milliseconds when waiting for the lock.

           ChangeSet@1.1425.5.20, 2001-10-15 15:57:42, lm@disks
             A weekend's worth of testing of locking over NFS
             turned into this cset.

           ChangeSet@1.1425.5.21, 2001-10-16 08:35:26, lm@disks
             The cset lock was too fine grained.
             This is a short term fix,
             the longer term fix is the per file locking
             Andrew is working on.
             TAG: bk-2.0.1

       To see the tagged releases which contain bk-2.0.3:

           $ bk set -l -tt -rbk-2.0.3
           bk-2.0.3
           bk-2.0.4
           bk-2.0.4b
           bk-2.1.2
           bk-2.1.3
           bk-3par_merge
           bk-3par_merge2

SEE ALSO
       bk help changes, bk help log

CATEGORY
       Utility

BitKeeper Inc                         1E1                         bk set(none)
$
help://setup
help://setup.1
help://bk-setup
help://bk-setup.1
help://init
bk setup(none)              BitKeeper User's Manual             bk setup(none)

NAME
       bk setup - create a new BitKeeper package

SYNOPSIS
       bk setup [-CfpP] [-F<key=val>] [-c<config_file>] [<directory>]

DESCRIPTION
       There is a graphical version of this command, bk setuptool.

       To  set up a BitKeeper package, you need to create and populate an ini-
       tial tree.  If the <directory> argument is supplied, the bk setup  com-
       mand will create a mostly empty package tree containing a few files and
       directories  that  are  used  by  BitKeeper. Otherwise, a new BitKeeper
       package will be created in place.

       A system wide default config template file may  be  created  in  either
       `bk dotbk`/etc/config.template,  /etc/BitKeeper/etc/config.template, or
       `bk bin`/etc/config.template.  If any of these files is  detected  when
       bk  setup  is run, without the "-c" option, the keys in it will be used
       as the defaults in the BitKeeper/etc/config  file  automatically.   The
       first file found is used.

OPTIONS
       -C              When  run  inside a product, setup will create a compo-
                       nent.  With -C, do not commit this new component to the
                       product.  Use this option when you wish to create  many
                       components and have only one commit.  The new component
                       will  be  left in the pending state.  The -C option can
                       not be used with -P.  In all  other  cases  (outside  a
                       product and with no -P), the -C option will be ignored.
       -c<config_file> Use  <config_file>  as  the configuration file to setup
                       the repository.
       --compat        Create the package using a  backwards  compatible  (and
                       slower) format.
       -f              Don't ask for confirmation.
       -F<key=val>     Override default values for the specified field.  Typi-
                       cally used in combination with a config template.
       -P              The  repository  being created is a product repository,
                       i.e., will have component repositories.
       -p              print the field names to stdout (used by setuptool).

EXAMPLES
       When creating a repository called "mypackage", you type  the  following
       command:

           $ bk setup ~/mypackage

       The following shows the directory structure of a new package.

       mypackage/

               .bk/              Directory for storing BitKeeper metadata.
               ChangeSet         Index of all changes to the repository.
               BitKeeper/        Directory   where  administrative  files  are
                                 kept.

                       etc/      Config files, in the future, policy files.
                       log/      Mail and command logs, parent pointer.
                       deleted/  Deleted files are  archived  here  (like  CVS
                                 Attic).
                       tmp/      Scratch area.
                       readers/  Transient directory for reader locks.
                       writer/   Transient directory for writer lock.
                       triggers/ Executable trigger programs stored here.

       Once  the  repository  is created, you should make a hierarchy to store
       your source files. For example, you could create the following tree:

       mypackage/

               src/              source code
               man/              manual pages
               doc/              user guides, papers, docs...

       At this point, if you are creating a new package from  scratch,  cd  to
       ~/mypackage/src  and start creating files.  See bk help Basics-Overview
       and bk help Howto-setup for more info.

       If you have an existing set of files that you want to add to the repos-
       itory, see bk import.

SEE ALSO
       bk help Howto, bk help Howto-setup, bk help attach, bk help config-etc,
       bk help import, bk help setuptool

CATEGORY
       Nested
       Repository

BitKeeper Inc                         1E1                       bk setup(none)
$
help://setuptool
help://setuptool.1
help://bk-setuptool
help://bk-setuptool.1
bk setuptool(none)          BitKeeper User's Manual         bk setuptool(none)

NAME
       bk setuptool - graphical front-end to the BitKeeper setup command

SYNOPSIS
       bk setuptool [<directory>]

DESCRIPTION
       The bk setuptool command is a graphical interface for creating new Bit-
       Keeper repositories.

       The  purpose  of  the  tool is to help you enter all of the information
       needed to create a repository by stepping you through a series of input
       forms and prompts.

       You will be prompted for additional information that will be stored  in
       the  config  file  for  the repository. Different types of repositories
       will require slightly different sets of data.

       After all information has been entered you will have a chance to review
       the information that will be put into the config file before the repos-
       itory is created. When the repository is created, the  config  file  is
       stored as a normal revision controlled file so that you may go back and
       edit the file at a later date.

       If  you  will  be  creating several repositories that will use the same
       configuration information (such as contact information) you may  create
       a  system-wide  default  config  file in /etc/BitKeeper/etc/config.tem-
       plate.  This has the same format as a regular config file.   bk  setup-
       tool will look for this file and, if found, use the data in the file to
       set the default values when creating a new repository.

EXAMPLES
       To create a repository named /projects/helloworld, you type the follow-
       ing command:

           bk setuptool /projects/helloworld

       This  will  prompt  you for information to place in the config file and
       then create a project hierarchy rooted  at  /projects/helloworld.   The
       config  file  with the data you entered is in /projects/helloworld/Bit-
       Keeper/etc/config.

       You do not need to include the name of a directory on the command line.
       If you do not include it you will be required to enter  a  name  during
       one of the configuration steps.

BINDINGS
       ENTER Perform  the  default  action,  which is either to go to the next
             step, or create the repository if on the final step.
       TAB   Moves between input fields.

       You may also use your system's cut, copy and paste keys  in  the  input
       fields.

SEE ALSO
       bk help config-etc, bk help setup

CATEGORY
       GUI-tools
       Repository

BitKeeper Inc                         1E1                   bk setuptool(none)
$
help://sfio
help://sfio.1
help://bk-sfio
help://bk-sfio.1
bk sfio(none)               BitKeeper User's Manual              bk sfio(none)

NAME
       bk sfio - BitKeeper file archiver

SYNOPSIS
       bk sfio [-qm] -i < <archive.sfio>
       bk sfio [-m] -p < <archive.sfio>
       bk sfio [-qmf] -o < <filelist>

DESCRIPTION
       The  bk  sfio command is similar to cpio(1).  It exists because we were
       unable to find a single CPIO format which was portable  across  all  of
       our supported platforms.

       bk  sfio  is  used  to transfer data during bk import and bk clone com-
       mands.

       There are three ways to run sfio, as listed above.  The  first  creates
       files from an archive, the second lists the contents of an archive, and
       the third creates an archive from the specified list of files.

OPTIONS
       -e  Echo  mode. After each file is archived or extracted print the file
           to stdout.  This is separate from the print to stderr controlled by
           "-q".  It is intended to be used by programs that want  to  perform
           actions after each file is unpacked when reading over a slow pipe.
       -i  Extract all files from the archive.
       -m  Transfer  file  modes  (default  not to do so).  If the archive was
           created with "-m" then it must be extracted with "-m".  We will not
           turn this on by default, transferring the file modes is not  always
           the correct answer so we force it to be explicit.
       -o  Create an archive.
       -p  List contents of an archive.
       -q  Quiet mode, when combined with the create or extract, does not list
           files as they are added or extracted.
       -f  Force  mode,  when  combined  with extract, will overwrite existing
           files that exist in the archive.

NOTE
       "-m" will become the default in a future version of bk sfio.

CATEGORY
       Repository

BitKeeper Inc                         1E1                        bk sfio(none)
$
help://smerge
help://smerge.1
help://bk-smerge
help://bk-smerge.1
bk smerge(none)             BitKeeper User's Manual            bk smerge(none)

NAME
       bk smerge - smart text-based 3-way file merge

SYNOPSIS
       bk smerge [-2efghn] [-A<n>] [-a<n>] -l<local> -r<remote> <file>

DESCRIPTION
       The bk smerge command compares the three versions of the file and iden-
       tifies  all  changes  by  either the local or the remote version of the
       file compared to the greatest common ancestor (gca).  These  groups  of
       changes are known as conflict regions and are bounded by a line that is
       identical in all three versions at the beginning of the conflict region
       and at the end of the conflict region.  For each region, one or more of
       the  automerge algorithms (see below) are run to see if the changes may
       be merged automatically.

       The bk smerge command does not  use  the  traditional  diff3(1)  merge.
       There  are  a  number  of heuristics in the default enabled merge algo-
       rithms which help determine regions which are safe to automerge.  These
       can simplify and resolve many conflict regions that can not be resolved
       in the traditional diff3(1) merge.  Please note, smerge can only be run
       on SCCS files.

       In some scripts users may want to call  smerge  directly.   If  so,  an
       example for usage is:

           bk smerge -g -l1.661 -r1.660.1.4 slib.c > slib.c.merged

       where 1.661 is the local revision and 1.660.1.4 is the remote revision,
       slib.c  is  the  file name and slib.c.merged is the file to which merge
       output is redirected.

       The string for the  local  or  remote  versions  of  the  file  can  be
       expressed  in  the  form  "rev+includes-excludes" where rev is a normal
       revision number like "1.661" and includes and excludes are a comma sep-
       arated list if revisions to include or exclude from the base  revision.
       (The include and/or exclude lists can be omitted if they are empty.)

MERGE ALGORITHMS
       Each of the automerge algorithms is described below.  Currently, all of
       these  are  run by default, but that may change in the future.  Any mix
       of these may be selectively enabled or disabled.

       1. Merge identical changes made by both sides
           If both the local and the  remote  files  have  made  an  identical
           change  to  the GCA, then this function will resolve the region and
           replace it with the new text.
       2. Merge when only one side changes
           This code finds conflict regions where only the local or the remote
           version has made  any  changes.   In  this  case  the  conflict  is
           resolved  and the side that made changes is kept.  This is the tra-
           ditional diff3(1) type automerge algorithm.
       3. Merge adjacent, non-overlapping modifications on both sides
           This code attempts to find a conflict consisting of a text  substi-
           tution  in  both the local and remote versions of the file.  A sub-
           stitution is a line or group of lines  that  is  deleted  and  then
           replaced  with  zero  or more lines.  If there is a conflict region
           that contains lines substituted in the local file that are  unmodi-
           fied  in  the  remote and there are lines substituted in the remote
           file that are unmodified in the local file, then a merge of the two
           substitutions is performed.

           Here is an example of a conflict region (in the "-g" output format)
           where this algorithm will successfully resolve the conflict.

               <<<<<<< local slib.c 1.642.1.6 vs 1.645
                    sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, s->proj);
               -    assert(sc->tree);
               -    sccs_sdelta(sc, sc->tree, file);
               +    assert(HASGRAPH(sc));
               +    sccs_sdelta(sc, sccs_ino(sc), file);
               <<<<<<< remote slib.c 1.642.1.6 vs 1.642.2.1
               -    sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, s->proj);
               +    sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, p);
                    assert(sc->tree);
                    sccs_sdelta(sc, sc->tree, file);
               >>>>>>>

           The block after the resolve will be:

                    sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, p);
                    assert(HASGRAPH(sc));
                    sccs_sdelta(sc, sccs_ino(sc), file);

           Multiple substitutions are not yet handled.
       4. Merge identical changes at the start of a conflict
           This code recognizes one or more lines at the beginning  the  local
           and  remote  versions  of a conflict region that are identical.  If
           there is a block of lines that are identical  then  the  region  is
           split  into  two  regions  with  the identical lines in a region by
           themselves.  This block will later be resolved by algorithm #1.
       5. Merge identical changes at the end of a conflict
           This is similar to algorithm #4,  except  it  looks  for  identical
           lines on both sides at the end of the conflict region.
       6. Merge identical deletions made by both sides
           If  both  the local and remote version of a region have deleted the
           same non-zero block of lines at the end of the region,  then  split
           the  region  into two with the deletions in a separate region.  The
           deletions will then get autoresolved.

       When a conflict regions is identified, then the enabled algorithms  are
       run  on  the block repeatedly until the block is resolved or no further
       progress is made.

       Default conflict output format is as follows:

           <<<<<<< gca slib.c 1.642.1.6
                sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, s->proj);
                assert(sc->tree);
                sccs_sdelta(sc, sc->tree, file);
           <<<<<<< local slib.c 1.645
                sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, s->proj);
                assert(HASGRAPH(sc));
                sccs_sdelta(sc, sccs_ino(sc), file);
           <<<<<<< remote slib.c 1.642.2.1
                sc = sccs_init(file, INIT_NOCKSUM|INIT_SAVEPROJ, p);
                assert(sc->tree);
                sccs_sdelta(sc, sc->tree, file);
           >>>>>>>

       Lines with "<<<<<<<" indicate the file the conflict region is  from  in
       the  form:  <<<<<<<  <label> <file> <revision> followed by the conflict
       lines from that file.  The end of the conflict region is  indicated  by
       ">>>>>>>".  Examples of conflict output can be viewed by using the "-e"
       option.

OPTIONS
       -2     Enable the 2 way output format (like diff3(1)).
       -g     Enable 'gca' output format that shows the local and remote files
              like  a unified diff between the GCA and that file.  This is the
              recommended output format, but not the default because  it  con-
              fuses people the first time they see it.
       -n     Enable  the 'newonly' output format.  (like "-2" except it marks
              added lines).
       -e     Print examples of all 4 output formats from bk smerge.
       -a<n>  Enable merge functions <n>, where <n> is a comma separated  list
              of  automerge  algorithms  specified  by number.  "-a<all>" will
              enable all automerge algorithms.  Use "bk smerge -h" to find the
              algorithms enabled by default.
       -A<n>  Disable merge functions <n>, where <n> is a comma separated list
              of automerge algorithms specified  by  number.   "-A<all>"  will
              turn off all automerging.
       -f     Enable fdiff output.  (Used internally by bk fm3tool)
       -h     Display  automerge  algorithms  by  number  that  are enabled by
              default.  If used in conjunction with "-a"  or  "-A",  asterisks
              denote enabled algorithms.

EXIT STATUS
       bk smerge returns exit status:

       0   if there were no conflicts
       1   if there were conflicts
       2   if an error occurred

SEE ALSO
       diff3(1), bk help resolve, bk help resolving, bk help merge

CATEGORY
       Utility

BitKeeper Inc                         1E1                      bk smerge(none)
$
help://status
help://status.1
help://bk-status
help://bk-status.1
bk status(none)             BitKeeper User's Manual            bk status(none)

NAME
       bk status - show repository status

SYNOPSIS
       bk status [<repository>]

DESCRIPTION
       The  bk status command gives a quick overview of the current (or speci-
       fied) repository.

OUTPUT
       The default output looks something like:

           Repo: hobbes.bitkeeper.com:/home/lm/bk/dev
           Nested: 22/22 components present
           Push/pull parent: bk://work.bitkeeper.com/dev
                13 csets to be pulled
           4 locally modified files
           Repo attributes: level=3, GATE, PORTAL
           BK version: bk-7.0.1 (repository requires bk-7.0 or later)

NOTE
       The current output format is preliminary and may change in the future.

SEE ALSO
       bk help gfiles

CATEGORY
       Repository

BitKeeper Inc                         1E1                      bk status(none)
$
help://stripdel
help://stripdel.1
help://bk-stripdel
help://bk-stripdel.1
bk stripdel(none)           BitKeeper User's Manual          bk stripdel(none)

NAME
       bk stripdel - strip deltas out of an s.file

SYNOPSIS
       bk stripdel [-bCcdq] [-r<rev>] <filename>

DESCRIPTION
       The  bk stripdel command is used to "strip" deltas from a revision his-
       tory.  The deltas, once stripped, are not recoverable.

       This command is typically called by the bk clone or the  bk  undo  com-
       mands, and perhaps the bk import command.  It can be called directly if
       you wish to remove certain deltas from a file.

       The  bk  stripdel  command  will  fail  if  the specified revisions are
       included in a changeset and the "-C" option is not present.

WARNING
       It is an extremely bad idea to use the "-C" option, it can corrupt your
       repository.  Instead, consider the "-x" option of bk get.

OPTIONS
       -C      Do not respect cset boundaries, used by bk undo.
       -c      Checks if the specified rev[s] can be stripped but do not strip
               them.
       -d      Strip deltas which are part of a MONOTONIC file.
       -q      Run quietly.
       -r<rev> Set of revisions to be removed.

SEE ALSO
       bk help admin, bk help clone, bk help get, bk help undo

CATEGORY
       File

BitKeeper Inc                         1E1                    bk stripdel(none)
$
help://superset
help://superset.1
help://bk-superset
help://bk-superset.1
bk superset(none)           BitKeeper User's Manual          bk superset(none)

NAME
       bk superset - check to see if the parent is ahead of the current repos-
       itory

SYNOPSIS
       bk superset [-q] [<parent>]

DESCRIPTION
       bk  superset does checks to see if removing the current repository is a
       lossless event.

       It checks that:

       =>  there are no local only changesets and/or tags
       =>  there are no pending deltas
       =>  there are no modified files
       =>  there are no extra files
       =>  there are no pending patches from aborted pulls
       =>  there are no unresolved pulls
       =>  there are no saved patches from a bk collapse operation
       =>  there are no saved patches from an undo/unpull operation
       =>  if there are sub-repositories and no parent was  specified  in  the
           call  to  bk superset, then the sub-repositories are also similarly
           checked against their parent

       Unless the "-q" option is present, bk superset lists  all  things  that
       are not in the parent.

OPTIONS
       -q  Be quiet

EXIT STATUS
       bk superset returns exit status

       0   if the parent is a superset
       1   if the parent is not a superset

CATEGORY
       Repository

BitKeeper Inc                         1E1                    bk superset(none)
$
help://support
help://support.1
help://bk-support
help://bk-support.1
bk support(none)            BitKeeper User's Manual           bk support(none)

NAME
       bk support - send a support request

SYNOPSIS
       bk support [-T]

DESCRIPTION
       Send a request to BitKeeper support.

       The default behavior is to display the graphical version of the support
       form  when  the  DISPLAY environment variable is set (UNIX) or if it is
       run on a Windows operating system.  To use a text  editor  rather  than
       the GUI, use the "-T" option.

       This  command can be used to request support instead of mailing to sup-
       port@bitkeeper.com.  The advantage is that  it  automatically  includes
       the  version  of  BitKeeper  and the operating system being used, which
       speeds the ability of the support team to respond to the request.

OPTIONS
       -T  Use a text editor rather than the default graphical  tool  to  fill
           out a support report.

EXAMPLE
       An example text template looks like this:

       Program:
               [cset, get, delta, etc.  or what you were doing, like 'installing']

       Release:
               beta10-pre1

       OS:
               [Linux, IRIX, NT, etc]
       Etc.

       and  the  filled  out  report should look like this (note that the data
       goes after the tags, not on the same line):

       Program:
               support

       Release:
               pre-2.0-2

       OS:
               All
       Etc.

CATEGORY
       Admin

BitKeeper Inc                         1E1                     bk support(none)
$
help://tag
help://tag.1
help://bk-tag
help://bk-tag.1
help://tags
help://label
help://labels
bk tag(none)                BitKeeper User's Manual               bk tag(none)

NAME
       bk tag - tag the BitKeeper repository with a symbolic name
       bk tags - list tagged changesets

SYNOPSIS
       bk tag [-q] [-r<rev>] <symbol>
       bk tags [<repo>]

DESCRIPTION
       Tags (aka symbols or labels) are used when you want to record the state
       of  a  tree.   It is quite common to "tag the tree" with a release name
       when shipping a product to customers.

       To add a tag to the repository, make sure that  you've  checked  every-
       thing  in  and  created a changeset.  You can use bk status to see what
       needs to be checked in and/or committed to a changeset.  Tag  the  tree
       by typing:

           $ bk tag Alpha

       The  Alpha  tag  will  be set on the most recent changeset.  Or you can
       commit a changeset and tag the tree at the same time with  the  "--tag"
       option to commit:

           $ bk commit --tag=Alpha

       To see all the tagged changesets run

           $ bk tags

       which is just an alias for

           $ bk changes -t

       Optionally, you can pass bk tags a repository URL (see bk help url).

       If you want to recover the state of the world as of a tag, do this:

           $ bk clone -rAlpha source_repository Alpha

       which will create a repository which has everything up to and including
       the Alpha changeset.

       If  you  discover  that  you  should have tagged a changeset after more
       changesets have been added to the repository, use the  "-r"  option  to
       select the proper changeset.  You can find out which revision to tag by
       running bk changes.

       A  frequent  problem  is  that you tag a changeset with "Done" and then
       discover you aren't done.  You may update the tag to the later  change-
       set by running the

           $ bk tag Done

       command  again.   If  there  are multiple tags with the same name, Bit-
       Keeper takes the most recently applied tag (which means you can move  a
       tag backwards by specifying an older revision of the cset file).

OPTIONS
       -q      Run quietly, supressing diagnostics.
       -r<rev> Tags an older release rev.

LEGAL TAGS
       Certain  characters  are not allowed in tags because they conflict with
       other parts of the BitKeeper revision, date, and/or range name spaces.

       A valid tag has to obey the following rules:

       +o   Tags can't start with the characters: '@', '=', '-', '+', or '.'.

       +o   Tags can't start with a digit ('0' to '9').

       +o   Tags can't contain any character with an ASCII value less than  040
           (octal)  or in the following list: '|', '?', '*', the DEL character
           (\177), '~', '^', ':', ';', '/', '!', '"', ''', '$', '%', '&', '\',
           '(', ')', '[', ']', '{', '}', or '`'.

       +o   Tags can't contain spaces (' ').

       +o   Tags can't contain the sequences "..", ".,", ",.", or ",,".

       In a nested repository, this release only allows tags on  the  product,
       not any of its components; future releases may allow both.

BUGS
       Need a way of setting a tag in bk citool.

SEE ALSO
       bk  help admin, bk help changes, bk help commit, bk help untag, bk help
       log

CATEGORY
       Repository

BitKeeper Inc                         1E1                         bk tag(none)
$
help://takepatch
help://takepatch.1
help://bk-takepatch
help://bk-takepatch.1
bk takepatch(none)          BitKeeper User's Manual         bk takepatch(none)

NAME
       bk takepatch - apply a BitKeeper patch

SYNOPSIS
       bk takepatch [-aciStv] [-f<file>]

DESCRIPTION
       The  takepatch  command  is used to apply a BitKeeper patch.  BitKeeper
       patches are how data is moved between BitKeeper repositories.

       Users do not normally invoke this command, it  is  called  directly  by
       bk pull, bk push, or bk receive.

OPTIONS
       -a             Apply the changes (call bk resolve.)
       -c             Do not accept conflicts with this patch.
       -f<file>       Take the patch from <file> and do not save it.
       -i             Initial patch, create a new repository.
       -j<N>          Unpack the patch using N parallel sub-processes.
       --no-automerge Takepatch will try to automerge the file as part of tak-
                      ing the patch.  This option will delay the merging until
                      the resolve stage.  bk pull -i uses this option.
       -S             Save RESYNC and or PENDING directories even if errors.
       -T             Run in text only mode, do not use GUI tools.
       -v             Verbose level, more is more verbose, "-vv" is suggested.

SEE ALSO
       bk help pull, bk help push, bk help receive

CATEGORY
       Repository

BitKeeper Inc                         1E1                   bk takepatch(none)
$
help://templates
help://templates.1
help://bk-templates
help://bk-templates.1
help://template
bk templates(none)          BitKeeper User's Manual         bk templates(none)

NAME
       bk templates - predefined templates for comments

SYNOPSIS
       BitKeeper/templates/commit

DESCRIPTION
       Templates  are  files  which  are used as the default checkin comments.
       Currently only commit templates are implemented.

       If the template exists, then the default comments for a commit are  the
       contents of the template followed by the per file checkin comments.  In
       citool, only the template is included.

EXAMPLE
           Bugid:
           Requester:
           Problem this solves:

SEE ALSO
       bk help commit, bk help citool

CATEGORY
       Repository

BitKeeper Inc                         1E1                   bk templates(none)
$
help://terms
help://terms.1
help://bk-terms
help://bk-terms.1
bk terms(none)              BitKeeper User's Manual             bk terms(none)

NAME
       bk terms - definitions of BitKeeper terms

DESCRIPTION
   BitKeeper definitions:
       package
           This  term is used when a distinction needs to be drawn between two
           different repositories which do not contain the same data, i.e. one
           contains a compiler and the other contains a debugger.  To  distin-
           guish  between  them, refer to the compiler package or the debugger
           package.  One way to think about it is that a package is a  logical
           concept, somewhat like an object, while a repository is an instance
           of  that  object.   Another  way  that people sometimes distinguish
           between packages is to talk about them having different  root  keys
           (each package has an internal identifier called the root key).
       repository
           A  repository  (also known as a work space, a clone, or an instance
           of a package) is where you  do  your  work.   A  repository  is  an
           instance  of a package i.e.  there is one package, but there can be
           many instances of that package.  Unlike other systems, such as CVS,
           every user gets their own repository, complete with  revision  his-
           tory.
       sfile
           A file containing the revision history, e.g., SCCS/s.foo.c.
       gfile
           A file that is checked out, e.g., foo.c.
       tag, symbol
           A symbolic name (or tag) which is given to a particular revision of
           one or more files.  e.g., "Alpha1".
       delta
           A delta (also known as a revision or version) is a specific version
           of  a file, or one change to a file, depending on context.  When we
           mean the specific version of a  file,  we  are  talking  about  the
           entire file as of that version.  When we mean the changes made in a
           specific  delta,  we are talking about the differences contained in
           that delta.
       rev argument
           Many commands take file revision numbers as arguments,  usually  to
           the  "-r" option.  On the command line anytime a revision number is
           expected, the delta key can be used instead.  Or after an @ sign, a
           changeset revision, tag, or changeset key can be used.  So "-r@1.4"
           finds the version number as of changeset revision 1.4. So the  fol-
           lowing are all legal:

               -r1.23
               -r3dcc5f35PWiRWg8wiP7Dehy51Pk7DA
               -r'amy@bitkeeper.com|man/man1/bk-terms.1|20020714011327|59990'
               -r@1.233.2
               -r@bk-3.0-pre3
               -r@'lm@disks.bitkeeper.com|ChangeSet|20020912140445|17593'

       ChangeSet
           The file used to record the repositories' history of changes.
       cset, changeset
           A  particular  change  to  a  repository  consisting of one or more
           changes to one or more files.
       changeset number
           Revision number for a changeset.  These numbers fluctuate, but sta-
           bilize, over time.  If you want an immutable, unique reference  for
           a changeset, use the changeset key.
       key A  unique,  unchanging identifier for a version of a file which may
           be used anywhere a normal revision number and/or  symbolic  tag  is
           used.   A  particular  key may be extracted with the following, the
           first form produces a longer key which is human readable, the  sec-
           ond form produces a shorter key which is not human readable.

               bk -R log -hr<rev> -nd:KEY: ChangeSet
               bk -R log -hr<rev> -nd:MD5KEY: ChangeSet

       package identity
           Each  BitKeeper  package  has  a  unique  identity.   All instances
           (repositories) of the package have the same package identity.
       repository identity
           Each repository has a unique identifier which is  different  across
           all repositories, regardless of the package.
       pending
           Deltas which have been checked into a file but not yet committed to
           a changeset.
       patch
           Formally,  this  is one or more changesets wrapped up for transmis-
           sion to someone else.  It is similar to what you  may  be  used  to
           thinking  of as a patch (a list of all the changes between two ver-
           sions of an entire package) but carries more information: who  made
           the changes, when, and why.
       Trunk
           Main  line source base.  In BitKeeper revtool, the trunk is the X.Y
           in the graph, branches are X.Y.Q.Z, which always  get  merged  into
           the trunk.
       Tip, Top of Trunk (TOT)
           The latest revision on the trunk.
       graph difference
           The  graph difference between revision <B> and revision <A> (repre-
           sented by the notation <A>..<B>) is the set  of  changes  in  <B>'s
           history that are not in <A>'s history.

                    /----> 1.1.1.1  ---->  1.1.1.2 -----\
                   /                                     \
                  /                                       \
               1.1 ----> 1.2 ----------------------------> 1.3 ----> 1.4
                  \                                                 /
                   \                                               /
                    \-----------> 1.1.2.1 ------------------------/

           For  example,  in  the  graph  above,  1.2..1.4 represents the list
           1.1.1.1,  1.1.1.2,  1.1.2.1,  1.3,  1.4;   1.1.2.1..1.1.1.2   means
           1.1.1.1, 1.1.1.2; and 1.1.1.2..1.1.2.1 consists only of 1.1.2.1.

NOTES
       We attempt to list all of the BitKeeper definitions here, but send us a
       message  at  support@bitkeeper.com  if you have suggestions for defini-
       tions we may have missed.

CATEGORY
       Overview

BitKeeper Inc                         1E1                       bk terms(none)
$
help://triggers
help://triggers.1
help://bk-triggers
help://bk-triggers.1
help://trigger
bk triggers(none)           BitKeeper User's Manual          bk triggers(none)

NAME
       bk triggers - using BitKeeper event triggers

DESCRIPTION
       BitKeeper  supports  a  variety of trigger types.   Triggers are simple
       programs, usually shell scripts, which  may  be  called  before  and/or
       after  certain  events,  such  as  a  commit, pull, push, resolve, etc.
       Triggers can be used for event notification and/or to implement control
       over the events themselves.

       When a trigger is called, it is called with the current working  direc-
       tory  set  to  the  root  of the  repository.  Note that in the case of
       incoming data, the root of the repository  is  defined  as  the  RESYNC
       directory.

       If  an incoming changeset adds or updates a trigger, the incoming trig-
       ger is not the trigger fired, with the exception of  the  post-incoming
       trigger.  The trigger already present in the repository, if any, is the
       trigger  used.   This  arrangement  is  for  security reasons; incoming
       changes could be malicious or ill advised and a prudent repository man-
       ager may have developed triggers to look for problems.  If the incoming
       data contained a new or modified trigger, and  that  trigger  was  run,
       triggers  could  not be used to implement security or other policies at
       the repository boundary.

   TRIGGER NAMES
       When  an  event  occurs,  if  there  exists  a   file   BitKeeper/trig-
       gers/event_class  in the repository root that corresponds to the event,
       BitKeeper will execute that trigger.  For example, if there is  a  push
       from  repository  B going into repository A and repository A has a file
       BitKeeper/triggers/pre-incoming, the pre-incoming script  will  be  run
       before the push event applies to repository A.

       All  triggers  for a particular class must be named with the class name
       and prefix, for example pre-incoming-ok.  More  than  one  trigger  per
       event  class  is  allowed;  each trigger program has the class name and
       prefix and a suffix of your choosing.  The trigger programs are  sorted
       and run alphabetically (C locale sort order).

       If  there  are multiple pre- triggers (see below), the first trigger to
       exit with a non-zero status will halt the trigger processing.  If there
       are pre- triggers that must always be run, they must be named such that
       their name will sort earlier than any other trigger of that class.

       In order to avoid name space conflicts, the typical approach is to  use
       the reason for the trigger as the suffix, i.e.,

           post-incoming.mail
           post-incoming.regression-test

       Files ending in ~ are ignored to avoid editor backup files.

   TRIGGER PATHS
       By  default,  triggers  are  stored  in  the  repository under the Bit-
       Keeper/triggers/ directory and this is the only directory searched when
       looking for triggers.  More than one triggers directory may be used  by
       setting  the  triggers variable.  The format is one or more paths sepa-
       rated by a vertical bar, each path has "BitKeeper/triggers" appended to
       it and the resulting path is scanned for triggers.  For example, if you
       wanted to run triggers from /etc/BitKeeper/triggers and from the repos-
       itories' BitKeeper/triggers, set the variable as follows in  your  con-
       figuration:

           triggers: /etc|.

       The directories are processed in the order found in the variable.

       There are several special values which are interpreted:

       .   It means `bk -R pwd`/BitKeeper/triggers is scanned for triggers.

       $BK_DOTBK
           If present, `bk dotbk`/BitKeeper/triggers is scanned for triggers.

       $BK_BIN
           If present, `bk bin`/BitKeeper/triggers is scanned for triggers.

       $NONE
           If present, with no other values, then no triggers are processed.

       $PRODUCT
           If present, `bk -P pwd`/BitKeeper/triggers is scanned for triggers.
           This  only  applies when in a component repository of a nested col-
           lection.  It is a way to run product level triggers in each  compo-
           nent.

       $SOMETHING_ELSE
           All  other  paths  starting with "$" are ignored, that character is
           reserved.

       If the the variable is not defined, the default is:

           triggers: $PRODUCT|.

   TRIGGER CLASSES
       There are multiple event classes which may activate triggers:  incoming
       events,  outgoing  events,  deltas, commits, tags, undo, and collapses.
       The incoming event is broken into multiple events:  incoming,  resolve,
       and apply.

       Most  events may have triggers which run before and/or after the event.
       The difference between pre- and post- event triggers is that  pre-trig-
       gers  may cause events to fail, but post-triggers are strictly informa-
       tional.  The exit status from post-triggers are ignored.

       Not all triggers have both pre- and post- versions,  the  set  of  sup-
       ported triggers are as follows:

       pre-apply
       =>  called  after  the data has been merged in the RESYNC directory but
           before it is applied to the tree.  Last chance to  say  no,  allows
           examination of the merged changes.
       =>  called in the RESYNC directory, not the enclosing repository.
       =>  exit 0 allows the pull/push.
       =>  exit 1 fails the entire pull/push.
       =>  exit 2 fails the pull/push but leaves the patch in PENDING.
       =>  exit  3 fails the pull/push but leaves the patch in PENDING and the
           RESYNC tree in PENDING/RESYNC-date.

       pre-collapse
       =>  called before a changeset is collapsed (see bk collapse).  Typical-
           ly used as part of a process to record the renaming  of  changesets
           in bug tracking systems.
       =>  exit 0 allows the collapse.
       =>  non-zero exit values will fail the collapse.

       pre-commit
       =>  called before a changeset is committed.
       =>  exit 0 allows the commit.
       =>  exit  1  fails the commit. If the commit was initiated from citool,
           citool will exit.  See example below.
       =>  exit 2 also fails the commit.  However, if it  was  initiated  from
           citool, citool will not exit.  This allows the user to try the com-
           mit again.  See example below.

       post-commit
       =>  called after a changeset is committed or attempted to be committed.
       =>  typically used for notification.

       pre-delta
       =>  called  before  a  delta  is  created. Can be use for triggers that
           check code style
       =>  exit 0 allows the delta.
       =>  exit 2 indicates that the trigger called delta itself,  upon  which
           the calling delta command treats it as a successful delta.
       =>  Other than 2, all other non-zero exit values will fail the delta.

       pre-incoming
       =>  called before an incoming push/pull is started.
       =>  non-zero exit status fails the incoming event.
       =>  typically used for locking down a repository.
       =>  may  be used to fail the event based on remote user, host, directo-
           ry, and/or BitKeeper version.

       post-incoming
       =>  called after the data has been applied to the tree.
       =>  typically used for notification.

       pre-outgoing
       =>  called before an outgoing pull/push/clone event.
       =>  non-zero exit status fails the outgoing event.
       =>  typically used for locking down a repository.

       post-outgoing
       =>  called after the outgoing event.
       =>  typically used for notification.

       pre-resolve
       =>  called after the data has been union-ed in the RESYNC directory.
       =>  called in the RESYNC directory, not the enclosing repository.
       =>  exit 0 allows the pull/push.
       =>  exit 1 fails the entire pull/push.
       =>  exit 2 fails the entire pull/push but leaves the patch in PENDING.
       =>  typically used to examine changes before taking them.

       pre-tag
       =>  called before a tag event, such as a bk commit with a specified tag
           or a bk tag.
       =>  exit 0 allows the tag.
       =>  exit 1 causes the tag operation to fail as well as the commit oper-
           ation if the tag was part of a commit.
       =>  exit 2 causes the tag operation to fail but allows the commit oper-
           ation to proceed if the tag was part of a commit.

       pre-undo
       =>  called before a undo is run by user or by unpull and clone -r.
       =>  exit 0 allows the undo.
       =>  exit 1 causes the undo operation to fail.

       post-undo
       =>  called after an undo is run successfully.

   TRIGGER LOCKING
       Triggers are called with a locked repository.  When a post  trigger  is
       called,  the repository is read locked, even in the case that the event
       was an event which changed the repository.  A read lock will allow  the
       trigger  to do outgoing events, such as a push, but will prevent incom-
       ing events.  Pre-incoming and pre-commit triggers will be called with a
       write locked repository.

   TRIGGER SECURITY ISSUES
       Triggers are arbitrary programs (or scripts) which are run automatical-
       ly and without warning.  It is possible that a malicious  person  could
       add  a  trigger  which effect a security breach, damage files, etc.  If
       you are operating in a non-trusted environment,  you  may  disable  all
       triggers  by  setting the BK_NO_TRIGGERS environment variable.  This is
       the safest thing to do but then the trigger functionality is lost.

       Alternatively, a "paranoid" trigger could be added which refused to ac-
       cept a new trigger into a  repository  without  being  examined  first.
       Here's  an  example  of  such a trigger, which would typically be named
       BitKeeper/triggers/pre-apply.paranoid:

           #!/bin/sh

           # This is running in the RESYNC tree, we're looking
           # for any new triggers and/or changes to triggers.
           # Done after the resolve stage because they could
           # be sneaky and create the file in an earlier
           # changeset and then move it.

           test `bk gfiles BitKeeper/triggers | wc -l` -gt 0 || exit 0

           if [ $BK_SIDE = server ]
           then    echo Refusing to accept any changes to triggers on push,
                   echo get the project admin to pull your changes.
                   exit 1
           fi

           rm -f BitKeeper/tmp/t_reject
           for i in `bk gfiles BitKeeper/triggers`
           do      (
                   echo Please review the following trigger for security risks.
                   echo Do not accept it if you think it is a problem.
                   echo
                   echo ===== $i =====
                   bk cat $i
                   ) > BitKeeper/tmp/prompt$$
                   bk prompt -fBitKeeper/tmp/prompt$$ \
                    -t"Review trigger" -yAccept -nReject
                   STATUS=$?
                   rm -f BitKeeper/tmp/prompt$$
                   test $STATUS = 0 || {
                           touch BitKeeper/tmp/t_reject
                           break
                   }
           done
           test -f BitKeeper/tmp/t_reject && {
                   rm -f BitKeeper/tmp/t_reject
                   exit 3
           }
           rm -f BitKeeper/tmp/t_reject
           exit 0

   TRIGGER ENVIRONMENT VARIABLES
       Information which might be useful to the trigger is passed in  environ-
       ment variables.  There are variables for user, host, location, BitKeep-
       er version, repository level, amongst others.  There are two classes of
       variables,  client  side  variables  (BK_*)  and  server side variables
       (BKD_*).  The client side variables are associated with  the  user  who
       initiated  the command.  The server side variables, if present, are as-
       sociated with the "other" repository.  For example, if a user  on  host
       "to"  does  a pull from host "from", then BK_HOST=to and BKD_HOST=from.
       In the list of variables which follow, BKD_* variables are not  present
       unless the command has two end points, such as  a pull, push, or clone.
       The  BKD_*  variables  are  not  defined for commit, resolve, and apply
       events.  In all other cases, the variable is present  in  all  triggers
       unless otherwise stated.

       BK_CSETLIST    If  set,  contains the name of a file which contains the
                      list of changesets being received.  Valid in  pre-apply,
                      post-incoming  pre-outgoing, post-outgoing, pre-resolve,
                      and pre-undo triggers.
       BK_CSETS       If set, contains the  list  of  changesets  being  sent.
                      Valid  only  in  pre-outgoing  and  post-outgoing  clone
                      events.
       BK_COMMENTFILE Location of the comment file for the  changeset.  Useful
                      when  writing  triggers that need to parse the changeset
                      comments. See example below.
       BK_EVENT       The event from the point of view of  the  trigger.   The
                      full  list  of  values for this variable is: apply, col-
                      lapse, commit,  delta,  fix,  incoming  clone,  incoming
                      port, incoming pull, incoming push, outgoing clone, out-
                      going pull, outgoing push, resolve, tag, and undo.
       BK_FILE        Valid  only  in  the pre-delta trigger, and contains the
                      filename of the file about to be delta-ed,  relative  to
                      the repository root.
       BK_HOST        The hostname of the client side host.
       BKD_HOST       The hostname of the server side host.
       BK_LEVEL       The "level" of the client side repository.
       BKD_LEVEL      The "level" of the server side repository.
       BK_LOCALCSETS  The  number  of  changesets  (and/or tags) which are not
                      present in the remote repository but are present in  the
                      local repository.  Note that this variable does not have
                      a  BKD_ version because it is valid only on the outgoing
                      end of a pull or a push.  The other variable  is  BK_RE-
                      MOTECSETS.  Both variables are valid in pre-outgoing and
                      post-outgoing triggers only.
       BK_REPO_TYPE   The  repository  type.   One  of  product, component, or
                      standalone.
       BKD_REPO_TYPE  As above.
       BK_PATCH       Valid only in the pre-resolve trigger, and contains  the
                      full pathname of the file containing the patch being re-
                      solved.
       BK_PENDING     Contains  the  name of a file which contains the list of
                      files with pending deltas.  Valid only in pre-commit.
       BK_REMOTECSETS The number of remote changesets (and/or tags) which  are
                      not  present  in the local repository but are present in
                      the remote repository.  Goes with BK_LOCALCSETS  and  is
                      valid only in pre-outgoing and post-outgoing triggers.
       BK_ROOT        The full path name to the root of the client side repos-
                      itory.
       BKD_ROOT       The full path name to the root of the server side repos-
                      itory.
       BK_SIDE        If  the  trigger is part of a two-sided operation (i.e.,
                      pull, push), then this is set to "server" if the trigger
                      is running on the server repository.  Otherwise this  is
                      set to "client."
       BK_STATUS      The  status  of  the  command, if known.  Values may in-
                      clude:

           NOTHING    There was nothing to pull or push.
           FAILED     The command did not complete because of an error.
           DRYRUN     The command did not complete because it was a "dry run,"
                      i.e., a "bk pull -n" to look to see if there is anything
                      to pull.
           CONFLICTS  The command did not complete  because  there  were  con-
                      flicts (parallel work).
           LOCAL_WORK The command did not complete because there is local work
                      and an update only operation was requested.
           SIGNALED   The  command did not complete because it received a sig-
                      nal.
           OK         The command completed successfully.
           UNKNOWN    Unknown status.
       BK_TAG         If set, contains the value of the  symbolic  tag  to  be
                      added to the repository.  Valid only in pre-tag trigger.
       BK_TAG_REV     If set, contains the changeset revision on which the tag
                      will be placed.  This will be set if and only if the re-
                      vision  is  not the most recent revision.  Valid only in
                      pre-tag trigger.
       BK_TIME_T      The UNIX style time stamp of the client  side  BitKeeper
                      binary.
       BKD_TIME_T     The  UNIX  style time stamp of the server side BitKeeper
                      binary.
       BK_TRIGGER     The basename name of the trigger program.
       BK_USER        The user name of the user who ran  the  command  on  the
                      client.
       BKD_USER       The  user  name  of  the user who ran the command on the
                      server.
       BK_UTC         The time stamp of the client side BitKeeper  binary  ex-
                      pressed as YYYYMMDDHHMMSS.
       BKD_UTC        The  time  stamp of the server side BitKeeper binary ex-
                      pressed as YYYYMMDDHHMMSS.
       BK_VERSION     The version of the client side BitKeeper binary  as  the
                      symbolic name or the UTC.
       BKD_VERSION    The  version  of the server side BitKeeper binary as the
                      symbolic name or the UTC.

EXAMPLE 1
           #!/bin/sh

           # Simple post-commit trigger for email notification of changes

           # For nested collections, we don't want notification in components,
           # the product recurses.
           test `bk repotype` = "component" && exit 0

           # Let bk changes do all the work for us.
           bk changes -vvr+ |
               mail -s "commit in `bk gethost -r`:`bk pwd` bk $BK_USER"
           exit 0

EXAMPLE 2
           #!/bin/sh

           # Display info about incoming and outgoing csets.

           if [ X$BK_STATUS = XDRYRUN -o X$BK_STATUS = XNOTHING ]
           then exit 0
           fi
           if [ $BK_SIDE = server ]
           then U=$BKD_USER
                H=$BKD_HOST
                R=$BKD_ROOT
           else U=$BK_USER
                H=$BK_HOST
                R=$BK_ROOT
           fi
           (
           if [ X$BKD_ROOT != X ]
           then printf '%-10s%-20s%-20s\n' VAR CLIENT SERVER
                printf '%-10s%-20s%-20s\n' === ====== ======
                printf '%-10s%-20s%-20s\n' USER $BK_USER $BKD_USER
                printf '%-10s%-20s%-20s\n' HOST $BK_HOST $BKD_HOST
                printf '%-10s%-20s%-20s\n' ROOT $BK_ROOT $BKD_ROOT
                printf '%-10s%-20s%-20s\n' LEVEL $BK_LEVEL $BKD_LEVEL
                printf '%-10s%-20s%-20s\n' TIME_T $BK_TIME_T $BKD_TIME_T
                printf '%-10s%-20s%-20s\n' UTC $BK_UTC $BKD_UTC
                printf '%-10s%-20s%-20s\n' VERSION $BK_VERSION $BKD_VERSION
                echo
           fi
           echo ${U}@${H} fired the $BK_TRIGGER trigger in $R
           case $BK_TRIGGER in
               pre-outgoing)   VERB=Sending;;
               post-outgoing)  VERB=Sent;;
               pre-incoming)   VERB=Receiving;;
               post-incoming)  VERB=Received;;
               pre-resolve)    VERB=Resolving;;
               pre-commit)          VERB=Committing;;
               post-commit)    VERB=Committed;;
               pre-apply)      VERB=Applying;;
           esac
           if [ X$BK_PENDING != X ]
           then (
                echo $VERB the following deltas
                echo
                bk log - < $BK_PENDING
                ) | sed 's/^/    /'
           fi
           if [ X$BK_CSETLIST != X ]
           then (
                echo $VERB the following changesets
                echo
                bk changes -v - < $BK_CSETLIST
                ) | sed 's/^/    /'
           fi
           if [ X$BK_CSETS != X ]
           then (
                echo $VERB the following changesets
                echo
                bk changes -v -r$BK_CSETS
                ) | sed 's/^/    /'
           fi
           ) | mail -s "$BK_EVENT in ${H}:${R}" notify@bitkeeper.com

EXAMPLE 3
           #!/bin/sh
           #
           # Using pre-commit trigger to verify changeset comment
           # BitKeeper/trigger/pre-commit.cset_comments
           #

           # only run in the product (or a traditional repo)
           bk repotype -q
           test $? -eq 1 && exit 0

           # if this is a merge, we are in the RESYNC directory
           # since it is not a user cset, ignore
           test "`basename "$BK_ROOT"`" = "RESYNC" && exit 0

           grep -q 'BUGID:' $BK_COMMENTFILE && exit 0

           msg="A 'BUGID:' field is needed in the checkin comments"

           # Bring up an external program to browse bugs so that the
           # engineer can add a valid bugid to the changeset comments.

           #/opt/bugtrack/bin/bugviewer 'http://server.host.com/bugs?status=open' &

           # Ask user if he needs to enter a bugid.  returning an exit code of 2
           # from the trigger will allow user to retry the commit from
           # within citool.
           bk prompt -y"Reenter bugid" -n"Force commit with no bugid" "$msg" && exit 2

           # If you wish to provide the option to fail out of citool, use this.
           #bk prompt -y"Abort commit" -n"Force commit with no bugid" "$msg" && exit 1

           exit 0

EXAMPLE 4
           #!/bin/sh
           #
           # Using a pre-collapse trigger to checks to see if the key is in
           # some repo that is frozen.

           bk changes -R bk://work/bk-4.0.x - < $BK_CSETS > /tmp/csets$$
           OK=0
           test -s /tmp/csets$$ && OK=1
           rm -f /tmp/csets$$
           exit $OK

EXAMPLE 5
           #!/bin/sh
           #
           # A post-incoming trigger that will push incoming changesets
           # to a mirror repository

           MIRROR=REPO-mirror

           # Debug
           #Q=
           #OUT=/tmp/OUT

           # Quiet
           Q=-q
           OUT=/dev/null

           # Do not run in components
           test `bk repotype` = component && exit 0

           # Only run on successful pulls/pushes
           test "$BK_EVENT" = "incoming clone" && exit 0
           test "$BK_STATUS" != "OK" && exit 0

           # Foreground mirror - incoming operation will block
           # until the mirror push is complete
           #bk push $Q "$MIRROR"
           #exit 0

           # Background mirror
           # Start a background process to push the incoming
           # changesets to a mirror repository
           #
           (
             # Avoid possible race, wait for any locks to be dropped
             bk lock -U
             bk push $Q "$MIRROR"
           ) > $OUT 2>&1 &

SEE ALSO
       bk help clone, bk help changes, bk help commit, bk  help  collapse,  bk
       help  delta,  bk  help  prompt, bk help pull, bk help push, bk help re-
       solve, bk help repotype, bk help tag

CATEGORY
       Repository

BitKeeper Inc                         1E1                    bk triggers(none)
$
help://undo
help://undo.1
help://bk-undo
help://bk-undo.1
help://reset
bk undo(none)               BitKeeper User's Manual              bk undo(none)

NAME
       bk undo - Undo a changeset or set of changesets

SYNOPSIS
       bk undo [-fqSsv] [-a<rev>] [-r<rev>]

DESCRIPTION
       The  bk  undo  command  can  be  used to remove any changeset or set of
       changesets.   There are options to select specific  changesets  or  all
       changesets after some point (which is what "bk clone -r" uses).

       To undo a bk pull use bk unpull.

WARNING
       With  one exception, the changes removed by an undo cannot be restored.
       Use bk undo with care, if the data was only present in your repository,
       when you undo it, it is gone for good.

       If the "-s" option is not present then bk undo saves a normal BitKeeper
       patch in BitKeeper/tmp/undo.patch.  Only the most recent undo is  saved
       there, i.e., the patch is overwritten each time bk undo is run.  To re-
       store the patch try this:

           bk takepatch -vvvaf BitKeeper/tmp/undo.patch

       There  is  a  a  shorthand, bk repatch, which is an alias for the above
       command.  The bk repatch command can take an  optional  argument  which
       specifies an alternate patch to reapply.

OPTIONS
       -a<rev>             Remove  all  changesets which occurred after <rev>.
                           If <rev> is what you want to have be top of  trunk,
                           use this option.
       -f                  Force  the  undo  to complete if it can.  Normally,
                           undo will prompt with a list of deltas  which  will
                           be removed.
       --force-unpopulate  If  the  undo results in a component being removed,
                           undo will first check that  the  component  can  be
                           found  in  a  gate.  Use this option to disable the
                           gate check and just remove the component.
       -q                  Run quietly; do not list files.
       -r<revs>            Remove the list of changesets specified by  <revs>.
                           <revs>  must  be of the form r1,r2,r3, etc. and can
                           be either the changeset  number  or  the  changeset
                           key.  See bk help terms for more information.
       -S
       --standalone        Just  undo the current component.  In a nested col-
                           lection, this rolls back just the current component
                           and not the entire nested collection.
       -s                  Do not save undone changes as a patch.
       -v                  When prompting with the list of changes to  be  un-
                           done  be  verbose and list not only the changes but
                           the deltas in each file in each changeset.

SEE ALSO
       bk help makepatch, bk help pull, bk help stripdel, bk  help  takepatch,
       bk help terms, bk help unpull

CATEGORY
       Repository

BitKeeper Inc                         1E1                        bk undo(none)
$
help://undos
help://undos.1
help://bk-undos
help://bk-undos.1
bk undos(none)              BitKeeper User's Manual             bk undos(none)

NAME
       bk undos - convert DOS files to UNIX files

SYNOPSIS
       bk undos [-nr] [<file> ...]

DESCRIPTION
       The  bk  undos  command  reads  the  specified file and translates each
       "\r\n" into "\n".  A trailing "\n" will also be added to the file if it
       doesn't have one already.

OPTIONS
       -n  Prevents adding a missing trailing "\n" to the file.
       -r  Reverses the process and converts a UNIX file to DOS line endings.

CATEGORY
       Utility

BitKeeper Inc                         1E1                       bk undos(none)
$
help://unedit
help://unedit.1
help://bk-unedit
help://bk-unedit.1
bk unedit(none)             BitKeeper User's Manual            bk unedit(none)

NAME
       bk unedit - destroy any unchecked in changes to specified files

SYNOPSIS
       bk unedit [-q] [<file> ...]

DESCRIPTION
       If  you  wish to discard any modifications you have made to a file, you
       can use the bk unedit command.  For each listed file,  bk  unedit  will
       discard the write lock and discard the checked out file and ANY CHANGES
       YOU  HAVE  MADE  TO THE FILE.  Use this command only when you have made
       changes to a file that you want to throw away.  If you want to clean up
       only those files without changes, use the bk clean command.

       The bk unedit command will not  autoexpand  the  file  list,  you  must
       explicitly name each file you want to unedit.

OPTIONS
       -q  be quiet.

SEE ALSO
       bk help clean, bk help edit

CATEGORY
       File

BitKeeper Inc                         1E1                      bk unedit(none)
$
help://uninstall
help://uninstall.1
help://bk-uninstall
help://bk-uninstall.1
bk uninstall(none)          BitKeeper User's Manual         bk uninstall(none)

NAME
       bk uninstall - uninstall BitKeeper

SYNOPSIS
       bk uninstall [-f]

DESCRIPTION
       bk  uninstall  removes the current BitKeeper installation from the host
       computer.  On non-Windows platforms, bk uninstall  attempts  to  remove
       any  symbolic links that refer to the removed installation (see bk help
       links for information about installing symlinks pointing  to  installa-
       tion  images).   On  Windows  platforms, bk uninstall removes BitKeeper
       entries from the registry.

OPTIONS
       -f  Force uninstallation; do not prompt.

SEE ALSO
       bk help upgrade

CATEGORY
       Utility

BitKeeper Inc                         1I1                   bk uninstall(none)
$
help://unlock
help://unlock.1
help://bk-unlock
help://bk-unlock.1
help://Repository/locks
help://Repository/repo
help://Repository/unlocking
bk unlock(none)             BitKeeper User's Manual            bk unlock(none)

NAME
       bk unlock - remove BitKeeper repository locks

SYNOPSIS
       bk unlock [-rsw] [<file> ...]

DESCRIPTION
       The  unlock  command  can  be used to remove locks which have been left
       behind for some reason.  In general, you shouldn't need  this  command,
       if  you  do  it  indicates that BitKeeper is leaving lock files that it
       should not.  In that case, please tell support@bitkeeper.com so we  can
       fix that problem.

       The  unlock command can be used to remove repository level locks.  This
       can be necessary if a remote process has  left  behind  a  lock  (local
       stale  locks  are detected and cleaned automatically).  A stale lock is
       one which has been  created  locally  but  the  process  is  no  longer
       present.

       Note:  a repository can have two write locks: the regular lock file and
       the existence of the RESYNC directory.  Removing the  write  lock  does
       not imply removing the RESYNC directory, see bk help abort for that.

OPTIONS
       -r  Remove all read locks, stale or not.
       -s  Remove both read and write locks, but only if they are stale.
       -w  Remove  the  write  lock, stale or not.  Does not remove the RESYNC
           directory.

SEE ALSO
       bk help lock, bk help abort

CATEGORY
       File
       Repository

BitKeeper Inc                         1E1                      bk unlock(none)
$
help://unpull
help://unpull.1
help://bk-unpull
help://bk-unpull.1
bk unpull(none)             BitKeeper User's Manual            bk unpull(none)

NAME
       bk unpull - remove changesets added by bk pull

SYNOPSIS
       bk unpull [-fqSs]

DESCRIPTION
       bk  unpull will remove changesets added by the most recent bk pull com-
       mand.  If a local changeset has been committed, bk unpull  can  not  be
       executed until that changeset is removed by bk undo.

NOTE
       bk unpull will discard the merge changeset, if any; that is not consid-
       ered  part of the local work in this context.  If the merge was compli-
       cated it is advisable to save a patch.

OPTIONS
       -f            Force unpull.
       -q            Quiet mode.
       -S
       --standalone  In a nested collection this makes  unpull  operate
                     only  on the current component.  This is useful to
                     revert a port command.
       -s            Do   not   save   a   backup   patch    in    Bit-
                     Keeper/tmp/unpull.patch.

SEE ALSO
       bk help pull, bk help undo

CATEGORY
       Common
       Repository

BitKeeper Inc                         1E1                      bk unpull(none)
$
help://unrm
help://unrm.1
help://bk-unrm
help://bk-unrm.1
bk unrm(none)               BitKeeper User's Manual              bk unrm(none)

NAME
       bk unrm - resurrect a removed BitKeeper file

SYNOPSIS
       bk unrm <file>

DESCRIPTION
       Use  bk  unrm  to  resurrect  a file that has been deleted using bk rm.
       Please note that bk unrm cannot resurrect files that have been  removed
       from the source tree using bk gone.

       If  you  know  the path to the original file, for example src/Makefile,
       then to resurrect:

           cd ~/projects/myproject/src
           bk unrm Makefile

       If you do not know the directory run unrm from the root of the  reposi-
       tory:

           cd ~/projects/myproject
           bk unrm Makefile

       There  will  be an interactive interface for choosing whether or not to
       resurrect the file.  Type "y" to resurrect the file, "n" to do  nothing
       or  go  to the next option, or "q" to quit.  If there are more than one
       files with the same name, choose "y" if the pathname shown is  the  one
       you want, or choose "n" until the correct file is shown.

SEE ALSO
       bk help gone, bk help rm, bk help rmdir

CATEGORY
       Common
       File

BitKeeper Inc                         1E1                        bk unrm(none)
$
help://untag
help://untag.1
help://bk-untag
help://bk-untag.1
bk untag(none)              BitKeeper User's Manual             bk untag(none)

NAME
       bk untag - delete the symbolic namd in the BitKeeper repository

SYNOPSIS
       bk untag [-q] <symbol> [<symbol> ...]

DESCRIPTION
       Tags (aka symbols or labels) are used when you want to record the state
       of  a  tree.   When the tag no longer is useful, then it can be deleted
       with this command.

       Remove a tag Alpha in the tree by typing:

           $ bk untag Alpha

OPTIONS
       -q Run quietly, supressing diagnostics.

BUGS
SEE ALSO
       bk help admin, bk help changes, bk help commit, bk help  tag,  bk  help
       log

CATEGORY
       Repository

BitKeeper Inc                         1E1                       bk untag(none)
$
help://unwrap
help://unwrap.1
help://bk-unwrap
help://bk-unwrap.1
bk unwrap(none)             BitKeeper User's Manual            bk unwrap(none)

NAME
       bk unwrap - unwrap patches

SYNOPSIS
       bk unwrap < <patch> > <patch.unwrapped>

DESCRIPTION
       Normally  you do not use this command as it is invoked automatically as
       part of the bk receive command.  However, you may want to use this com-
       mand to peek inside a wrapped patch.

SEE ALSO
       bk help receive, bk help send, bk help wrap

CATEGORY
       File

BitKeeper Inc                         1E1                      bk unwrap(none)
$
help://upgrade
help://upgrade.1
help://bk-upgrade
help://bk-upgrade.1
bk upgrade(none)            BitKeeper User's Manual           bk upgrade(none)

NAME
       bk upgrade - upgrade to, or check for, new versions of BitKeeper

SYNOPSIS
       bk upgrade [-cdfq] [-a[<arch>]] [<srcurl>]

DESCRIPTION
       The  bk  upgrade command contacts BitKeeper's servers using HTTP to see
       if new versions of BitKeeper are available for download.  If a new ver-
       sion is found for this platform,  then  the  image  is  downloaded  and
       installed, unless instructed otherwise with the options below.

OPTIONS
       -a[<arch>]   Requests  an  installer image for another architecture and
                    reports the newest available version.  Usually  used  with
                    "-d"  to  download a BitKeeper installer for another plat-
                    form.  If "-d" is not set then "-c" is implied.  Omit  the
                    architecture to request a list of all supported platforms.
       -c           Just  check to see if a new version BitKeeper is available
                    for this platform but do not download and install it.
       -d           Download the installer for a new version of BitKeeper, but
                    do not install it.
       -f           If the bk upgrade command is unable to  determine  if  the
                    currently installed version of BitKeeper has been replaced
                    by  a  newly  released version, then an warning message is
                    printed and the upgrade is aborted.  The "-f" option allow
                    the user to force the new version to be used.
       -q           This causes the upgrade program to suppress  extra  output
                    when running.

EXAMPLES
       To check for new upgrades:

           bk upgrade -c

       To install a new version of bk:

           bk upgrade

       To upgrade a given installation of bk on this machine:

           /home/user/bitkeeper/bk upgrade

       To download the latest installer regardless of what you have installed:

           bk upgrade -df

       To download the latest installer for Windows:

           bk upgrade -df -ax86-win32

NOTES
       The  default  URL  that BitKeeper uses to search for new updates can be
       overridden with the "upgrade_url" config option.  This will usually  be
       used  in a corporate environment to prevent users from using a new ver-
       sion of BitKeeper that has  not  been  certified  locally.  Usually  an
       internal  URL  will  be  put  in a config file in the BitKeeper install
       directory.

       To populate the local copy of the binaries you will need  to  wget  the
       directory  of binaries from bitkeeper.com; the images are encrypted and
       bk upgrade expects that and will not work with un-encrypted images.

       To download the images run

           wget -r http://upgrades.bitkeeper.com/upgrades

EXIT STATUS
       0   if a new version of BitKeeper is found
       1   if no updates are available
       2   if errors occurred downloading new updates

SEE ALSO
       bk help config-etc

CATEGORY
       Utility

BitKeeper Inc                         1E1                     bk upgrade(none)
$
help://url
help://url.1
help://bk-url
help://bk-url.1
help://naming
bk url(none)                BitKeeper User's Manual               bk url(none)

NAME
       bk url - methods of accessing BitKeeper repositories

DESCRIPTION
       BitKeeper  supports many ways to access a repository.  The selection of
       the access method is determined by how the  repository  is  referenced.
       Each  reference  form is described below with an explanation of how the
       repository is accessed following each form.

       In all cases below if the <pathname> part of the URL starts with a  "/"
       then the pathname is absolute, otherwise it is relative to the location
       of the bkd.  If <pathname> is not set then the implied remote directory
       must be the root of a repository.  See EXAMPLES below.

ACCESS METHODS
   LOCAL
       <pathname>
       file://<pathname>
           Access is all local, through the local file system.

   RSH
       rsh://<host>/<pathname>
       rsh://<user>@<host>/<pathname>
           Uses rsh to access <host> and starts in the user's home directory.

   SSH
       <host>:<pathname>
       <user>@<host>:<pathname>
           Uses  ssh  (by  default)  to access <host> and starts in the user's
           home directory.  If $BK_RSH is set, then that is used  to  talk  to
           the host (allows for proxying).  If no ssh is found then falls back
           to rsh.
       ssh://<host>/<pathname>
       ssh://<host>:<port>/<pathname>
       ssh://<user>@<host>/<pathname>
       ssh://<user>@<host>:<port>/<pathname>
           Uses ssh to access <host> and starts in the user's home directory.
       bk://<user>@<host>/<pathname>
           This is a deprecated form of ssh that only worked with a bkd run as
           a  login  shell.   Connecting  to a bkd running as a login shell is
           still supported.  Please use the ssh:// URL form.

   BKD
       bk://<host>/<pathname>
           Connects to an existing bkd on the default bkd port and  starts  in
           the directory where the long lived bkd was initially started.
       bk://<host>:<port>/<pathname>
           Connects to an existing bkd on the specified port and starts in the
           directory where the long lived bkd was initially started.

   HTTP
       http://<host>/<pathname>
           Connects to an existing bkd using the HTTP port and transfer proto-
           col  and  starts in the directory where the long lived bkd was ini-
           tially started.
       http://<host>:<port>/<pathname>
           Connects to the specified port using the HTTP transfer protocol and
           starts in the directory where the  long  lived  bkd  was  initially
           started.

PROXIES
       BitKeeper  supports most HTTP proxies.  Information about proxies needs
       to be passed to BitKeeper in the environment.

       The following are the environmental variables are available for use:
           http_proxy=http://<host>:<port>
           http_proxy=http://[<user>:<pass>@]<host>:<port>/
           no_proxy=<comma,separated,list,of,hosts,to,not,proxy>

           SOCKS_HOST=<host_name>
           SOCKS_PORT=<port_number>
           SOCKS_SERVER=<host>:<port>

       Note: if SOCKS_HOST is set, SOCK_PORT must also be set.  If you are not
       sure if you should set environment variables, please consult your  sys-
       tem administrator.

       On Windows, BitKeeper will also read Internet Explorer's proxy informa-
       tion  from  the  registry.   So  in most cases if Internet Explorer can
       browse the web then BitKeeper will work as well.

EXAMPLES
       To clone <old> to <new>:

           bk clone old new

       To clone from a repository named <old> on a  host  named  <host>  using
       SSH:

           bk clone ssh://host/old new

       To  clone  from  a  repository named <old> on a host named <host> using
       rsh:

           bk clone rsh://host/old new

       To clone from a repository named /home/bk/mysql on a host named  <host>
       using ssh (note there are 2 slashes before "home"):

           bk clone ssh://host//home/bk/mysql new

       Suppose  that  you  had  a  number  of repositories in /home/bk and you
       wanted to make them available via the bkd protocol.  On the server  you
       would run:

           cd /home/bk
           bk bkd

       and on the client you would run this to get /home/bk/mysql:

           bk clone bk://server/mysql

SEE ALSO
       bk help bkd

CATEGORY
       Repository
       Overview

BitKeeper Inc                         1E1                         bk url(none)
$
help://version
help://version.1
help://bk-version
help://bk-version.1
bk version(none)            BitKeeper User's Manual           bk version(none)

NAME
       bk version - print BitKeeper version

SYNOPSIS
       bk version [-s] [<URL>]

DESCRIPTION
       The bk version command shows what version of BitKeeper you are running.
       If  the version is symbolically named (most are), the version will look
       like:

           BitKeeper version is bk-3.0.4 20031218201658 for x86-glibc22-linux
           Built by: lm@redhat71.bitkeeper.com in /build/3.0.x-lm/src
           Built on: Thu Dec 18 17:32:47 PST 2003

       The version output for a development snapshot looks like:

           BitKeeper version is bk-7.0.2+20@0x56afec8c-dirty for x86-glibc23-linux
           Built by: lm@work.bitkeeper.com in /home/bk/lm/bugfix-release/src
           Built on: Mon Feb 01 2016 16:11:16 PST (18 seconds ago)

       The version is generated by bk describe, see that command  for  how  to
       read it.

       If a URL is specified, then get the version of bk running at that URL.

OPTIONS
       -s  Print just the version number (either "3.0.4" or "20040211171546").

NOTE
       BitKeeper  Inc  provides  support for symbolically-tagged version only.
       The snapshot versions are completely unsupported.

SEE ALSO
       bk help describe

CATEGORY
       Admin
       Common

BitKeeper Inc                         1E1                     bk version(none)
$
help://what
help://what.1
help://bk-what
help://bk-what.1
bk what(none)               BitKeeper User's Manual              bk what(none)

NAME
       bk what - look for SCCS what strings

SYNOPSIS
       bk [-r] what [<file> ... | -]

DESCRIPTION
       The  bk  what  command  looks through the specified list of file[s] for
       strings which start with the SCCS "what" string "@(#)",  which  can  be
       stated as %Z% in a source file, and prints the entire string.

       If a C program contains

           char sccsid[] = "@(#)some ident info";

       and the program is compiled to yield a program a.out, then the command

           what a.out

       will produce

           a.out:
               some ident info

SEE ALSO
       bk help keywords

CATEGORY
       File

BitKeeper Inc                         1E1                        bk what(none)
$
help://wrap
help://wrap.1
help://bk-wrap
help://bk-wrap.1
bk wrap(none)               BitKeeper User's Manual              bk wrap(none)

NAME
       bk wrap - using BitKeeper wrappers

DESCRIPTION
       For  various reasons, you may wish to wrap a patch which is transmitted
       through email.  The typical reason is that the patch is  going  through
       some  mailer  which  chops  long  lines or performs some other unwanted
       transformation on the data.  Wrapping is typically done via the bk send
       interface with the -w option.

       The following two commands produce identical data:

           $ ls -1 | bk uuwrap | bk unuuwrap
           $ ls -1

       The current set of wrappers are:

           b64 - wrap data using base 64 encoding
           gzip_b64 - gzip the data and then base 64 encode the zipped data
           gzip_uu - gzip the data and then uuencode the zipped data
           uu - wrap the data using uuencode

SEE ALSO
       bk help base64, bk help send, bk help receive

CATEGORY
       File

BitKeeper Inc                         1E1                        bk wrap(none)
$
help://xflags
help://xflags.1
help://bk-xflags
help://bk-xflags.1
bk xflags(none)             BitKeeper User's Manual            bk xflags(none)

NAME
       bk xflags - check or fix BitKeeper flags

SYNOPSIS
       bk xflags [-ns] [<file> ...]

DESCRIPTION
       bk  xflags  is  an administrative command used to check and/or fix Bit-
       Keeper flags.  These flags control things such as what sort of keywords
       are expanded.

       This command should not be typically needed, it  exists  to  fix  older
       repositories  which did not properly maintain these flags.  If bk check
       yields output like

           src/utils/Makefile@@1.12 should have EXPAND1 flag
           src/utils/README@@1.3 should have SCCS flag
           src/DOCS: missing required flag[s]: BITKEEPER

       bk xflags needs to be run.

       With no options, bk xflags will fix the flags in all of  the  specified
       files.  To fix all files, run

           bk -A xflags

OPTIONS
       -n  Do not change any files, just list any problems found.
       -s  Do  not change any files, do not list any status, just exit 0 if no
           problems were found, exit 1 if problems were found.

SEE ALSO
       bk help admin, bk help check

CATEGORY
       File

BitKeeper Inc                         1E1                      bk xflags(none)
$
help://zone
help://zone.1
help://bk-zone
help://bk-zone.1
bk zone(none)               BitKeeper User's Manual              bk zone(none)

NAME
       bk zone - print BitKeeper's view of the timezone

SYNOPSIS
       bk zone

DESCRIPTION
       Prints  the timezone as an offset from GMT, i.e., PST is -08:00, PDT is
       -07:00.

EXIT STATUS
       bk zone returns exit status 0.

CATEGORY
       Utility

BitKeeper Inc                         1E1                        bk zone(none)
$
