Merge branch 'pw/p4-docs-and-tests'

* pw/p4-docs-and-tests:
  git-p4: document and test submit options
  git-p4: test and document --use-client-spec
  git-p4: test --keep-path
  git-p4: test --max-changes
  git-p4: document and test --import-local
  git-p4: honor --changesfile option and test
  git-p4: document and test clone --branch
  git-p4: test cloning with two dirs, clarify doc
  git-p4: clone does not use --git-dir
  git-p4: introduce asciidoc documentation
  rename git-p4 tests
diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt
new file mode 100644
index 0000000..d7f5a51
--- /dev/null
+++ b/Documentation/git-p4.txt
@@ -0,0 +1,479 @@
+git-p4(1)
+=========
+
+NAME
+----
+git-p4 - Import from and submit to Perforce repositories
+
+
+SYNOPSIS
+--------
+[verse]
+'git p4 clone' [<sync options>] [<clone options>] <p4 depot path>...
+'git p4 sync' [<sync options>] [<p4 depot path>...]
+'git p4 rebase'
+'git p4 submit' [<submit options>] [<master branch name>]
+
+
+DESCRIPTION
+-----------
+This command provides a way to interact with p4 repositories
+using git.
+
+Create a new git repository from an existing p4 repository using
+'git p4 clone', giving it one or more p4 depot paths.  Incorporate
+new commits from p4 changes with 'git p4 sync'.  The 'sync' command
+is also used to include new branches from other p4 depot paths.
+Submit git changes back to p4 using 'git p4 submit'.  The command
+'git p4 rebase' does a sync plus rebases the current branch onto
+the updated p4 remote branch.
+
+
+EXAMPLE
+-------
+* Create an alias for 'git p4', using the full path to the 'git-p4'
+  script if needed:
++
+------------
+$ git config --global alias.p4 '!git-p4'
+------------
+
+* Clone a repository:
++
+------------
+$ git p4 clone //depot/path/project
+------------
+
+* Do some work in the newly created git repository:
++
+------------
+$ cd project
+$ vi foo.h
+$ git commit -a -m "edited foo.h"
+------------
+
+* Update the git repository with recent changes from p4, rebasing your
+  work on top:
++
+------------
+$ git p4 rebase
+------------
+
+* Submit your commits back to p4:
++
+------------
+$ git p4 submit
+------------
+
+
+COMMANDS
+--------
+
+Clone
+~~~~~
+Generally, 'git p4 clone' is used to create a new git directory
+from an existing p4 repository:
+------------
+$ git p4 clone //depot/path/project
+------------
+This:
+
+1.   Creates an empty git repository in a subdirectory called 'project'.
++
+2.   Imports the full contents of the head revision from the given p4
+depot path into a single commit in the git branch 'refs/remotes/p4/master'.
++
+3.   Creates a local branch, 'master' from this remote and checks it out.
+
+To reproduce the entire p4 history in git, use the '@all' modifier on
+the depot path:
+------------
+$ git p4 clone //depot/path/project@all
+------------
+
+
+Sync
+~~~~
+As development continues in the p4 repository, those changes can
+be included in the git repository using:
+------------
+$ git p4 sync
+------------
+This command finds new changes in p4 and imports them as git commits.
+
+P4 repositories can be added to an existing git repository using
+'git p4 sync' too:
+------------
+$ mkdir repo-git
+$ cd repo-git
+$ git init
+$ git p4 sync //path/in/your/perforce/depot
+------------
+This imports the specified depot into
+'refs/remotes/p4/master' in an existing git repository.  The
+'--branch' option can be used to specify a different branch to
+be used for the p4 content.
+
+If a git repository includes branches 'refs/remotes/origin/p4', these
+will be fetched and consulted first during a 'git p4 sync'.  Since
+importing directly from p4 is considerably slower than pulling changes
+from a git remote, this can be useful in a multi-developer environment.
+
+
+Rebase
+~~~~~~
+A common working pattern is to fetch the latest changes from the p4 depot
+and merge them with local uncommitted changes.  Often, the p4 repository
+is the ultimate location for all code, thus a rebase workflow makes
+sense.  This command does 'git p4 sync' followed by 'git rebase' to move
+local commits on top of updated p4 changes.
+------------
+$ git p4 rebase
+------------
+
+
+Submit
+~~~~~~
+Submitting changes from a git repository back to the p4 repository
+requires a separate p4 client workspace.  This should be specified
+using the 'P4CLIENT' environment variable or the git configuration
+variable 'git-p4.client'.  The p4 client must exist, but the client root
+will be created and populated if it does not already exist.
+
+To submit all changes that are in the current git branch but not in
+the 'p4/master' branch, use:
+------------
+$ git p4 submit
+------------
+
+To specify a branch other than the current one, use:
+------------
+$ git p4 submit topicbranch
+------------
+
+The upstream reference is generally 'refs/remotes/p4/master', but can
+be overridden using the '--origin=' command-line option.
+
+The p4 changes will be created as the user invoking 'git p4 submit'. The
+'--preserve-user' option will cause ownership to be modified
+according to the author of the git commit.  This option requires admin
+privileges in p4, which can be granted using 'p4 protect'.
+
+
+OPTIONS
+-------
+
+General options
+~~~~~~~~~~~~~~~
+All commands except clone accept this option.
+
+--git-dir <dir>::
+	Set the 'GIT_DIR' environment variable.  See linkgit:git[1].
+
+Sync options
+~~~~~~~~~~~~
+These options can be used in the initial 'clone' as well as in
+subsequent 'sync' operations.
+
+--branch <branch>::
+	Import changes into given branch.  If the branch starts with
+	'refs/', it will be used as is, otherwise the path 'refs/heads/'
+	will be prepended.  The default branch is 'master'.  If used
+	with an initial clone, no HEAD will be checked out.
++
+This example imports a new remote "p4/proj2" into an existing
+git repository:
+----
+    $ git init
+    $ git p4 sync --branch=refs/remotes/p4/proj2 //depot/proj2
+----
+
+--detect-branches::
+	Use the branch detection algorithm to find new paths in p4.  It is
+	documented below in "BRANCH DETECTION".
+
+--changesfile <file>::
+	Import exactly the p4 change numbers listed in 'file', one per
+	line.  Normally, 'git p4' inspects the current p4 repository
+	state and detects the changes it should import.
+
+--silent::
+	Do not print any progress information.
+
+--verbose::
+	Provide more progress information.
+
+--detect-labels::
+	Query p4 for labels associated with the depot paths, and add
+	them as tags in git.
+
+--import-local::
+	By default, p4 branches are stored in 'refs/remotes/p4/',
+	where they will be treated as remote-tracking branches by
+	linkgit:git-branch[1] and other commands.  This option instead
+	puts p4 branches in 'refs/heads/p4/'.  Note that future
+	sync operations must specify '--import-local' as well so that
+	they can find the p4 branches in refs/heads.
+
+--max-changes <n>::
+	Limit the number of imported changes to 'n'.  Useful to
+	limit the amount of history when using the '@all' p4 revision
+	specifier.
+
+--keep-path::
+	The mapping of file names from the p4 depot path to git, by
+	default, involves removing the entire depot path.  With this
+	option, the full p4 depot path is retained in git.  For example,
+	path '//depot/main/foo/bar.c', when imported from
+	'//depot/main/', becomes 'foo/bar.c'.  With '--keep-path', the
+	git path is instead 'depot/main/foo/bar.c'.
+
+--use-client-spec::
+	Use a client spec to find the list of interesting files in p4.
+	The client spec is discovered using 'p4 client -o' which checks
+	the 'P4CLIENT' environment variable and returns a mapping of
+	depot files to workspace files.  Note that a depot path is
+	still required, but files found in the path that match in
+	the client spec view will be laid out according to the client
+	spec.
+
+Clone options
+~~~~~~~~~~~~~
+These options can be used in an initial 'clone', along with the 'sync'
+options described above.
+
+--destination <directory>::
+	Where to create the git repository.  If not provided, the last
+	component in the p4 depot path is used to create a new
+	directory.
+
+--bare::
+	Perform a bare clone.  See linkgit:git-clone[1].
+
+-/ <path>::
+	Exclude selected depot paths when cloning.
+
+Submit options
+~~~~~~~~~~~~~~
+These options can be used to modify 'git p4 submit' behavior.
+
+--verbose::
+	Provide more progress information.
+
+--origin <commit>::
+	Upstream location from which commits are identified to submit to
+	p4.  By default, this is the most recent p4 commit reachable
+	from 'HEAD'.
+
+-M[<n>]::
+	Detect renames.  See linkgit:git-diff[1].  Renames will be
+	represented in p4 using explicit 'move' operations.  There
+	is no corresponding option to detect copies, but there are
+	variables for both moves and copies.
+
+--preserve-user::
+	Re-author p4 changes before submitting to p4.  This option
+	requires p4 admin privileges.
+
+
+DEPOT PATH SYNTAX
+-----------------
+The p4 depot path argument to 'git p4 sync' and 'git p4 clone' can
+be one or more space-separated p4 depot paths, with an optional
+p4 revision specifier on the end:
+
+"//depot/my/project"::
+    Import one commit with all files in the '#head' change under that tree.
+
+"//depot/my/project@all"::
+    Import one commit for each change in the history of that depot path.
+
+"//depot/my/project@1,6"::
+    Import only changes 1 through 6.
+
+"//depot/proj1@all //depot/proj2@all"::
+    Import all changes from both named depot paths into a single
+    repository.  Only files below these directories are included.
+    There is not a subdirectory in git for each "proj1" and "proj2".
+    You must use the '--destination' option when specifying more
+    than one depot path.  The revision specifier must be specified
+    identically on each depot path.  If there are files in the
+    depot paths with the same name, the path with the most recently
+    updated version of the file is the one that appears in git.
+
+See 'p4 help revisions' for the full syntax of p4 revision specifiers.
+
+
+BRANCH DETECTION
+----------------
+P4 does not have the same concept of a branch as git.  Instead,
+p4 organizes its content as a directory tree, where by convention
+different logical branches are in different locations in the tree.
+The 'p4 branch' command is used to maintain mappings between
+different areas in the tree, and indicate related content.  'git p4'
+can use these mappings to determine branch relationships.
+
+If you have a repository where all the branches of interest exist as
+subdirectories of a single depot path, you can use '--detect-branches'
+when cloning or syncing to have 'git p4' automatically find
+subdirectories in p4, and to generate these as branches in git.
+
+For example, if the P4 repository structure is:
+----
+//depot/main/...
+//depot/branch1/...
+----
+
+And "p4 branch -o branch1" shows a View line that looks like:
+----
+//depot/main/... //depot/branch1/...
+----
+
+Then this 'git p4 clone' command:
+----
+git p4 clone --detect-branches //depot@all
+----
+produces a separate branch in 'refs/remotes/p4/' for //depot/main,
+called 'master', and one for //depot/branch1 called 'depot/branch1'.
+
+However, it is not necessary to create branches in p4 to be able to use
+them like branches.  Because it is difficult to infer branch
+relationships automatically, a git configuration setting
+'git-p4.branchList' can be used to explicitly identify branch
+relationships.  It is a list of "source:destination" pairs, like a
+simple p4 branch specification, where the "source" and "destination" are
+the path elements in the p4 repository.  The example above relied on the
+presence of the p4 branch.  Without p4 branches, the same result will
+occur with:
+----
+git config git-p4.branchList main:branch1
+git p4 clone --detect-branches //depot@all
+----
+
+
+PERFORMANCE
+-----------
+The fast-import mechanism used by 'git p4' creates one pack file for
+each invocation of 'git p4 sync'.  Normally, git garbage compression
+(linkgit:git-gc[1]) automatically compresses these to fewer pack files,
+but explicit invocation of 'git repack -adf' may improve performance.
+
+
+CONFIGURATION VARIABLES
+-----------------------
+The following config settings can be used to modify 'git p4' behavior.
+They all are in the 'git-p4' section.
+
+General variables
+~~~~~~~~~~~~~~~~~
+git-p4.user::
+	User specified as an option to all p4 commands, with '-u <user>'.
+	The environment variable 'P4USER' can be used instead.
+
+git-p4.password::
+	Password specified as an option to all p4 commands, with
+	'-P <password>'.
+	The environment variable 'P4PASS' can be used instead.
+
+git-p4.port::
+	Port specified as an option to all p4 commands, with
+	'-p <port>'.
+	The environment variable 'P4PORT' can be used instead.
+
+git-p4.host::
+	Host specified as an option to all p4 commands, with
+	'-h <host>'.
+	The environment variable 'P4HOST' can be used instead.
+
+git-p4.client::
+	Client specified as an option to all p4 commands, with
+	'-c <client>'.  This can also be used as a way to find
+	the client spec for the 'useClientSpec' option.
+	The environment variable 'P4CLIENT' can be used instead.
+
+Clone and sync variables
+~~~~~~~~~~~~~~~~~~~~~~~~
+git-p4.syncFromOrigin::
+	Because importing commits from other git repositories is much faster
+	than importing them from p4, a mechanism exists to find p4 changes
+	first in git remotes.  If branches exist under 'refs/remote/origin/p4',
+	those will be fetched and used when syncing from p4.  This
+	variable can be set to 'false' to disable this behavior.
+
+git-p4.branchUser::
+	One phase in branch detection involves looking at p4 branches
+	to find new ones to import.  By default, all branches are
+	inspected.  This option limits the search to just those owned
+	by the single user named in the variable.
+
+git-p4.branchList::
+	List of branches to be imported when branch detection is
+	enabled.  Each entry should be a pair of branch names separated
+	by a colon (:).  This example declares that both branchA and
+	branchB were created from main:
+-------------
+git config       git-p4.branchList main:branchA
+git config --add git-p4.branchList main:branchB
+-------------
+
+git-p4.useClientSpec::
+	Specify that the p4 client spec to be used to identify p4 depot
+	paths of interest.  This is equivalent to specifying the option
+	'--use-client-spec'.  The variable 'git-p4.client' can be used
+	to specify the name of the client.
+
+Submit variables
+~~~~~~~~~~~~~~~~
+git-p4.detectRenames::
+	Detect renames.  See linkgit:git-diff[1].
+
+git-p4.detectCopies::
+	Detect copies.  See linkgit:git-diff[1].
+
+git-p4.detectCopiesHarder::
+	Detect copies harder.  See linkgit:git-diff[1].
+
+git-p4.preserveUser::
+	On submit, re-author changes to reflect the git author,
+	regardless of who invokes 'git p4 submit'.
+
+git-p4.allowMissingP4Users::
+	When 'preserveUser' is true, 'git p4' normally dies if it
+	cannot find an author in the p4 user map.  This setting
+	submits the change regardless.
+
+git-p4.skipSubmitEdit::
+	The submit process invokes the editor before each p4 change
+	is submitted.  If this setting is true, though, the editing
+	step is skipped.
+
+git-p4.skipSubmitEditCheck::
+	After editing the p4 change message, 'git p4' makes sure that
+	the description really was changed by looking at the file
+	modification time.  This option disables that test.
+
+git-p4.allowSubmit::
+	By default, any branch can be used as the source for a 'git p4
+	submit' operation.  This configuration variable, if set, permits only
+	the named branches to be used as submit sources.  Branch names
+	must be the short names (no "refs/heads/"), and should be
+	separated by commas (","), with no spaces.
+
+git-p4.skipUserNameCheck::
+	If the user running 'git p4 submit' does not exist in the p4
+	user map, 'git p4' exits.  This option can be used to force
+	submission regardless.
+
+
+IMPLEMENTATION DETAILS
+----------------------
+* Changesets from p4 are imported using git fast-import.
+* Cloning or syncing does not require a p4 client; file contents are
+  collected using 'p4 print'.
+* Submitting requires a p4 client, which is not in the same location
+  as the git repository.  Patches are applied, one at a time, to
+  this p4 client and submitted from there.
+* Each commit imported by 'git p4' has a line at the end of the log
+  message indicating the p4 depot location and change number.  This
+  line is used by later 'git p4 sync' operations to know which p4
+  changes are new.
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 5949803..d3c3ad8 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -362,6 +362,11 @@
 def parseRevision(ref):
     return read_pipe("git rev-parse %s" % ref).strip()
 
+def branchExists(ref):
+    rev = read_pipe(["git", "rev-parse", "-q", "--verify", ref],
+                     ignore_error=True)
+    return len(rev) > 0
+
 def extractLogMessageFromGitCommit(commit):
     logMessage = ""
 
@@ -1089,6 +1094,8 @@
                 die("Detecting current git branch failed!")
         elif len(args) == 1:
             self.master = args[0]
+            if not branchExists(self.master):
+                die("Branch %s does not exist" % self.master)
         else:
             return False
 
@@ -1951,7 +1958,10 @@
             if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch):
                 system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch))
 
-        if self.useClientSpec or gitConfig("git-p4.useclientspec") == "true":
+        if not self.useClientSpec:
+            if gitConfig("git-p4.useclientspec", "--bool") == "true":
+                self.useClientSpec = True
+        if self.useClientSpec:
             self.getClientSpec()
 
         # TODO: should always look at previous commits,
@@ -2024,6 +2034,17 @@
         revision = ""
         self.users = {}
 
+        # Make sure no revision specifiers are used when --changesfile
+        # is specified.
+        bad_changesfile = False
+        if len(self.changesFile) > 0:
+            for p in self.depotPaths:
+                if p.find("@") >= 0 or p.find("#") >= 0:
+                    bad_changesfile = True
+                    break
+        if bad_changesfile:
+            die("Option --changesfile is incompatible with revision specifiers")
+
         newPaths = []
         for p in self.depotPaths:
             if p.find("@") != -1:
@@ -2040,7 +2061,10 @@
                 revision = p[hashIdx:]
                 p = p[:hashIdx]
             elif self.previousDepotPaths == []:
-                revision = "#head"
+                # pay attention to changesfile, if given, else import
+                # the entire p4 tree at the head revision
+                if len(self.changesFile) == 0:
+                    revision = "#head"
 
             p = re.sub ("\.\.\.$", "", p)
             if not p.endswith("/"):
@@ -2335,7 +2359,8 @@
     args = sys.argv[2:]
 
     if len(options) > 0:
-        options.append(optparse.make_option("--git-dir", dest="gitdir"))
+        if cmd.needsGit:
+            options.append(optparse.make_option("--git-dir", dest="gitdir"))
 
         parser = optparse.OptionParser(cmd.usage.replace("%prog", "%prog " + cmdName),
                                        options,
@@ -2365,6 +2390,7 @@
 
     if not cmd.run(args):
         parser.print_help()
+        sys.exit(2)
 
 
 if __name__ == '__main__':
diff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt
deleted file mode 100644
index 5044a12..0000000
--- a/contrib/fast-import/git-p4.txt
+++ /dev/null
@@ -1,302 +0,0 @@
-git-p4 - Perforce <-> Git converter using git-fast-import
-
-Usage
-=====
-
-git-p4 can be used in two different ways:
-
-1) To import changes from Perforce to a Git repository, using "git-p4 sync".
-
-2) To submit changes from Git back to Perforce, using "git-p4 submit".
-
-Importing
-=========
-
-Simply start with
-
-  git-p4 clone //depot/path/project
-
-or
-
-  git-p4 clone //depot/path/project myproject
-
-This will:
-
-1) Create an empty git repository in a subdirectory called "project" (or
-"myproject" with the second command)
-
-2) Import the head revision from the given Perforce path into a git branch
-called "p4" (remotes/p4 actually)
-
-3) Create a master branch based on it and check it out.
-
-If you want the entire history (not just the head revision) then you can simply
-append a "@all" to the depot path:
-
-  git-p4 clone //depot/project/main@all myproject
-
-
-
-If you want more control you can also use the git-p4 sync command directly:
-
-  mkdir repo-git
-  cd repo-git
-  git init
-  git-p4 sync //path/in/your/perforce/depot
-
-This will import the current head revision of the specified depot path into a
-"remotes/p4/master" branch of your git repository. You can use the
---branch=mybranch option to import into a different branch.
-
-If you want to import the entire history of a given depot path simply use:
-
-  git-p4 sync //path/in/depot@all
-
-
-Note:
-
-To achieve optimal compression you may want to run 'git repack -a -d -f' after
-a big import. This may take a while.
-
-Incremental Imports
-===================
-
-After an initial import you can continue to synchronize your git repository
-with newer changes from the Perforce depot by just calling
-
-  git-p4 sync
-
-in your git repository. By default the "remotes/p4/master" branch is updated.
-
-Advanced Setup
-==============
-
-Suppose you have a periodically updated git repository somewhere, containing a
-complete import of a Perforce project. This repository can be cloned and used
-with git-p4. When updating the cloned repository with the "sync" command,
-git-p4 will try to fetch changes from the original repository first. The git
-protocol used with this is usually faster than importing from Perforce
-directly.
-
-This behaviour can be disabled by setting the "git-p4.syncFromOrigin" git
-configuration variable to "false".
-
-Updating
-========
-
-A common working pattern is to fetch the latest changes from the Perforce depot
-and merge them with local uncommitted changes. The recommended way is to use
-git's rebase mechanism to preserve linear history. git-p4 provides a convenient
-
-  git-p4 rebase
-
-command that calls git-p4 sync followed by git rebase to rebase the current
-working branch.
-
-Submitting
-==========
-
-git-p4 has support for submitting changes from a git repository back to the
-Perforce depot. This requires a Perforce checkout separate from your git
-repository. To submit all changes that are in the current git branch but not in
-the "p4" branch (or "origin" if "p4" doesn't exist) simply call
-
-    git-p4 submit
-
-in your git repository. If you want to submit changes in a specific branch that
-is not your current git branch you can also pass that as an argument:
-
-    git-p4 submit mytopicbranch
-
-You can override the reference branch with the --origin=mysourcebranch option.
-
-The Perforce changelists will be created with the user who ran git-p4. If you
-use --preserve-user then git-p4 will attempt to create Perforce changelists
-with the Perforce user corresponding to the git commit author. You need to
-have sufficient permissions within Perforce, and the git users need to have
-Perforce accounts. Permissions can be granted using 'p4 protect'.
-
-If a submit fails you may have to "p4 resolve" and submit manually. You can
-continue importing the remaining changes with
-
-  git-p4 submit --continue
-
-Example
-=======
-
-# Clone a repository
-  git-p4 clone //depot/path/project
-# Enter the newly cloned directory
-  cd project
-# Do some work...
-  vi foo.h
-# ... and commit locally to gi
-  git commit foo.h
-# In the meantime somebody submitted changes to the Perforce depot. Rebase your latest
-# changes against the latest changes in Perforce:
-  git-p4 rebase
-# Submit your locally committed changes back to Perforce
-  git-p4 submit
-# ... and synchronize with Perforce
-  git-p4 rebase
-
-
-Configuration parameters
-========================
-
-git-p4.user ($P4USER)
-
-Allows you to specify the username to use to connect to the Perforce repository.
-
-  git config [--global] git-p4.user public
-
-git-p4.password ($P4PASS)
-
-Allows you to specify the password to use to connect to the Perforce repository.
-Warning this password will be visible on the command-line invocation of the p4 binary.
-
-  git config [--global] git-p4.password public1234
-
-git-p4.port ($P4PORT)
-
-Specify the port to be used to contact the Perforce server. As this will be passed
-directly to the p4 binary, it may be in the format host:port as well.
-
-  git config [--global] git-p4.port codes.zimbra.com:2666
-
-git-p4.host ($P4HOST)
-
-Specify the host to contact for a Perforce repository.
-
-  git config [--global] git-p4.host perforce.example.com
-
-git-p4.client ($P4CLIENT)
-
-Specify the client name to use
-
-  git config [--global] git-p4.client public-view
-
-git-p4.allowSubmit
-
-  git config [--global] git-p4.allowSubmit false
-
-git-p4.syncFromOrigin
-
-A useful setup may be that you have a periodically updated git repository
-somewhere that contains a complete import of a Perforce project. That git
-repository can be used to clone the working repository from and one would
-import from Perforce directly after cloning using git-p4. If the connection to
-the Perforce server is slow and the working repository hasn't been synced for a
-while it may be desirable to fetch changes from the origin git repository using
-the efficient git protocol. git-p4 supports this setup by calling "git fetch origin"
-by default if there is an origin branch. You can disable this using:
-
-  git config [--global] git-p4.syncFromOrigin false
-
-git-p4.useclientspec
-
-  git config [--global] git-p4.useclientspec false
-
-The P4CLIENT environment variable should be correctly set for p4 to be
-able to find the relevant client.  This client spec will be used to
-both filter the files cloned by git and set the directory layout as
-specified in the client (this implies --keep-path style semantics).
-
-git-p4.skipSubmitEdit
-
-  git config [--global] git-p4.skipSubmitEdit false
-
-Normally, git-p4 invokes an editor after each commit is applied so
-that you can make changes to the submit message.  Setting this
-variable to true will skip the editing step, submitting the change as is.
-
-git-p4.skipSubmitEditCheck
-
-  git config [--global] git-p4.skipSubmitEditCheck false
-
-After the editor is invoked, git-p4 normally makes sure you saved the
-change description, as an indication that you did indeed read it over
-and edit it.  You can quit without saving to abort the submit (or skip
-this change and continue).  Setting this variable to true will cause
-git-p4 not to check if you saved the change description.  This variable
-only matters if git-p4.skipSubmitEdit has not been set to true.
-
-git-p4.preserveUser
-
-  git config [--global] git-p4.preserveUser false
-
-If true, attempt to preserve user names by modifying the p4 changelists. See
-the "--preserve-user" submit option.
-
-git-p4.allowMissingPerforceUsers
-
-  git config [--global] git-p4.allowMissingP4Users false
-
-If git-p4 is setting the perforce user for a commit (--preserve-user) then
-if there is no perforce user corresponding to the git author, git-p4 will
-stop. With allowMissingPerforceUsers set to true, git-p4 will use the
-current user (i.e. the behavior without --preserve-user) and carry on with
-the perforce commit.
-
-git-p4.skipUserNameCheck
-
-  git config [--global] git-p4.skipUserNameCheck false
-
-When submitting, git-p4 checks that the git commits are authored by the current
-p4 user, and warns if they are not. This disables the check.
-
-git-p4.detectRenames
-
-Detect renames when submitting changes to Perforce server. Will enable -M git
-argument. Can be optionally set to a number representing the threshold
-percentage value of the rename detection.
-
-  git config [--global] git-p4.detectRenames true
-  git config [--global] git-p4.detectRenames 50
-
-git-p4.detectCopies
-
-Detect copies when submitting changes to Perforce server. Will enable -C git
-argument. Can be optionally set to a number representing the threshold
-percentage value of the copy detection.
-
-  git config [--global] git-p4.detectCopies true
-  git config [--global] git-p4.detectCopies 80
-
-git-p4.detectCopiesHarder
-
-Detect copies even between files that did not change when submitting changes to
-Perforce server. Will enable --find-copies-harder git argument.
-
-  git config [--global] git-p4.detectCopies true
-
-git-p4.branchUser
-
-Only use branch specifications defined by the selected username.
-
-  git config [--global] git-p4.branchUser username
-
-git-p4.branchList
-
-List of branches to be imported when branch detection is enabled.
-
-  git config [--global] git-p4.branchList main:branchA
-  git config [--global] --add git-p4.branchList main:branchB
-
-Implementation Details...
-=========================
-
-* Changesets from Perforce are imported using git fast-import.
-* The import does not require anything from the Perforce client view as it just uses
-  "p4 print //depot/path/file#revision" to get the actual file contents.
-* Every imported changeset has a special [git-p4...] line at the
-  end of the log message that gives information about the corresponding
-  Perforce change number and is also used by git-p4 itself to find out
-  where to continue importing when doing incremental imports.
-  Basically when syncing it extracts the perforce change number of the
-  latest commit in the "p4" branch and uses "p4 changes //depot/path/...@changenum,#head"
-  to find out which changes need to be imported.
-* git-p4 submit uses "git rev-list" to pick the commits between the "p4" branch
-  and the current branch.
-  The commits themselves are applied using git diff/format-patch ... | git apply
-
diff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4-basic.sh
similarity index 90%
rename from t/t9800-git-p4.sh
rename to t/t9800-git-p4-basic.sh
index 272de3f..04ee20e 100755
--- a/t/t9800-git-p4.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -65,6 +65,66 @@
 	)
 '
 
+test_expect_success 'clone two dirs' '
+	(
+		cd "$cli" &&
+		mkdir sub1 sub2 &&
+		echo sub1/f1 >sub1/f1 &&
+		echo sub2/f2 >sub2/f2 &&
+		p4 add sub1/f1 &&
+		p4 submit -d "sub1/f1" &&
+		p4 add sub2/f2 &&
+		p4 submit -d "sub2/f2"
+	) &&
+	"$GITP4" clone --dest="$git" //depot/sub1 //depot/sub2 &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git ls-files >lines &&
+		test_line_count = 2 lines &&
+		git log --oneline p4/master >lines &&
+		test_line_count = 1 lines
+	)
+'
+
+test_expect_success 'clone two dirs, @all' '
+	(
+		cd "$cli" &&
+		echo sub1/f3 >sub1/f3 &&
+		p4 add sub1/f3 &&
+		p4 submit -d "sub1/f3"
+	) &&
+	"$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git ls-files >lines &&
+		test_line_count = 3 lines &&
+		git log --oneline p4/master >lines &&
+		test_line_count = 3 lines
+	)
+'
+
+test_expect_success 'clone two dirs, @all, conflicting files' '
+	(
+		cd "$cli" &&
+		echo sub2/f3 >sub2/f3 &&
+		p4 add sub2/f3 &&
+		p4 submit -d "sub2/f3"
+	) &&
+	"$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git ls-files >lines &&
+		test_line_count = 3 lines &&
+		git log --oneline p4/master >lines &&
+		test_line_count = 4 lines &&
+		echo sub2/f3 >expected &&
+		test_cmp expected f3
+	)
+'
+
 test_expect_success 'exit when p4 fails to produce marshaled output' '
 	badp4dir="$TRASH_DIRECTORY/badp4dir" &&
 	mkdir "$badp4dir" &&
diff --git a/t/t9803-git-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh
similarity index 100%
rename from t/t9803-git-shell-metachars.sh
rename to t/t9803-git-p4-shell-metachars.sh
diff --git a/t/t9805-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
similarity index 100%
rename from t/t9805-skip-submit-edit.sh
rename to t/t9805-git-p4-skip-submit-edit.sh
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
new file mode 100755
index 0000000..1f1952a
--- /dev/null
+++ b/t/t9806-git-p4-options.sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+
+test_description='git-p4 options'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+	start_p4d
+'
+
+test_expect_success 'init depot' '
+	(
+		cd "$cli" &&
+		echo file1 >file1 &&
+		p4 add file1 &&
+		p4 submit -d "change 1" &&
+		echo file2 >file2 &&
+		p4 add file2 &&
+		p4 submit -d "change 2" &&
+		echo file3 >file3 &&
+		p4 add file3 &&
+		p4 submit -d "change 3"
+	)
+'
+
+test_expect_success 'clone no --git-dir' '
+	test_must_fail "$GITP4" clone --git-dir=xx //depot
+'
+
+test_expect_success 'clone --branch' '
+	"$GITP4" clone --branch=refs/remotes/p4/sb --dest="$git" //depot &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git ls-files >files &&
+		test_line_count = 0 files &&
+		test_path_is_file .git/refs/remotes/p4/sb
+	)
+'
+
+test_expect_success 'clone --changesfile' '
+	cf="$TRASH_DIRECTORY/cf" &&
+	test_when_finished "rm \"$cf\"" &&
+	printf "1\n3\n" >"$cf" &&
+	"$GITP4" clone --changesfile="$cf" --dest="$git" //depot &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git log --oneline p4/master >lines &&
+		test_line_count = 2 lines
+		test_path_is_file file1 &&
+		test_path_is_missing file2 &&
+		test_path_is_file file3
+	)
+'
+
+test_expect_success 'clone --changesfile, @all' '
+	cf="$TRASH_DIRECTORY/cf" &&
+	test_when_finished "rm \"$cf\"" &&
+	printf "1\n3\n" >"$cf" &&
+	test_must_fail "$GITP4" clone --changesfile="$cf" --dest="$git" //depot@all
+'
+
+# imports both master and p4/master in refs/heads
+# requires --import-local on sync to find p4 refs/heads
+# does not update master on sync, just p4/master
+test_expect_success 'clone/sync --import-local' '
+	"$GITP4" clone --import-local --dest="$git" //depot@1,2 &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git log --oneline refs/heads/master >lines &&
+		test_line_count = 2 lines &&
+		git log --oneline refs/heads/p4/master >lines &&
+		test_line_count = 2 lines &&
+		test_must_fail "$GITP4" sync &&
+
+		"$GITP4" sync --import-local &&
+		git log --oneline refs/heads/master >lines &&
+		test_line_count = 2 lines &&
+		git log --oneline refs/heads/p4/master >lines &&
+		test_line_count = 3 lines
+	)
+'
+
+test_expect_success 'clone --max-changes' '
+	"$GITP4" clone --dest="$git" --max-changes 2 //depot@all &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		git log --oneline refs/heads/master >lines &&
+		test_line_count = 2 lines
+	)
+'
+
+test_expect_success 'clone --keep-path' '
+	(
+		cd "$cli" &&
+		mkdir -p sub/dir &&
+		echo f4 >sub/dir/f4 &&
+		p4 add sub/dir/f4 &&
+		p4 submit -d "change 4"
+	) &&
+	"$GITP4" clone --dest="$git" --keep-path //depot/sub/dir@all &&
+	test_when_finished cleanup_git &&
+	(
+		cd "$git" &&
+		test_path_is_missing f4 &&
+		test_path_is_file sub/dir/f4
+	) &&
+	cleanup_git &&
+	"$GITP4" clone --dest="$git" //depot/sub/dir@all &&
+	(
+		cd "$git" &&
+		test_path_is_file f4 &&
+		test_path_is_missing sub/dir/f4
+	)
+'
+
+# clone --use-client-spec must still specify a depot path
+# if given, it should rearrange files according to client spec
+# when it has view lines that match the depot path
+# XXX: should clone/sync just use the client spec exactly, rather
+# than needing depot paths?
+test_expect_success 'clone --use-client-spec' '
+	(
+		# big usage message
+		exec >/dev/null &&
+		test_must_fail "$GITP4" clone --dest="$git" --use-client-spec
+	) &&
+	cli2="$TRASH_DIRECTORY/cli2" &&
+	mkdir -p "$cli2" &&
+	test_when_finished "rmdir \"$cli2\"" &&
+	(
+		cd "$cli2" &&
+		p4 client -i <<-EOF
+		Client: client2
+		Description: client2
+		Root: $cli2
+		View: //depot/sub/... //client2/bus/...
+		EOF
+	) &&
+	P4CLIENT=client2 &&
+	test_when_finished cleanup_git &&
+	"$GITP4" clone --dest="$git" --use-client-spec //depot/... &&
+	(
+		cd "$git" &&
+		test_path_is_file bus/dir/f4 &&
+		test_path_is_file file1
+	) &&
+	cleanup_git &&
+
+	# same thing again, this time with variable instead of option
+	mkdir "$git" &&
+	(
+		cd "$git" &&
+		git init &&
+		git config git-p4.useClientSpec true &&
+		"$GITP4" sync //depot/... &&
+		git checkout -b master p4/master &&
+		test_path_is_file bus/dir/f4 &&
+		test_path_is_file file1
+	)
+'
+
+test_expect_success 'kill p4d' '
+	kill_p4d
+'
+
+test_done
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
new file mode 100755
index 0000000..b1f61e3
--- /dev/null
+++ b/t/t9807-git-p4-submit.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='git-p4 submit'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+	start_p4d
+'
+
+test_expect_success 'init depot' '
+	(
+		cd "$cli" &&
+		echo file1 >file1 &&
+		p4 add file1 &&
+		p4 submit -d "change 1"
+	)
+'
+
+test_expect_success 'submit with no client dir' '
+	test_when_finished cleanup_git &&
+	"$GITP4" clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		echo file2 >file2 &&
+		git add file2 &&
+		git commit -m "git commit 2" &&
+		rm -rf "$cli" &&
+		git config git-p4.skipSubmitEdit true &&
+		"$GITP4" submit
+	)
+'
+
+# make two commits, but tell it to apply only from HEAD^
+test_expect_success 'submit --origin' '
+	test_when_finished cleanup_git &&
+	"$GITP4" clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		test_commit "file3" &&
+		test_commit "file4" &&
+		git config git-p4.skipSubmitEdit true &&
+		"$GITP4" submit --origin=HEAD^
+	) &&
+	(
+		cd "$cli" &&
+		p4 sync &&
+		test_path_is_missing "file3.t" &&
+		test_path_is_file "file4.t"
+	)
+'
+
+test_expect_success 'submit with allowSubmit' '
+	test_when_finished cleanup_git &&
+	"$GITP4" clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		test_commit "file5" &&
+		git config git-p4.skipSubmitEdit true &&
+		git config git-p4.allowSubmit "nobranch" &&
+		test_must_fail "$GITP4" submit &&
+		git config git-p4.allowSubmit "nobranch,master" &&
+		"$GITP4" submit
+	)
+'
+
+test_expect_success 'submit with master branch name from argv' '
+	test_when_finished cleanup_git &&
+	"$GITP4" clone --dest="$git" //depot &&
+	(
+		cd "$git" &&
+		test_commit "file6" &&
+		git config git-p4.skipSubmitEdit true &&
+		test_must_fail "$GITP4" submit nobranch &&
+		git branch otherbranch &&
+		git reset --hard HEAD^ &&
+		test_commit "file7" &&
+		"$GITP4" submit otherbranch
+	) &&
+	(
+		cd "$cli" &&
+		p4 sync &&
+		test_path_is_file "file6.t" &&
+		test_path_is_missing "file7.t"
+	)
+'
+
+test_expect_success 'kill p4d' '
+	kill_p4d
+'
+
+test_done
diff --git a/t/t9807-submit.sh b/t/t9807-submit.sh
deleted file mode 100755
index 2cb724e..0000000
--- a/t/t9807-submit.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-test_description='git-p4 submit'
-
-. ./lib-git-p4.sh
-
-test_expect_success 'start p4d' '
-	start_p4d
-'
-
-test_expect_success 'init depot' '
-	(
-		cd "$cli" &&
-		echo file1 >file1 &&
-		p4 add file1 &&
-		p4 submit -d "change 1"
-	)
-'
-
-test_expect_success 'submit with no client dir' '
-	test_when_finished cleanup_git &&
-	"$GITP4" clone --dest="$git" //depot &&
-	(
-		cd "$git" &&
-		echo file2 >file2 &&
-		git add file2 &&
-		git commit -m "git commit 2" &&
-		rm -rf "$cli" &&
-		git config git-p4.skipSubmitEdit true &&
-		"$GITP4" submit
-	)
-'
-
-test_expect_success 'kill p4d' '
-	kill_p4d
-'
-
-test_done
diff --git a/t/t9808-chdir.sh b/t/t9808-git-p4-chdir.sh
similarity index 100%
rename from t/t9808-chdir.sh
rename to t/t9808-git-p4-chdir.sh