The following help topics are available:
intro -- Basic concepts: commits, tags, branches. The form of commands.
-revisions -- How to specify ranges of commits to operate on
-commands -- a summary of the commands
+revisions -- How to specify ranges of commits to operate on.
+commands -- a summary of the commands.
+status -- details about the src status command.
+ignores -- .srcignore files and their uses.
""",
"intro": """
SRC (or src) is designed for version control on single-file projects.
src verb [switches] [revision-spec] [files...]
-That is, a command verb is followed by optional switches, which is
+That is, a command verb is followed by optional switches, which are
(sometimes) optionally followed by a range of commits to operate on,
-which is optionally followed by a list of files to operate on.
+which is optionally followed by a list of files to operate on. Usually
+you will specify either a revision range or multiple files, but not both.
The token "--" tells the command-line interpreter that subcommands,
switches, and revision-specs are done - everything after it is a filename,
A history is created for the file if it does not already exist.
With '-', take comment text from stdin; with '-m' use the
following string as the comment; with '-f' take from a file.
- With '-e', edit even after '-f' or '-m'. ci is a synonym for commit.
+ With '-e', edit even after '-f' or '-m'. 'ci' is a synonym for commit.
src amend [- | -m string | -f file | -e] ['revision'] ['file'...]::
Amends the stored comment for a specified revision, defaulting to the
latest revision on the current branch. Flags are as for commit.
src checkout ['revision'] ['file'...]
- Refresh the working copy of the file(s) from their history files.
- co is a synonym for checkout.
+ Refresh the working copies of the file(s) from their history files.
+ 'co' is a synonym for checkout.
-src status ['file'...]
- A = added, . = unmodified, M = modified, ! = missing, ? = not tracked,
- I = ignored, L = locked (recover with src checkout). The A and L statuses
- status should only occur if you have used RCS directly on a file.
+src status [-a] ['file'...]
+ A = added, . = unmodified, M = modified, ! = missing, ? = not
+ tracked, I = ignored, L = locked (recover with src checkout).
+ Find more details under 'help status'. 'st' is a synonym fot status.
src cat ['revision'] ['file'...]
Send the specified revisions of the files to standard output.
Report the version of src.
The omission of 'src remove' is a deliberate speed bump.
+""",
+ "status": """
+The status command shows you the version-control status of files. It is
+designed to be useful for both humans and software front ends such as
+Emacs VC mode.
+
+The status codes, in roughly most common to rarest, are:
+
+. = Unmodified. File is the same as the latest stored revision.
+
+M = Modified. File has been changed since the latest stored revision
+
+? = Not tracked. SRC dies not keep a history for this file.
+
+I = ignored. This file matches the patterns in .srcignore
+
+! = Missing. There is a history for this file but the workfile is missing.
+
+A = The file has been registered into SRC but has no commits.
+
+L = The file is locked.
+
+You can usually recover of file from A, L, and ! status with src
+checkout. A and L statuses should only occur if you have used RCS
+directly on a file.
+
+If you give 'src status' no filename arguments, it surveys all files
+in the current directory but untracked and ignored files
+are not listed. If you give it filename arguments, status is listed
+for all of them.
+
+The -a option forces status listing of all files. This differs from
+'src status *' because the latter will not see dotfiles and thus not list
+the status of them.
+""",
+ "ignores" : """
+You can have a file named .srcignore containing the names of files that
+SRC should ignore, or more commonly patterns describing files to ignore.
+
+When SRC is told to ignore a file, it won't show up in src status
+listings unless the '-a' (all) flag is used or you give it as an
+explicit argument. It will also be ignored when commands that expect a
+list of registered files see it (which could easily happen when you
+use shell wildcards in SRC commands).
+
+Other version-control systems have these too. The classic example of
+how to do this is using the pattern '*.o' to ignore C object files.
+But if you need to do that, you should probably be using a multi-file
+VCS with changesets, not this one.
+
+Patterns that might be useful with single-file projects include "*~"
+to ignore editor backup files, or '*.html' if you're writing documents
+that render to HTML but aren't sourced in it.
+
+The repo subdirectory - normally .src - is always ignored, but .srcignore
+iyself is not automatically ignored.
+
+SRC's pattern syntax is that of Unix glob(3), with initial '!' treated
+as a negation operator. This is forward-compatible to Git's ignore
+syntax.
+
+* matches any string of characters.
+
+? matches any single character.
+
+[] brackets a character class; it matches any character in the class.
+So, for example, [0123456789] would match any decimal digit.
+
+[!] brackets a negated character class; [!0123456789] would match
+any character not a decimal digit.
"""
}
def help_method(*args):
"Summarize src commands, or (with argument) show help for a single command."
- sys.stdout.write(help_topics['topics'])
+ if not args:
+ sys.stdout.write(help_topics['topics'])
for arg in args:
if arg in args:
if arg in help_topics:
"Should the specified file be ignored?"
global ignorable
if ignorable is None:
- ignorable = []
+ ignorable = set([])
+ ignorable = set()
if os.path.exists(".srcignore"):
for line in open(".srcignore"):
- if not line.startswith("#") and line.strip():
- ignorable += glob.glob(line.strip())
- return filename in ignorable
+ if line.startswith("#") or not line.strip():
+ continue
+ elif line.startswith("!"):
+ ignorable -= set(glob.glob(line[1:].strip()))
+ else:
+ ignorable |= set(glob.glob(line.strip()))
+ return (filename == repodir) or (filename in ignorable)
class CommandContext:
"Consume a revision specification or range from an argument list"
registered = os.listdir(repodir)
except OSError:
croak("repo directory %s does not exist" % repodir)
+ args = list(args)
+ allflag = False
+ if args:
+ if args[0] == '--':
+ args.pop(0)
+ elif args[0] == '-a':
+ allflag = True
+ args.pop(0)
if args:
candidates = args
else:
pairs = []
for fn in candidates:
if ignore(fn):
- if fn in args:
+ if allflag or fn in args:
pairs.append((fn, "I"))
continue
masterbase = os.path.basename(backend.history(fn))
if masterbase not in registered:
- if fn in args:
+ if allflag or fn in args:
pairs.append((fn, "?"))
elif not os.path.exists(fn):
pairs.append((fn, "!"))
"checkout": checkout_method,
"co": checkout_method,
"status": status_method,
+ "st": status_method,
"cat": cat_method,
"diff": diff_method,
"tag": tag_method,
A history is created for the file if it does not already exist.
With '-', take comment text from stdin; with '-m' use the
following string as the comment; with '-f' take from a file.
- With '-e', edit even after '-f' or '-m'. ci is a synonym for commit.
+ With '-e', edit even after '-f' or '-m'. "ci" is a synonym for commit.
src amend [- | -m string | -f file | -e] ['revision'] ['file'...]::
Amends the stored comment for a specified revision, defaulting to the
src checkout [revision] ['file'...]::
Refresh the working copy of the file(s) from their history files.
- co is a synonym for checkout.
+ "co" is a synonym for checkout.
-src status ['file'...]::
+src status [-a] ['file'...]::
A = added, . = unmodified, M = modified, ! = missing, ? = not tracked,
I = ignored, L = locked (recover with src checkout). The A and L
statuses should only occur if you have used RCS directly on a file.
+ Normally ? and I files are nit listed; this changes if you either
+ give the -a switch or specify which files to look at. "st" is a
+ synonym for status.
src cat ['revision'] ['file'...]::
Send the specified revision of the files to standard output.