Merge "jiri: More documentation."
diff --git a/README.md b/README.md
index 2123c0a..29336ce 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,72 @@
 * restoring local project state from a snapshot, and
 * facilitating sending change lists to [Gerrit][gerrit].
 
+Jiri has an extensible plugin model, making it easy to create new sub-commands.
+
 Jiri is open-source.  See the contributor guidelines [here][contributing].
 
+## Jiri Basics
+Jiri organizes a set of repositories on your local filesystem according to a
+[manifest][manifests].  These repositories are referred to as "projects", and
+are all contained within a single directory called the "jiri root" which is
+assumed to be set in the `JIRI_ROOT` environment variable.
+
+The manifest file specifies the relative location of each project within the
+jiri root, and also includes other metadata about the project such as its
+remote url, the remote branch it should track, and more.
+
+The `jiri update` command syncs the master branch of all local projects to the
+revision and remote branch specified in the manifest for each project.  Jiri
+will create the project locally if it does not exist, and if run with the `-gc`
+flag, jiri will "garbage collect" any projects that are not listed in the
+manifest by deleting them locally.
+
+The `.jiri_manifest` file in the jiri root describes which project jiri should
+sync.  Typically the `.jiri_manifest` file will import other manifests, but it
+can also contain a list of projects.
+
+For example, here is a simple `.jiri_manifest` with just two projects, "foo"
+and "bar", which are hosted on github and bitbucket respectively.
+```
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+  <projects>
+    <project name="foo-project"
+             remote="https://github.com/my-org/foo"
+             path="foo"/>
+    <project name="bar"
+             remote="https://bitbucket.com/other-org/bar"
+             path="bar"/>
+  </projects>
+</manifest>
+```
+When you run `jiri update` for the first time, the "foo" and "bar" repos will
+be cloned into `$JIRI_ROOT/foo` and `$JIRI_ROOT/bar` respectively.  Running
+`jiri update` again will sync the master branch of these repos with the remote
+master branch.
+
+Note that the project paths do not need to be immediate children of the jiri
+root.  We could have decided to set the `path` attribute for the "bar" project
+to "third_party/bar", or even nest "bar" inside the "foo" project by setting
+the `path` to  "foo/bar" (assuming no files in the foo repo conflict with bar).
+
+Because manifest files also need to be kept in sync between various team
+members, it often makes sense to keep your team's manifests in a version
+controlled repository.
+
+Jiri makes it easy to "import" a remote manifest from your local
+`.jiri_manifest` file with the `jiri import` command.  For example, running the
+following command will create a `.jiri_manifest` file (or append to an existing
+one) with an `import` tag that imports the minimal manifest from the
+https://github.com/vanadium/manifest repo.
+
+ ```
+ jiri import -name="manifest" minimal https://github.com/vanadium/manifest
+```
+
+The next time you run `jiri update`, jiri will sync all projects listed in the
+Vanadium minimal manifest.
+
 ## Quickstart
 
 This section explains how to get started with jiri.
@@ -169,17 +233,17 @@
 
 ## Filesystem
 
-TODO(nlacasse): There's a pretty good description of the filesystem layout at
-`jiri help filesystem`.  Do we want to keep those docs there, or move them
-here?  Maybe figure out a way to include them in both places but only have a
-single copy in source control.
+<!-- TODO(nlacasse): Figure out a way to keep the canonical documentation in
+one place but mirror it to the README and cmdline docs. -->
+
+See the jiri [filesystem godocs](https://godoc.org/v.io/jiri/cmd/jiri#hdr-Jiri_filesystem___Description_of_jiri_file_system_layout).
 
 ## Manifests<a name="manifests"></a>
 
-TODO(nlacasse): There's a brief description of manifests in `jiri help
-manifest`, but it needs a lot of improvement.  Do we want to keep those docs
-there, or move them here?  Maybe figure out a way to include them in both
-places but only have a single copy in source control.
+<!-- TODO(nlacasse): Figure out a way to keep the canonical documentation in
+one place but mirror it to the README and cmdline docs. -->
+
+See the jiri [manifest godocs](https://godoc.org/v.io/jiri/cmd/jiri#hdr-Jiri_manifest___Description_of_manifest_files).
 
 ## Snapshots
 
@@ -220,10 +284,10 @@
 the remote master via the Gerrit code review system.  The change can then be
 merged into the local master branch with `jiri update`.
 
-TODO(nlacasse): dje is changing this behavior.  The plan is that "master" will
-be the default reserved branch for each repo, but that can be overridden with
-the `localbranch` attribute in the manifest.  Update this section once this
-change lands.
+<!-- TODO(nlacasse): dje is changing this behavior.  The plan is that "master"
+will be the default reserved branch for each repo, but that can be overridden
+with the `localbranch` attribute in the manifest.  Update this section once
+this change lands. -->
 
 ### Creating a new CL
 
@@ -343,9 +407,39 @@
 has not been merged into master yet.  For this reason, we recommend using `jiri
 cl cleanup` to delete the feature branch safely.
 
-## FAQ
+### Dependent CLs
+If you have changes A and B, and B depends on A, you can still submit distinct
+CLs for A and B that can be reviewed and submitted independently (although A
+must be submitted before B).
 
-TODO(nlacasse): Answer these.
+First, create your feature branch for A, make your change, and upload the CL
+for review according to the instructions above.
+
+Then, while still on the feature branch for A, create your feature branch for B.
+```
+jiri cl new feature-B
+```
+Then make your change and upload the CL for review according to the
+instructions above.
+
+You can respond to review comments by submitting new patch sets as normal.
+
+After the CL for A has been submitted, make sure to clean up A's feature branch
+and upload a new patch set for feature B.
+```
+jiri update # fetch update that includes feature A
+git checkout feature-B
+jiri cl cleanup feature-A
+git merge master # merge feature A into feature B branch
+jiri cl mail # send new patch set for feature B
+```
+The CL for feature B can now be submitted.
+
+This process can be extended for more than 2 CLs.  You must keep two things in mind:
+* always create the dependent feature branch with `jiri cl new` from the parent feature branch, and
+* after a parent feature has been submitted, cleanup the parent feature branch with `jiri cl cleanup`, and merge master into all dependent CLs and upload new patch sets.
+
+## FAQ
 
 ### Why the name "jiri"?
 [Jiří][jiri-wiki] is a very popular boys name in the Czech Republic.
@@ -355,11 +449,16 @@
 
 The actual Czech name [Jiří][jiri-wiki] is pronounced something like "yirzhee".
 
-### Why not repo/gclient/etc?
-
 ### Why can't I commit to my master branch?
 
+Jiri keeps the master branch of each project in the state described in the
+manifest.  Any changes that are made to the master branch would be lost during
+the next `jiri update`.
+
+<!-- TODO(nlacasse): Answer these.
+### Why not repo/gclient/etc?
 ### How can I test changes to a manifest without pushing it upstream?
+-->
 
 [android repo]: https://source.android.com/source/using-repo.html "Repo command reference"
 [bootstrap_jiri]: scripts/bootstrap_jiri "bootstrap_jiri"
diff --git a/cmd/jiri/cmd.go b/cmd/jiri/cmd.go
index 0d4d2ee..a5d8ab5 100644
--- a/cmd/jiri/cmd.go
+++ b/cmd/jiri/cmd.go
@@ -111,48 +111,123 @@
 logic.  This is the reason the shim script is recommended over running the
 binary directly.
 
-The binary is located at [root]/.jiri_root/bin/jiri
+The jiri binary is located at [root]/.jiri_root/bin/jiri
 `,
 }
 
-// TODO(toddw): Update the description of manifest files.
 var topicManifest = cmdline.Topic{
 	Name:  "manifest",
 	Short: "Description of manifest files",
 	Long: `
-Jiri manifests are revisioned and stored in a "manifest" repository, that is
-available locally in $JIRI_ROOT/.manifest. The manifest uses the following XML
-schema:
+Jiri manifest files describe the set of projects that get synced and tools that
+get built when running "jiri update".
 
- <manifest>
-   <imports>
-     <import name="default"/>
-     ...
-   </imports>
-   <projects>
-     <project name="release.go.jiri"
-              path="release/go/src/v.io/jiri"
-              protocol="git"
-              name="https://vanadium.googlesource.com/release.go.jiri"
-              revision="HEAD"/>
-     ...
-   </projects>
-   <tools>
-     <tool name="jiri" package="v.io/jiri"/>
-     ...
-   </tools>
- </manifest>
+The first manifest file that jiri reads is in $JIRI_ROOT/.jiri_manifest.  This
+manifest **must** exist for the jiri tool to work.
 
-The <import> element can be used to share settings across multiple
-manifests. Import names are interpreted relative to the $JIRI_ROOT/.manifest/v2
-directory. Import cycles are not allowed and if a project or a tool is specified
-multiple times, the last specification takes effect. In particular, the elements
-<project name="foo" exclude="true"/> and <tool name="bar" exclude="true"/> can
-be used to exclude previously included projects and tools.
+Usually the manifest in $JIRI_ROOT/.jiri_manifest will import other manifests
+from remote repositories via <import> tags, but it can contain its own list of
+projects and tools as well.
 
-The tool identifies which manifest to use using the following algorithm. If the
-$JIRI_ROOT/.local_manifest file exists, then it is used. Otherwise, the
-$JIRI_ROOT/.manifest/v2/<manifest>.xml file is used, where <manifest> is the
-value of the -manifest command-line flag, which defaults to "default".
+Manifests have the following XML schema:
+
+<manifest>
+  <imports>
+    <import remote="https://vanadium.googlesource.com/manifest"
+            manifest="public"
+            name="manifest"
+    />
+    <localimport file="/path/to/local/manifest"/>
+    ...
+  </imports>
+  <projects>
+    <project name="my-project"
+             path="path/where/project/lives"
+             protocol="git"
+             remote="https://github.com/myorg/foo"
+             revision="ed42c05d8688ab23"
+             remotebranch="my-branch"
+             gerrithost="https://myorg-review.googlesource.com"
+             githooks="path/to/githooks-dir"
+             runhook="path/to/runhook-script"
+    />
+    ...
+  </projects>
+  <tools>
+    <tool name="jiri"
+          package="v.io/jiri"
+          project="release.go.jiri"
+    />
+    ...
+  </tools>
+</manifest>
+
+The <import> and <localimport> tags can be used to share common projects and
+tools across multiple manifests.
+
+A <localimport> tag should be used when the manifest being imported and the
+importing manifest are both in the same repository, or when neither one is in a
+repository.  The "file" attribute is the path to the manifest file being
+imported.  It can be absolute, or relative to the importing manifest file.
+
+If the manifest being imported and the importing manifest are in different
+repositories then an <import> tag must be used, with the following attributes:
+
+* remote (required) - The remote url of the repository containing the
+manifest to be imported
+
+* manifest (required) - The path of the manifest file to be imported,
+relative to the repository root.
+
+* name (optional) - The name of the project corresponding to the manifest
+repository.  If your manifest contains a <project> with the same remote as
+the manifest remote, then the "name" attribute of on the <import> tag should
+match the "name" attribute on the <project>.  Otherwise, jiri will clone the
+manifest repository on every update.
+
+The <project> tags describe the projects to sync, and what state they should
+sync to, accoring to the following attributes:
+
+* name (required) - The name of the project.
+
+* path (required) - The location where the project will be located, relative to
+the jiri root.
+
+* remote (required) - The remote url of the project repository.
+
+* protocol (optional) - The protocol to use when cloning and syncing the repo.
+Currently "git" is the default and only supported protocol.
+
+* remotebranch (optional) - The remote branch that the project will sync to.
+Defaults to "master".  The "remotebranch" attribute is ignored if "revision"
+is specified.
+
+* revision (optional) - The specific revision (usually a git SHA) that the
+project will sync to.  If "revision" is  specified then the "remotebranch"
+attribute is ignored.
+
+* gerrithost (optional) - The url of the Gerrit host for the project.  If
+specified, then running "jiri cl mail" will upload a CL to this Gerrit host.
+
+* githooks (optional) - The path (relative to $JIRI_ROOT) of a directory
+containing git hooks that will be installed in the projects .git/hooks
+directory during each update.
+
+* runhook (optional) - The path (relate to $JIRI_ROOT) of a script that will be
+run during each update.
+
+The <tool> tags describe the tools that will be compiled and installed in
+$JIRI_ROOT/.jiri_root/bin after each update.  The tools must be written in go,
+and are identified by their package name and the project that contains their
+code.  They are configured via the following attributes:
+
+* name (required) - The name of the binary that will be installed in
+  JIRI_ROOT/.jiri_root/bin
+
+* package (required) - The name of the Go package that will be passed to "go
+  build".
+
+* project (required) - The name of the project that contains the source code
+  for the tool.
 `,
 }
diff --git a/cmd/jiri/doc.go b/cmd/jiri/doc.go
index 3bd4684..a1e9106 100644
--- a/cmd/jiri/doc.go
+++ b/cmd/jiri/doc.go
@@ -864,43 +864,119 @@
 logic.  This is the reason the shim script is recommended over running the
 binary directly.
 
-The binary is located at [root]/.jiri_root/bin/jiri
+The jiri binary is located at [root]/.jiri_root/bin/jiri
 
 Jiri manifest - Description of manifest files
 
-Jiri manifests are revisioned and stored in a "manifest" repository, that is
-available locally in $JIRI_ROOT/.manifest. The manifest uses the following XML
-schema:
+Jiri manifest files describe the set of projects that get synced and tools that
+get built when running "jiri update".
 
- <manifest>
-   <imports>
-     <import name="default"/>
-     ...
-   </imports>
-   <projects>
-     <project name="release.go.jiri"
-              path="release/go/src/v.io/jiri"
-              protocol="git"
-              name="https://vanadium.googlesource.com/release.go.jiri"
-              revision="HEAD"/>
-     ...
-   </projects>
-   <tools>
-     <tool name="jiri" package="v.io/jiri"/>
-     ...
-   </tools>
- </manifest>
+The first manifest file that jiri reads is in $JIRI_ROOT/.jiri_manifest.  This
+manifest **must** exist for the jiri tool to work.
 
-The <import> element can be used to share settings across multiple manifests.
-Import names are interpreted relative to the $JIRI_ROOT/.manifest/v2 directory.
-Import cycles are not allowed and if a project or a tool is specified multiple
-times, the last specification takes effect. In particular, the elements <project
-name="foo" exclude="true"/> and <tool name="bar" exclude="true"/> can be used to
-exclude previously included projects and tools.
+Usually the manifest in $JIRI_ROOT/.jiri_manifest will import other manifests
+from remote repositories via <import> tags, but it can contain its own list of
+projects and tools as well.
 
-The tool identifies which manifest to use using the following algorithm. If the
-$JIRI_ROOT/.local_manifest file exists, then it is used. Otherwise, the
-$JIRI_ROOT/.manifest/v2/<manifest>.xml file is used, where <manifest> is the
-value of the -manifest command-line flag, which defaults to "default".
+Manifests have the following XML schema:
+
+<manifest>
+  <imports>
+    <import remote="https://vanadium.googlesource.com/manifest"
+            manifest="public"
+            name="manifest"
+    />
+    <localimport file="/path/to/local/manifest"/>
+    ...
+  </imports>
+  <projects>
+    <project name="my-project"
+             path="path/where/project/lives"
+             protocol="git"
+             remote="https://github.com/myorg/foo"
+             revision="ed42c05d8688ab23"
+             remotebranch="my-branch"
+             gerrithost="https://myorg-review.googlesource.com"
+             githooks="path/to/githooks-dir"
+             runhook="path/to/runhook-script"
+    />
+    ...
+  </projects>
+  <tools>
+    <tool name="jiri"
+          package="v.io/jiri"
+          project="release.go.jiri"
+    />
+    ...
+  </tools>
+</manifest>
+
+The <import> and <localimport> tags can be used to share common projects and
+tools across multiple manifests.
+
+A <localimport> tag should be used when the manifest being imported and the
+importing manifest are both in the same repository, or when neither one is in a
+repository.  The "file" attribute is the path to the manifest file being
+imported.  It can be absolute, or relative to the importing manifest file.
+
+If the manifest being imported and the importing manifest are in different
+repositories then an <import> tag must be used, with the following attributes:
+
+* remote (required) - The remote url of the repository containing the manifest
+to be imported
+
+* manifest (required) - The path of the manifest file to be imported, relative
+to the repository root.
+
+* name (optional) - The name of the project corresponding to the manifest
+repository.  If your manifest contains a <project> with the same remote as the
+manifest remote, then the "name" attribute of on the <import> tag should match
+the "name" attribute on the <project>.  Otherwise, jiri will clone the manifest
+repository on every update.
+
+The <project> tags describe the projects to sync, and what state they should
+sync to, accoring to the following attributes:
+
+* name (required) - The name of the project.
+
+* path (required) - The location where the project will be located, relative to
+the jiri root.
+
+* remote (required) - The remote url of the project repository.
+
+* protocol (optional) - The protocol to use when cloning and syncing the repo.
+Currently "git" is the default and only supported protocol.
+
+* remotebranch (optional) - The remote branch that the project will sync to.
+Defaults to "master".  The "remotebranch" attribute is ignored if "revision" is
+specified.
+
+* revision (optional) - The specific revision (usually a git SHA) that the
+project will sync to.  If "revision" is  specified then the "remotebranch"
+attribute is ignored.
+
+* gerrithost (optional) - The url of the Gerrit host for the project.  If
+specified, then running "jiri cl mail" will upload a CL to this Gerrit host.
+
+* githooks (optional) - The path (relative to $JIRI_ROOT) of a directory
+containing git hooks that will be installed in the projects .git/hooks directory
+during each update.
+
+* runhook (optional) - The path (relate to $JIRI_ROOT) of a script that will be
+run during each update.
+
+The <tool> tags describe the tools that will be compiled and installed in
+$JIRI_ROOT/.jiri_root/bin after each update.  The tools must be written in go,
+and are identified by their package name and the project that contains their
+code.  They are configured via the following attributes:
+
+* name (required) - The name of the binary that will be installed in
+  JIRI_ROOT/.jiri_root/bin
+
+* package (required) - The name of the Go package that will be passed to "go
+  build".
+
+* project (required) - The name of the project that contains the source code
+  for the tool.
 */
 package main