{"thread":{"id":"29247","subject":"[PATCHv3 00/11] git-p4: asciidoc documentation and fixes","startedAt":"2011-12-25T02:07:29Z","lastAt":"2011-12-25T02:07:40Z","messageCount":12,"participants":["Pete Wyckoff"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"181670","messageId":"1324778860-4821-1-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":null,"subject":"[PATCHv3 00/11] git-p4: asciidoc documentation and fixes","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:29Z","receivedAt":"2011-12-25T02:07:29Z","isPatch":false,"sender":{"key":"pw@padd.com","avatar":null},"body":"This series starts with a revamp of the documentation for git-p4,\nmoving it into Documentation/ with the rest of the docs.  Changes\nfrom v2 of this series are:\n\n    - rename tests to be consistent: t98<num>-git-p4-<topic>.sh\n    - drop debug() test helper\n\nPete Wyckoff (11):\n  rename git-p4 tests\n  git-p4: introduce asciidoc documentation\n  git-p4: clone does not use --git-dir\n  git-p4: test cloning with two dirs, clarify doc\n  git-p4: document and test clone --branch\n  git-p4: honor --changesfile option and test\n  git-p4: document and test --import-local\n  git-p4: test --max-changes\n  git-p4: test --keep-path\n  git-p4: test and document --use-client-spec\n  git-p4: document and test submit options\n\n Documentation/git-p4.txt                           |  480 ++++++++++++++++++++\n contrib/fast-import/git-p4                         |   32 ++-\n contrib/fast-import/git-p4.txt                     |  302 ------------\n t/{t9800-git-p4.sh => t9800-git-p4-basic.sh}       |   60 +++\n ...etachars.sh => t9803-git-p4-shell-metachars.sh} |    0\n ...it-edit.sh => t9805-git-p4-skip-submit-edit.sh} |    0\n t/t9806-git-p4-options.sh                          |  170 +++++++\n t/t9807-git-p4-submit.sh                           |   92 ++++\n t/t9807-submit.sh                                  |   38 --\n t/{t9808-chdir.sh => t9808-git-p4-chdir.sh}        |    0\n 10 files changed, 831 insertions(+), 343 deletions(-)\n create mode 100644 Documentation/git-p4.txt\n delete mode 100644 contrib/fast-import/git-p4.txt\n rename t/{t9800-git-p4.sh => t9800-git-p4-basic.sh} (90%)\n rename t/{t9803-git-shell-metachars.sh => t9803-git-p4-shell-metachars.sh} (100%)\n rename t/{t9805-skip-submit-edit.sh => t9805-git-p4-skip-submit-edit.sh} (100%)\n create mode 100755 t/t9806-git-p4-options.sh\n create mode 100755 t/t9807-git-p4-submit.sh\n delete mode 100755 t/t9807-submit.sh\n rename t/{t9808-chdir.sh => t9808-git-p4-chdir.sh} (100%)\n\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181671","messageId":"1324778860-4821-2-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 01/11] rename git-p4 tests","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:30Z","receivedAt":"2011-12-25T02:07:30Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Use consistent naming for all tests: \"t98<num>-git-p4-<topic>.sh\"\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n t/{t9800-git-p4.sh => t9800-git-p4-basic.sh}       |    0\n ...etachars.sh => t9803-git-p4-shell-metachars.sh} |    0\n ...it-edit.sh => t9805-git-p4-skip-submit-edit.sh} |    0\n t/{t9807-submit.sh => t9807-git-p4-submit.sh}      |    0\n t/{t9808-chdir.sh => t9808-git-p4-chdir.sh}        |    0\n 5 files changed, 0 insertions(+), 0 deletions(-)\n rename t/{t9800-git-p4.sh => t9800-git-p4-basic.sh} (100%)\n rename t/{t9803-git-shell-metachars.sh => t9803-git-p4-shell-metachars.sh} (100%)\n rename t/{t9805-skip-submit-edit.sh => t9805-git-p4-skip-submit-edit.sh} (100%)\n rename t/{t9807-submit.sh => t9807-git-p4-submit.sh} (100%)\n rename t/{t9808-chdir.sh => t9808-git-p4-chdir.sh} (100%)\n\ndiff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4-basic.sh\nsimilarity index 100%\nrename from t/t9800-git-p4.sh\nrename to t/t9800-git-p4-basic.sh\ndiff --git a/t/t9803-git-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh\nsimilarity index 100%\nrename from t/t9803-git-shell-metachars.sh\nrename to t/t9803-git-p4-shell-metachars.sh\ndiff --git a/t/t9805-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh\nsimilarity index 100%\nrename from t/t9805-skip-submit-edit.sh\nrename to t/t9805-git-p4-skip-submit-edit.sh\ndiff --git a/t/t9807-submit.sh b/t/t9807-git-p4-submit.sh\nsimilarity index 100%\nrename from t/t9807-submit.sh\nrename to t/t9807-git-p4-submit.sh\ndiff --git a/t/t9808-chdir.sh b/t/t9808-git-p4-chdir.sh\nsimilarity index 100%\nrename from t/t9808-chdir.sh\nrename to t/t9808-git-p4-chdir.sh\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181672","messageId":"1324778860-4821-3-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 02/11] git-p4: introduce asciidoc documentation","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:31Z","receivedAt":"2011-12-25T02:07:31Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Add proper documentation for git-p4.  Delete the old .txt\ndocumentation from contrib/fast-import.\n\nCc: Frans Klaver <fransklaver@gmail.com>\nCc: Luke Diamand <luke@diamand.org>\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt       |  456 ++++++++++++++++++++++++++++++++++++++++\n contrib/fast-import/git-p4.txt |  302 --------------------------\n 2 files changed, 456 insertions(+), 302 deletions(-)\n create mode 100644 Documentation/git-p4.txt\n delete mode 100644 contrib/fast-import/git-p4.txt\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nnew file mode 100644\nindex 0000000..c981407\n--- /dev/null\n+++ b/Documentation/git-p4.txt\n@@ -0,0 +1,456 @@\n+git-p4(1)\n+=========\n+\n+NAME\n+----\n+git-p4 - Import from and submit to Perforce repositories\n+\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git p4 clone' [<sync options>] [<clone options>] <p4 depot path>...\n+'git p4 sync' [<sync options>] [<p4 depot path>...]\n+'git p4 rebase'\n+'git p4 submit' [<submit options>] [<master branch name>]\n+\n+\n+DESCRIPTION\n+-----------\n+This command provides a way to interact with p4 repositories\n+using git.\n+\n+Create a new git repository from an existing p4 repository using\n+'git p4 clone', giving it one or more p4 depot paths.  Incorporate\n+new commits from p4 changes with 'git p4 sync'.  The 'sync' command\n+is also used to include new branches from other p4 depot paths.\n+Submit git changes back to p4 using 'git p4 submit'.  The command\n+'git p4 rebase' does a sync plus rebases the current branch onto\n+the updated p4 remote branch.\n+\n+\n+EXAMPLE\n+-------\n+* Create an alias for 'git p4', using the full path to the 'git-p4'\n+  script if needed:\n++\n+------------\n+$ git config --global alias.p4 '!git-p4'\n+------------\n+\n+* Clone a repository:\n++\n+------------\n+$ git p4 clone //depot/path/project\n+------------\n+\n+* Do some work in the newly created git repository:\n++\n+------------\n+$ cd project\n+$ vi foo.h\n+$ git commit -a -m \"edited foo.h\"\n+------------\n+\n+* Update the git repository with recent changes from p4, rebasing your\n+  work on top:\n++\n+------------\n+$ git p4 rebase\n+------------\n+\n+* Submit your commits back to p4:\n++\n+------------\n+$ git p4 submit\n+------------\n+\n+\n+COMMANDS\n+--------\n+\n+Clone\n+~~~~~\n+Generally, 'git p4 clone' is used to create a new git directory\n+from an existing p4 repository:\n+------------\n+$ git p4 clone //depot/path/project\n+------------\n+This:\n+\n+1.   Creates an empty git repository in a subdirectory called 'project'.\n++\n+2.   Imports the full contents of the head revision from the given p4\n+depot path into a single commit in the git branch 'refs/remotes/p4/master'.\n++\n+3.   Creates a local branch, 'master' from this remote and checks it out.\n+\n+To reproduce the entire p4 history in git, use the '@all' modifier on\n+the depot path:\n+------------\n+$ git p4 clone //depot/path/project@all\n+------------\n+\n+\n+Sync\n+~~~~\n+As development continues in the p4 repository, those changes can\n+be included in the git repository using:\n+------------\n+$ git p4 sync\n+------------\n+This command finds new changes in p4 and imports them as git commits.\n+\n+P4 repositories can be added to an existing git repository using\n+'git p4 sync' too:\n+------------\n+$ mkdir repo-git\n+$ cd repo-git\n+$ git init\n+$ git p4 sync //path/in/your/perforce/depot\n+------------\n+This imports the specified depot into\n+'refs/remotes/p4/master' in an existing git repository.  The\n+'--branch' option can be used to specify a different branch to\n+be used for the p4 content.\n+\n+If a git repository includes branches 'refs/remotes/origin/p4', these\n+will be fetched and consulted first during a 'git p4 sync'.  Since\n+importing directly from p4 is considerably slower than pulling changes\n+from a git remote, this can be useful in a multi-developer environment.\n+\n+\n+Rebase\n+~~~~~~\n+A common working pattern is to fetch the latest changes from the p4 depot\n+and merge them with local uncommitted changes.  Often, the p4 repository\n+is the ultimate location for all code, thus a rebase workflow makes\n+sense.  This command does 'git p4 sync' followed by 'git rebase' to move\n+local commits on top of updated p4 changes.\n+------------\n+$ git p4 rebase\n+------------\n+\n+\n+Submit\n+~~~~~~\n+Submitting changes from a git repository back to the p4 repository\n+requires a separate p4 client workspace.  This should be specified\n+using the 'P4CLIENT' environment variable or the git configuration\n+variable 'git-p4.client'.  The p4 client must exist, but the client root\n+will be created and populated if it does not already exist.\n+\n+To submit all changes that are in the current git branch but not in\n+the 'p4/master' branch, use:\n+------------\n+$ git p4 submit\n+------------\n+\n+To specify a branch other than the current one, use:\n+------------\n+$ git p4 submit topicbranch\n+------------\n+\n+The upstream reference is generally 'refs/remotes/p4/master', but can\n+be overridden using the '--origin=' command-line option.\n+\n+The p4 changes will be created as the user invoking 'git p4 submit'. The\n+'--preserve-user' option will cause ownership to be modified\n+according to the author of the git commit.  This option requires admin\n+privileges in p4, which can be granted using 'p4 protect'.\n+\n+\n+OPTIONS\n+-------\n+\n+General options\n+~~~~~~~~~~~~~~~\n+All commands except clone accept this option.\n+\n+--git-dir <dir>::\n+\tSet the 'GIT_DIR' environment variable.  See linkgit:git[1].\n+\n+Sync options\n+~~~~~~~~~~~~\n+These options can be used in the initial 'clone' as well as in\n+subsequent 'sync' operations.\n+\n+--branch <branch>::\n+\tImport changes into given branch.  If the branch starts with\n+\t'refs/', it will be used as is, otherwise the path 'refs/heads/'\n+\twill be prepended.  The default branch is 'master'.\n+\n+--detect-branches::\n+\tUse the branch detection algorithm to find new paths in p4.  It is\n+\tdocumented below in \"BRANCH DETECTION\".\n+\n+--changesfile <file>::\n+\tImport exactly the p4 change numbers listed in 'file', one per\n+\tline.  Normally, 'git p4' inspects the current p4 repository\n+\tstate and detects the changes it should import.\n+\n+--silent::\n+\tDo not print any progress information.\n+\n+--verbose::\n+\tProvide more progress information.\n+\n+--detect-labels::\n+\tQuery p4 for labels associated with the depot paths, and add\n+\tthem as tags in git.\n+\n+--import-local::\n+\tBy default, p4 branches are stored in 'refs/remotes/p4/',\n+\twhere they will be treated as remote-tracking branches by\n+\tlinkgit:git-branch[1] and other commands.  This option instead\n+\tputs p4 branches in 'refs/heads/p4/'.\n+\n+--max-changes <n>::\n+\tLimit the number of imported changes to 'n'.  Useful to\n+\tlimit the amount of history when using the '@all' p4 revision\n+\tspecifier.\n+\n+--keep-path::\n+\tThe mapping of file names from the p4 depot path to git, by\n+\tdefault, involves removing the entire depot path.  With this\n+\toption, the full p4 depot path is retained in git.  For example,\n+\tpath '//depot/main/foo/bar.c', when imported from\n+\t'//depot/main/', becomes 'foo/bar.c'.  With '--keep-path', the\n+\tgit path is instead 'depot/main/foo/bar.c'.\n+\n+--use-client-spec::\n+\tUse a client spec to find the list of interesting files in p4.\n+\tThe client spec is discovered using 'p4 client -o' which checks\n+\tthe 'P4CLIENT' environment variable and returns a mapping of\n+\tdepot files to workspace files.\n+\n+Clone options\n+~~~~~~~~~~~~~\n+These options can be used in an initial 'clone', along with the 'sync'\n+options described above.\n+\n+--destination <directory>::\n+\tWhere to create the git repository.  If not provided, the last\n+\tcomponent in the p4 depot path is used to create a new\n+\tdirectory.\n+\n+--bare::\n+\tPerform a bare clone.  See linkgit:git-clone[1].\n+\n+-/ <path>::\n+\tExclude selected depot paths when cloning.\n+\n+Submit options\n+~~~~~~~~~~~~~~\n+These options can be used to modify 'git p4 submit' behavior.\n+\n+--verbose::\n+\tProvide more progress information.\n+\n+--origin <commit>::\n+\tUpstream location from which commits are identified to submit to\n+\tp4.  By default, this is the most recent p4 commit reachable\n+\tfrom 'HEAD'.\n+\n+-M[<n>]::\n+\tDetect renames.  See linkgit:git-diff[1].  Renames will be\n+\trepresented in p4 using explicit 'move' operations.\n+\n+--preserve-user::\n+\tRe-author p4 changes before submitting to p4.  This option\n+\trequires p4 admin privileges.\n+\n+\n+DEPOT PATH SYNTAX\n+-----------------\n+The p4 depot path argument to 'git p4 sync' and 'git p4 clone' can\n+be one or more space-separated p4 depot paths, with an optional\n+p4 revision specifier on the end:\n+\n+\"//depot/my/project\"::\n+    Import one commit with all files in the '#head' change under that tree.\n+\n+\"//depot/my/project@all\"::\n+    Import one commit for each change in the history of that depot path.\n+\n+\"//depot/my/project@1,6\"::\n+    Import only changes 1 through 6.\n+\n+\"//depot/proj1 //depot/proj2@all\"::\n+    Import all changes from both named depot paths.\n+\n+See 'p4 help revisions' for the full syntax of p4 revision specifiers.\n+\n+\n+BRANCH DETECTION\n+----------------\n+P4 does not have the same concept of a branch as git.  Instead,\n+p4 organizes its content as a directory tree, where by convention\n+different logical branches are in different locations in the tree.\n+The 'p4 branch' command is used to maintain mappings between\n+different areas in the tree, and indicate related content.  'git p4'\n+can use these mappings to determine branch relationships.\n+\n+If you have a repository where all the branches of interest exist as\n+subdirectories of a single depot path, you can use '--detect-branches'\n+when cloning or syncing to have 'git p4' automatically find\n+subdirectories in p4, and to generate these as branches in git.\n+\n+For example, if the P4 repository structure is:\n+----\n+//depot/main/...\n+//depot/branch1/...\n+----\n+\n+And \"p4 branch -o branch1\" shows a View line that looks like:\n+----\n+//depot/main/... //depot/branch1/...\n+----\n+\n+Then this 'git p4 clone' command:\n+----\n+git p4 clone --detect-branches //depot@all\n+----\n+produces a separate branch in 'refs/remotes/p4/' for //depot/main,\n+called 'master', and one for //depot/branch1 called 'depot/branch1'.\n+\n+However, it is not necessary to create branches in p4 to be able to use\n+them like branches.  Because it is difficult to infer branch\n+relationships automatically, a git configuration setting\n+'git-p4.branchList' can be used to explicitly identify branch\n+relationships.  It is a list of \"source:destination\" pairs, like a\n+simple p4 branch specification, where the \"source\" and \"destination\" are\n+the path elements in the p4 repository.  The example above relied on the\n+presence of the p4 branch.  Without p4 branches, the same result will\n+occur with:\n+----\n+git config git-p4.branchList main:branch1\n+git p4 clone --detect-branches //depot@all\n+----\n+\n+\n+PERFORMANCE\n+-----------\n+The fast-import mechanism used by 'git p4' creates one pack file for\n+each invocation of 'git p4 sync'.  Normally, git garbage compression\n+(linkgit:git-gc[1]) automatically compresses these to fewer pack files,\n+but explicit invocation of 'git repack -adf' may improve performance.\n+\n+\n+CONFIGURATION VARIABLES\n+-----------------------\n+The following config settings can be used to modify 'git p4' behavior.\n+They all are in the 'git-p4' section.\n+\n+General variables\n+~~~~~~~~~~~~~~~~~\n+git-p4.user::\n+\tUser specified as an option to all p4 commands, with '-u <user>'.\n+\tThe environment variable 'P4USER' can be used instead.\n+\n+git-p4.password::\n+\tPassword specified as an option to all p4 commands, with\n+\t'-P <password>'.\n+\tThe environment variable 'P4PASS' can be used instead.\n+\n+git-p4.port::\n+\tPort specified as an option to all p4 commands, with\n+\t'-p <port>'.\n+\tThe environment variable 'P4PORT' can be used instead.\n+\n+git-p4.host::\n+\tHost specified as an option to all p4 commands, with\n+\t'-h <host>'.\n+\tThe environment variable 'P4HOST' can be used instead.\n+\n+git-p4.client::\n+\tClient specified as an option to all p4 commands, with\n+\t'-c <client>'.  This can also be used as a way to find\n+\tthe client spec for the 'useClientSpec' option.\n+\tThe environment variable 'P4CLIENT' can be used instead.\n+\n+Clone and sync variables\n+~~~~~~~~~~~~~~~~~~~~~~~~\n+git-p4.syncFromOrigin::\n+\tBecause importing commits from other git repositories is much faster\n+\tthan importing them from p4, a mechanism exists to find p4 changes\n+\tfirst in git remotes.  If branches exist under 'refs/remote/origin/p4',\n+\tthose will be fetched and used when syncing from p4.  This\n+\tvariable can be set to 'false' to disable this behavior.\n+\n+git-p4.branchUser::\n+\tOne phase in branch detection involves looking at p4 branches\n+\tto find new ones to import.  By default, all branches are\n+\tinspected.  This option limits the search to just those owned\n+\tby the single user named in the variable.\n+\n+git-p4.branchList::\n+\tList of branches to be imported when branch detection is\n+\tenabled.  Each entry should be a pair of branch names separated\n+\tby a colon (:).  This example declares that both branchA and\n+\tbranchB were created from main:\n+-------------\n+git config       git-p4.branchList main:branchA\n+git config --add git-p4.branchList main:branchB\n+-------------\n+\n+git-p4.useClientSpec::\n+\tSpecify that the p4 client spec to be used to identify p4 depot\n+\tpaths of interest.  This is equivalent to specifying the option\n+\t'--use-client-spec'.  The variable 'git-p4.client' can be used\n+\tto specify the name of the client.\n+\n+Submit variables\n+~~~~~~~~~~~~~~~~\n+git-p4.detectRenames::\n+\tDetect renames.  See linkgit:git-diff[1].\n+\n+git-p4.detectCopies::\n+\tDetect copies.  See linkgit:git-diff[1].\n+\n+git-p4.detectCopiesHarder::\n+\tDetect copies harder.  See linkgit:git-diff[1].\n+\n+git-p4.preserveUser::\n+\tOn submit, re-author changes to reflect the git author,\n+\tregardless of who invokes 'git p4 submit'.\n+\n+git-p4.allowMissingP4Users::\n+\tWhen 'preserveUser' is true, 'git p4' normally dies if it\n+\tcannot find an author in the p4 user map.  This setting\n+\tsubmits the change regardless.\n+\n+git-p4.skipSubmitEdit::\n+\tThe submit process invokes the editor before each p4 change\n+\tis submitted.  If this setting is true, though, the editing\n+\tstep is skipped.\n+\n+git-p4.skipSubmitEditCheck::\n+\tAfter editing the p4 change message, 'git p4' makes sure that\n+\tthe description really was changed by looking at the file\n+\tmodification time.  This option disables that test.\n+\n+git-p4.allowSubmit::\n+\tBy default, any branch can be used as the source for a 'git p4\n+\tsubmit' operation.  This configuration variable, if set, permits only\n+\tthe named branches to be used as submit sources.\n+\n+git-p4.skipUserNameCheck::\n+\tIf the user running 'git p4 submit' does not exist in the p4\n+\tuser map, 'git p4' exits.  This option can be used to force\n+\tsubmission regardless.\n+\n+\n+IMPLEMENTATION DETAILS\n+----------------------\n+* Changesets from p4 are imported using git fast-import.\n+* Cloning or syncing does not require a p4 client; file contents are\n+  collected using 'p4 print'.\n+* Submitting requires a p4 client, which is not in the same location\n+  as the git repository.  Patches are applied, one at a time, to\n+  this p4 client and submitted from there.\n+* Each commit imported by 'git p4' has a line at the end of the log\n+  message indicating the p4 depot location and change number.  This\n+  line is used by later 'git p4 sync' operations to know which p4\n+  changes are new.\n+\ndiff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt\ndeleted file mode 100644\nindex 5044a12..0000000\n--- a/contrib/fast-import/git-p4.txt\n+++ /dev/null\n@@ -1,302 +0,0 @@\n-git-p4 - Perforce <-> Git converter using git-fast-import\n-\n-Usage\n-=====\n-\n-git-p4 can be used in two different ways:\n-\n-1) To import changes from Perforce to a Git repository, using \"git-p4 sync\".\n-\n-2) To submit changes from Git back to Perforce, using \"git-p4 submit\".\n-\n-Importing\n-=========\n-\n-Simply start with\n-\n-  git-p4 clone //depot/path/project\n-\n-or\n-\n-  git-p4 clone //depot/path/project myproject\n-\n-This will:\n-\n-1) Create an empty git repository in a subdirectory called \"project\" (or\n-\"myproject\" with the second command)\n-\n-2) Import the head revision from the given Perforce path into a git branch\n-called \"p4\" (remotes/p4 actually)\n-\n-3) Create a master branch based on it and check it out.\n-\n-If you want the entire history (not just the head revision) then you can simply\n-append a \"@all\" to the depot path:\n-\n-  git-p4 clone //depot/project/main@all myproject\n-\n-\n-\n-If you want more control you can also use the git-p4 sync command directly:\n-\n-  mkdir repo-git\n-  cd repo-git\n-  git init\n-  git-p4 sync //path/in/your/perforce/depot\n-\n-This will import the current head revision of the specified depot path into a\n-\"remotes/p4/master\" branch of your git repository. You can use the\n---branch=mybranch option to import into a different branch.\n-\n-If you want to import the entire history of a given depot path simply use:\n-\n-  git-p4 sync //path/in/depot@all\n-\n-\n-Note:\n-\n-To achieve optimal compression you may want to run 'git repack -a -d -f' after\n-a big import. This may take a while.\n-\n-Incremental Imports\n-===================\n-\n-After an initial import you can continue to synchronize your git repository\n-with newer changes from the Perforce depot by just calling\n-\n-  git-p4 sync\n-\n-in your git repository. By default the \"remotes/p4/master\" branch is updated.\n-\n-Advanced Setup\n-==============\n-\n-Suppose you have a periodically updated git repository somewhere, containing a\n-complete import of a Perforce project. This repository can be cloned and used\n-with git-p4. When updating the cloned repository with the \"sync\" command,\n-git-p4 will try to fetch changes from the original repository first. The git\n-protocol used with this is usually faster than importing from Perforce\n-directly.\n-\n-This behaviour can be disabled by setting the \"git-p4.syncFromOrigin\" git\n-configuration variable to \"false\".\n-\n-Updating\n-========\n-\n-A common working pattern is to fetch the latest changes from the Perforce depot\n-and merge them with local uncommitted changes. The recommended way is to use\n-git's rebase mechanism to preserve linear history. git-p4 provides a convenient\n-\n-  git-p4 rebase\n-\n-command that calls git-p4 sync followed by git rebase to rebase the current\n-working branch.\n-\n-Submitting\n-==========\n-\n-git-p4 has support for submitting changes from a git repository back to the\n-Perforce depot. This requires a Perforce checkout separate from your git\n-repository. To submit all changes that are in the current git branch but not in\n-the \"p4\" branch (or \"origin\" if \"p4\" doesn't exist) simply call\n-\n-    git-p4 submit\n-\n-in your git repository. If you want to submit changes in a specific branch that\n-is not your current git branch you can also pass that as an argument:\n-\n-    git-p4 submit mytopicbranch\n-\n-You can override the reference branch with the --origin=mysourcebranch option.\n-\n-The Perforce changelists will be created with the user who ran git-p4. If you\n-use --preserve-user then git-p4 will attempt to create Perforce changelists\n-with the Perforce user corresponding to the git commit author. You need to\n-have sufficient permissions within Perforce, and the git users need to have\n-Perforce accounts. Permissions can be granted using 'p4 protect'.\n-\n-If a submit fails you may have to \"p4 resolve\" and submit manually. You can\n-continue importing the remaining changes with\n-\n-  git-p4 submit --continue\n-\n-Example\n-=======\n-\n-# Clone a repository\n-  git-p4 clone //depot/path/project\n-# Enter the newly cloned directory\n-  cd project\n-# Do some work...\n-  vi foo.h\n-# ... and commit locally to gi\n-  git commit foo.h\n-# In the meantime somebody submitted changes to the Perforce depot. Rebase your latest\n-# changes against the latest changes in Perforce:\n-  git-p4 rebase\n-# Submit your locally committed changes back to Perforce\n-  git-p4 submit\n-# ... and synchronize with Perforce\n-  git-p4 rebase\n-\n-\n-Configuration parameters\n-========================\n-\n-git-p4.user ($P4USER)\n-\n-Allows you to specify the username to use to connect to the Perforce repository.\n-\n-  git config [--global] git-p4.user public\n-\n-git-p4.password ($P4PASS)\n-\n-Allows you to specify the password to use to connect to the Perforce repository.\n-Warning this password will be visible on the command-line invocation of the p4 binary.\n-\n-  git config [--global] git-p4.password public1234\n-\n-git-p4.port ($P4PORT)\n-\n-Specify the port to be used to contact the Perforce server. As this will be passed\n-directly to the p4 binary, it may be in the format host:port as well.\n-\n-  git config [--global] git-p4.port codes.zimbra.com:2666\n-\n-git-p4.host ($P4HOST)\n-\n-Specify the host to contact for a Perforce repository.\n-\n-  git config [--global] git-p4.host perforce.example.com\n-\n-git-p4.client ($P4CLIENT)\n-\n-Specify the client name to use\n-\n-  git config [--global] git-p4.client public-view\n-\n-git-p4.allowSubmit\n-\n-  git config [--global] git-p4.allowSubmit false\n-\n-git-p4.syncFromOrigin\n-\n-A useful setup may be that you have a periodically updated git repository\n-somewhere that contains a complete import of a Perforce project. That git\n-repository can be used to clone the working repository from and one would\n-import from Perforce directly after cloning using git-p4. If the connection to\n-the Perforce server is slow and the working repository hasn't been synced for a\n-while it may be desirable to fetch changes from the origin git repository using\n-the efficient git protocol. git-p4 supports this setup by calling \"git fetch origin\"\n-by default if there is an origin branch. You can disable this using:\n-\n-  git config [--global] git-p4.syncFromOrigin false\n-\n-git-p4.useclientspec\n-\n-  git config [--global] git-p4.useclientspec false\n-\n-The P4CLIENT environment variable should be correctly set for p4 to be\n-able to find the relevant client.  This client spec will be used to\n-both filter the files cloned by git and set the directory layout as\n-specified in the client (this implies --keep-path style semantics).\n-\n-git-p4.skipSubmitEdit\n-\n-  git config [--global] git-p4.skipSubmitEdit false\n-\n-Normally, git-p4 invokes an editor after each commit is applied so\n-that you can make changes to the submit message.  Setting this\n-variable to true will skip the editing step, submitting the change as is.\n-\n-git-p4.skipSubmitEditCheck\n-\n-  git config [--global] git-p4.skipSubmitEditCheck false\n-\n-After the editor is invoked, git-p4 normally makes sure you saved the\n-change description, as an indication that you did indeed read it over\n-and edit it.  You can quit without saving to abort the submit (or skip\n-this change and continue).  Setting this variable to true will cause\n-git-p4 not to check if you saved the change description.  This variable\n-only matters if git-p4.skipSubmitEdit has not been set to true.\n-\n-git-p4.preserveUser\n-\n-  git config [--global] git-p4.preserveUser false\n-\n-If true, attempt to preserve user names by modifying the p4 changelists. See\n-the \"--preserve-user\" submit option.\n-\n-git-p4.allowMissingPerforceUsers\n-\n-  git config [--global] git-p4.allowMissingP4Users false\n-\n-If git-p4 is setting the perforce user for a commit (--preserve-user) then\n-if there is no perforce user corresponding to the git author, git-p4 will\n-stop. With allowMissingPerforceUsers set to true, git-p4 will use the\n-current user (i.e. the behavior without --preserve-user) and carry on with\n-the perforce commit.\n-\n-git-p4.skipUserNameCheck\n-\n-  git config [--global] git-p4.skipUserNameCheck false\n-\n-When submitting, git-p4 checks that the git commits are authored by the current\n-p4 user, and warns if they are not. This disables the check.\n-\n-git-p4.detectRenames\n-\n-Detect renames when submitting changes to Perforce server. Will enable -M git\n-argument. Can be optionally set to a number representing the threshold\n-percentage value of the rename detection.\n-\n-  git config [--global] git-p4.detectRenames true\n-  git config [--global] git-p4.detectRenames 50\n-\n-git-p4.detectCopies\n-\n-Detect copies when submitting changes to Perforce server. Will enable -C git\n-argument. Can be optionally set to a number representing the threshold\n-percentage value of the copy detection.\n-\n-  git config [--global] git-p4.detectCopies true\n-  git config [--global] git-p4.detectCopies 80\n-\n-git-p4.detectCopiesHarder\n-\n-Detect copies even between files that did not change when submitting changes to\n-Perforce server. Will enable --find-copies-harder git argument.\n-\n-  git config [--global] git-p4.detectCopies true\n-\n-git-p4.branchUser\n-\n-Only use branch specifications defined by the selected username.\n-\n-  git config [--global] git-p4.branchUser username\n-\n-git-p4.branchList\n-\n-List of branches to be imported when branch detection is enabled.\n-\n-  git config [--global] git-p4.branchList main:branchA\n-  git config [--global] --add git-p4.branchList main:branchB\n-\n-Implementation Details...\n-=========================\n-\n-* Changesets from Perforce are imported using git fast-import.\n-* The import does not require anything from the Perforce client view as it just uses\n-  \"p4 print //depot/path/file#revision\" to get the actual file contents.\n-* Every imported changeset has a special [git-p4...] line at the\n-  end of the log message that gives information about the corresponding\n-  Perforce change number and is also used by git-p4 itself to find out\n-  where to continue importing when doing incremental imports.\n-  Basically when syncing it extracts the perforce change number of the\n-  latest commit in the \"p4\" branch and uses \"p4 changes //depot/path/...@changenum,#head\"\n-  to find out which changes need to be imported.\n-* git-p4 submit uses \"git rev-list\" to pick the commits between the \"p4\" branch\n-  and the current branch.\n-  The commits themselves are applied using git diff/format-patch ... | git apply\n-\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181673","messageId":"1324778860-4821-4-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 03/11] git-p4: clone does not use --git-dir","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:32Z","receivedAt":"2011-12-25T02:07:32Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Complain if --git-dir is given during a clone.  It has no\neffect.  Only --destination and --bare can change where the newly\ncloned git dir will be.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |    3 ++-\n t/t9806-git-p4-options.sh  |   34 ++++++++++++++++++++++++++++++++++\n 2 files changed, 36 insertions(+), 1 deletions(-)\n create mode 100755 t/t9806-git-p4-options.sh\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 5949803..dafc4a2 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -2335,7 +2335,8 @@ def main():\n     args = sys.argv[2:]\n \n     if len(options) > 0:\n-        options.append(optparse.make_option(\"--git-dir\", dest=\"gitdir\"))\n+        if cmd.needsGit:\n+            options.append(optparse.make_option(\"--git-dir\", dest=\"gitdir\"))\n \n         parser = optparse.OptionParser(cmd.usage.replace(\"%prog\", \"%prog \" + cmdName),\n                                        options,\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nnew file mode 100755\nindex 0000000..8044fb0\n--- /dev/null\n+++ b/t/t9806-git-p4-options.sh\n@@ -0,0 +1,34 @@\n+#!/bin/sh\n+\n+test_description='git-p4 options'\n+\n+. ./lib-git-p4.sh\n+\n+test_expect_success 'start p4d' '\n+\tstart_p4d\n+'\n+\n+test_expect_success 'init depot' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\techo file1 >file1 &&\n+\t\tp4 add file1 &&\n+\t\tp4 submit -d \"change 1\" &&\n+\t\techo file2 >file2 &&\n+\t\tp4 add file2 &&\n+\t\tp4 submit -d \"change 2\" &&\n+\t\techo file3 >file3 &&\n+\t\tp4 add file3 &&\n+\t\tp4 submit -d \"change 3\"\n+\t)\n+'\n+\n+test_expect_success 'clone no --git-dir' '\n+\ttest_must_fail \"$GITP4\" clone --git-dir=xx //depot\n+'\n+\n+test_expect_success 'kill p4d' '\n+\tkill_p4d\n+'\n+\n+test_done\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181674","messageId":"1324778860-4821-5-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 04/11] git-p4: test cloning with two dirs, clarify doc","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:33Z","receivedAt":"2011-12-25T02:07:33Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Document how git-p4 currently works when specifying multiple\ndepot paths:\n\n1.  No branches or directories are named.\n\n2.  Conflicting files are silently ignored---the last change\n    wins.\n\n2.  Option --destination is required, else the last path is construed\n    to be a directory.\n\n3.  Revision specifiers must be the same on all paths for them to\n    take effect.\n\nTest this behavior.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt |   11 +++++++-\n t/t9800-git-p4-basic.sh  |   60 ++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 69 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex c981407..c15b3b7 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -276,8 +276,15 @@ p4 revision specifier on the end:\n \"//depot/my/project@1,6\"::\n     Import only changes 1 through 6.\n \n-\"//depot/proj1 //depot/proj2@all\"::\n-    Import all changes from both named depot paths.\n+\"//depot/proj1@all //depot/proj2@all\"::\n+    Import all changes from both named depot paths into a single\n+    repository.  Only files below these directories are included.\n+    There is not a subdirectory in git for each \"proj1\" and \"proj2\".\n+    You must use the '--destination' option when specifying more\n+    than one depot path.  The revision specifier must be specified\n+    identically on each depot path.  If there are files in the\n+    depot paths with the same name, the path with the most recently\n+    updated version of the file is the one that appears in git.\n \n See 'p4 help revisions' for the full syntax of p4 revision specifiers.\n \ndiff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh\nindex 272de3f..04ee20e 100755\n--- a/t/t9800-git-p4-basic.sh\n+++ b/t/t9800-git-p4-basic.sh\n@@ -65,6 +65,66 @@ test_expect_success 'git-p4 sync new branch' '\n \t)\n '\n \n+test_expect_success 'clone two dirs' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\tmkdir sub1 sub2 &&\n+\t\techo sub1/f1 >sub1/f1 &&\n+\t\techo sub2/f2 >sub2/f2 &&\n+\t\tp4 add sub1/f1 &&\n+\t\tp4 submit -d \"sub1/f1\" &&\n+\t\tp4 add sub2/f2 &&\n+\t\tp4 submit -d \"sub2/f2\"\n+\t) &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot/sub1 //depot/sub2 &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit ls-files >lines &&\n+\t\ttest_line_count = 2 lines &&\n+\t\tgit log --oneline p4/master >lines &&\n+\t\ttest_line_count = 1 lines\n+\t)\n+'\n+\n+test_expect_success 'clone two dirs, @all' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\techo sub1/f3 >sub1/f3 &&\n+\t\tp4 add sub1/f3 &&\n+\t\tp4 submit -d \"sub1/f3\"\n+\t) &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot/sub1@all //depot/sub2@all &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit ls-files >lines &&\n+\t\ttest_line_count = 3 lines &&\n+\t\tgit log --oneline p4/master >lines &&\n+\t\ttest_line_count = 3 lines\n+\t)\n+'\n+\n+test_expect_success 'clone two dirs, @all, conflicting files' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\techo sub2/f3 >sub2/f3 &&\n+\t\tp4 add sub2/f3 &&\n+\t\tp4 submit -d \"sub2/f3\"\n+\t) &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot/sub1@all //depot/sub2@all &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit ls-files >lines &&\n+\t\ttest_line_count = 3 lines &&\n+\t\tgit log --oneline p4/master >lines &&\n+\t\ttest_line_count = 4 lines &&\n+\t\techo sub2/f3 >expected &&\n+\t\ttest_cmp expected f3\n+\t)\n+'\n+\n test_expect_success 'exit when p4 fails to produce marshaled output' '\n \tbadp4dir=\"$TRASH_DIRECTORY/badp4dir\" &&\n \tmkdir \"$badp4dir\" &&\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181675","messageId":"1324778860-4821-6-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 05/11] git-p4: document and test clone --branch","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:34Z","receivedAt":"2011-12-25T02:07:34Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Clone with --branch will not checkout HEAD, unless the branch\nhappens to be called the default refs/remotes/p4/master.  The\n--branch option is most useful with sync; give an example of\nthat.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt  |   10 +++++++++-\n t/t9806-git-p4-options.sh |   11 +++++++++++\n 2 files changed, 20 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex c15b3b7..a5d3d81 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -178,7 +178,15 @@ subsequent 'sync' operations.\n --branch <branch>::\n \tImport changes into given branch.  If the branch starts with\n \t'refs/', it will be used as is, otherwise the path 'refs/heads/'\n-\twill be prepended.  The default branch is 'master'.\n+\twill be prepended.  The default branch is 'master'.  If used\n+\twith an initial clone, no HEAD will be checked out.\n++\n+This example imports a new remote \"p4/proj2\" into an existing\n+git repository:\n+----\n+    $ git init\n+    $ git p4 sync --branch=refs/remotes/p4/proj2 //depot/proj2\n+----\n \n --detect-branches::\n \tUse the branch detection algorithm to find new paths in p4.  It is\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex 8044fb0..7e2e45a 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -27,6 +27,17 @@ test_expect_success 'clone no --git-dir' '\n \ttest_must_fail \"$GITP4\" clone --git-dir=xx //depot\n '\n \n+test_expect_success 'clone --branch' '\n+\t\"$GITP4\" clone --branch=refs/remotes/p4/sb --dest=\"$git\" //depot &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit ls-files >files &&\n+\t\ttest_line_count = 0 files &&\n+\t\ttest_path_is_file .git/refs/remotes/p4/sb\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181676","messageId":"1324778860-4821-7-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 06/11] git-p4: honor --changesfile option and test","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:35Z","receivedAt":"2011-12-25T02:07:35Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"When an explicit list of changes is given, it makes no sense to\nuse @all or @3,5 or any of the other p4 revision specifiers.\nMake the code notice when this happens, instead of just ignoring\n--changesfile.  Test it.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |   16 +++++++++++++++-\n t/t9806-git-p4-options.sh  |   23 +++++++++++++++++++++++\n 2 files changed, 38 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex dafc4a2..d0a9b0d 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -2024,6 +2024,17 @@ class P4Sync(Command, P4UserMap):\n         revision = \"\"\n         self.users = {}\n \n+        # Make sure no revision specifiers are used when --changesfile\n+        # is specified.\n+        bad_changesfile = False\n+        if len(self.changesFile) > 0:\n+            for p in self.depotPaths:\n+                if p.find(\"@\") >= 0 or p.find(\"#\") >= 0:\n+                    bad_changesfile = True\n+                    break\n+        if bad_changesfile:\n+            die(\"Option --changesfile is incompatible with revision specifiers\")\n+\n         newPaths = []\n         for p in self.depotPaths:\n             if p.find(\"@\") != -1:\n@@ -2040,7 +2051,10 @@ class P4Sync(Command, P4UserMap):\n                 revision = p[hashIdx:]\n                 p = p[:hashIdx]\n             elif self.previousDepotPaths == []:\n-                revision = \"#head\"\n+                # pay attention to changesfile, if given, else import\n+                # the entire p4 tree at the head revision\n+                if len(self.changesFile) == 0:\n+                    revision = \"#head\"\n \n             p = re.sub (\"\\.\\.\\.$\", \"\", p)\n             if not p.endswith(\"/\"):\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex 7e2e45a..7a1dba6 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -38,6 +38,29 @@ test_expect_success 'clone --branch' '\n \t)\n '\n \n+test_expect_success 'clone --changesfile' '\n+\tcf=\"$TRASH_DIRECTORY/cf\" &&\n+\ttest_when_finished \"rm \\\"$cf\\\"\" &&\n+\tprintf \"1\\n3\\n\" >\"$cf\" &&\n+\t\"$GITP4\" clone --changesfile=\"$cf\" --dest=\"$git\" //depot &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit log --oneline p4/master >lines &&\n+\t\ttest_line_count = 2 lines\n+\t\ttest_path_is_file file1 &&\n+\t\ttest_path_is_missing file2 &&\n+\t\ttest_path_is_file file3\n+\t)\n+'\n+\n+test_expect_success 'clone --changesfile, @all' '\n+\tcf=\"$TRASH_DIRECTORY/cf\" &&\n+\ttest_when_finished \"rm \\\"$cf\\\"\" &&\n+\tprintf \"1\\n3\\n\" >\"$cf\" &&\n+\ttest_must_fail \"$GITP4\" clone --changesfile=\"$cf\" --dest=\"$git\" //depot@all\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181677","messageId":"1324778860-4821-8-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 07/11] git-p4: document and test --import-local","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:36Z","receivedAt":"2011-12-25T02:07:36Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Explain that it is needed on future syncs to find p4 branches\nin refs/heads.  Test this behavior.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt  |    4 +++-\n t/t9806-git-p4-options.sh |   22 ++++++++++++++++++++++\n 2 files changed, 25 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex a5d3d81..2885b82 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -211,7 +211,9 @@ git repository:\n \tBy default, p4 branches are stored in 'refs/remotes/p4/',\n \twhere they will be treated as remote-tracking branches by\n \tlinkgit:git-branch[1] and other commands.  This option instead\n-\tputs p4 branches in 'refs/heads/p4/'.\n+\tputs p4 branches in 'refs/heads/p4/'.  Note that future\n+\tsync operations must specify '--import-local' as well so that\n+\tthey can find the p4 branches in refs/heads.\n \n --max-changes <n>::\n \tLimit the number of imported changes to 'n'.  Useful to\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex 7a1dba6..6770326 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -61,6 +61,28 @@ test_expect_success 'clone --changesfile, @all' '\n \ttest_must_fail \"$GITP4\" clone --changesfile=\"$cf\" --dest=\"$git\" //depot@all\n '\n \n+# imports both master and p4/master in refs/heads\n+# requires --import-local on sync to find p4 refs/heads\n+# does not update master on sync, just p4/master\n+test_expect_success 'clone/sync --import-local' '\n+\t\"$GITP4\" clone --import-local --dest=\"$git\" //depot@1,2 &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit log --oneline refs/heads/master >lines &&\n+\t\ttest_line_count = 2 lines &&\n+\t\tgit log --oneline refs/heads/p4/master >lines &&\n+\t\ttest_line_count = 2 lines &&\n+\t\ttest_must_fail \"$GITP4\" sync &&\n+\n+\t\t\"$GITP4\" sync --import-local &&\n+\t\tgit log --oneline refs/heads/master >lines &&\n+\t\ttest_line_count = 2 lines &&\n+\t\tgit log --oneline refs/heads/p4/master >lines &&\n+\t\ttest_line_count = 3 lines\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181678","messageId":"1324778860-4821-9-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 08/11] git-p4: test --max-changes","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:37Z","receivedAt":"2011-12-25T02:07:37Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n t/t9806-git-p4-options.sh |   10 ++++++++++\n 1 files changed, 10 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex 6770326..cc0fd26 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -83,6 +83,16 @@ test_expect_success 'clone/sync --import-local' '\n \t)\n '\n \n+test_expect_success 'clone --max-changes' '\n+\t\"$GITP4\" clone --dest=\"$git\" --max-changes 2 //depot@all &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit log --oneline refs/heads/master >lines &&\n+\t\ttest_line_count = 2 lines\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181679","messageId":"1324778860-4821-10-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 09/11] git-p4: test --keep-path","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:38Z","receivedAt":"2011-12-25T02:07:38Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Make sure it leaves the path, below //depot, in git.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n t/t9806-git-p4-options.sh |   24 ++++++++++++++++++++++++\n 1 files changed, 24 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex cc0fd26..6b288ac 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -93,6 +93,30 @@ test_expect_success 'clone --max-changes' '\n \t)\n '\n \n+test_expect_success 'clone --keep-path' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\tmkdir -p sub/dir &&\n+\t\techo f4 >sub/dir/f4 &&\n+\t\tp4 add sub/dir/f4 &&\n+\t\tp4 submit -d \"change 4\"\n+\t) &&\n+\t\"$GITP4\" clone --dest=\"$git\" --keep-path //depot/sub/dir@all &&\n+\ttest_when_finished cleanup_git &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_path_is_missing f4 &&\n+\t\ttest_path_is_file sub/dir/f4\n+\t) &&\n+\tcleanup_git &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot/sub/dir@all &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_path_is_file f4 &&\n+\t\ttest_path_is_missing sub/dir/f4\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181680","messageId":"1324778860-4821-11-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 10/11] git-p4: test and document --use-client-spec","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:39Z","receivedAt":"2011-12-25T02:07:39Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"The depot path is required, even with this option.  Make sure\ngit-p4 fails and exits with non-zero.\n\nContents in the specified depot path will be rearranged according\nto the client spec.  Test this and add a note in the docs.\n\nLeave an XXX suggesting that this is somewhat confusing behavior\nthat might be good to fix later.\n\nFunction stripRepoPath() looks at self.useClientSpec.  Make sure\nthis is set both for command-line option --use-client-spec and\nfor configuration variable git-p4.useClientSpec.  Test this.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt   |    5 +++-\n contrib/fast-import/git-p4 |    6 ++++-\n t/t9806-git-p4-options.sh  |   46 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 55 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex 2885b82..3092571 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -232,7 +232,10 @@ git repository:\n \tUse a client spec to find the list of interesting files in p4.\n \tThe client spec is discovered using 'p4 client -o' which checks\n \tthe 'P4CLIENT' environment variable and returns a mapping of\n-\tdepot files to workspace files.\n+\tdepot files to workspace files.  Note that a depot path is\n+\tstill required, but files found in the path that match in\n+\tthe client spec view will be laid out according to the client\n+\tspec.\n \n Clone options\n ~~~~~~~~~~~~~\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex d0a9b0d..5420bf1 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1951,7 +1951,10 @@ class P4Sync(Command, P4UserMap):\n             if not gitBranchExists(self.refPrefix + \"HEAD\") and self.importIntoRemotes and gitBranchExists(self.branch):\n                 system(\"git symbolic-ref %sHEAD %s\" % (self.refPrefix, self.branch))\n \n-        if self.useClientSpec or gitConfig(\"git-p4.useclientspec\") == \"true\":\n+        if not self.useClientSpec:\n+            if gitConfig(\"git-p4.useclientspec\", \"--bool\") == \"true\":\n+                self.useClientSpec = True\n+        if self.useClientSpec:\n             self.getClientSpec()\n \n         # TODO: should always look at previous commits,\n@@ -2380,6 +2383,7 @@ def main():\n \n     if not cmd.run(args):\n         parser.print_help()\n+        sys.exit(2)\n \n \n if __name__ == '__main__':\ndiff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh\nindex 6b288ac..1f1952a 100755\n--- a/t/t9806-git-p4-options.sh\n+++ b/t/t9806-git-p4-options.sh\n@@ -117,6 +117,52 @@ test_expect_success 'clone --keep-path' '\n \t)\n '\n \n+# clone --use-client-spec must still specify a depot path\n+# if given, it should rearrange files according to client spec\n+# when it has view lines that match the depot path\n+# XXX: should clone/sync just use the client spec exactly, rather\n+# than needing depot paths?\n+test_expect_success 'clone --use-client-spec' '\n+\t(\n+\t\t# big usage message\n+\t\texec >/dev/null &&\n+\t\ttest_must_fail \"$GITP4\" clone --dest=\"$git\" --use-client-spec\n+\t) &&\n+\tcli2=\"$TRASH_DIRECTORY/cli2\" &&\n+\tmkdir -p \"$cli2\" &&\n+\ttest_when_finished \"rmdir \\\"$cli2\\\"\" &&\n+\t(\n+\t\tcd \"$cli2\" &&\n+\t\tp4 client -i <<-EOF\n+\t\tClient: client2\n+\t\tDescription: client2\n+\t\tRoot: $cli2\n+\t\tView: //depot/sub/... //client2/bus/...\n+\t\tEOF\n+\t) &&\n+\tP4CLIENT=client2 &&\n+\ttest_when_finished cleanup_git &&\n+\t\"$GITP4\" clone --dest=\"$git\" --use-client-spec //depot/... &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_path_is_file bus/dir/f4 &&\n+\t\ttest_path_is_file file1\n+\t) &&\n+\tcleanup_git &&\n+\n+\t# same thing again, this time with variable instead of option\n+\tmkdir \"$git\" &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit init &&\n+\t\tgit config git-p4.useClientSpec true &&\n+\t\t\"$GITP4\" sync //depot/... &&\n+\t\tgit checkout -b master p4/master &&\n+\t\ttest_path_is_file bus/dir/f4 &&\n+\t\ttest_path_is_file file1\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"},{"id":"181681","messageId":"1324778860-4821-12-git-send-email-pw@padd.com","threadId":"29247","inReplyTo":"1324778860-4821-1-git-send-email-pw@padd.com","subject":"[PATCH 11/11] git-p4: document and test submit options","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-12-25T02:07:40Z","receivedAt":"2011-12-25T02:07:40Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Clarify there is a -M option, but no -C.  These are both\nconfigurable through variables.\n\nExplain that the allowSubmit variable takes a comma-separated\nlist of branch names.\n\nCatch earlier an invalid branch name given as an argument to\n\"git p4 clone\".\n\nTest option --origin, variable allowSubmit, and explicit master\nbranch name.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n Documentation/git-p4.txt   |    8 +++++-\n contrib/fast-import/git-p4 |    7 +++++\n t/t9807-git-p4-submit.sh   |   54 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 67 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex 3092571..f97b1c5 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -267,7 +267,9 @@ These options can be used to modify 'git p4 submit' behavior.\n \n -M[<n>]::\n \tDetect renames.  See linkgit:git-diff[1].  Renames will be\n-\trepresented in p4 using explicit 'move' operations.\n+\trepresented in p4 using explicit 'move' operations.  There\n+\tis no corresponding option to detect copies, but there are\n+\tvariables for both moves and copies.\n \n --preserve-user::\n \tRe-author p4 changes before submitting to p4.  This option\n@@ -453,7 +455,9 @@ git-p4.skipSubmitEditCheck::\n git-p4.allowSubmit::\n \tBy default, any branch can be used as the source for a 'git p4\n \tsubmit' operation.  This configuration variable, if set, permits only\n-\tthe named branches to be used as submit sources.\n+\tthe named branches to be used as submit sources.  Branch names\n+\tmust be the short names (no \"refs/heads/\"), and should be\n+\tseparated by commas (\",\"), with no spaces.\n \n git-p4.skipUserNameCheck::\n \tIf the user running 'git p4 submit' does not exist in the p4\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 5420bf1..d3c3ad8 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -362,6 +362,11 @@ def isValidGitDir(path):\n def parseRevision(ref):\n     return read_pipe(\"git rev-parse %s\" % ref).strip()\n \n+def branchExists(ref):\n+    rev = read_pipe([\"git\", \"rev-parse\", \"-q\", \"--verify\", ref],\n+                     ignore_error=True)\n+    return len(rev) > 0\n+\n def extractLogMessageFromGitCommit(commit):\n     logMessage = \"\"\n \n@@ -1089,6 +1094,8 @@ class P4Submit(Command, P4UserMap):\n                 die(\"Detecting current git branch failed!\")\n         elif len(args) == 1:\n             self.master = args[0]\n+            if not branchExists(self.master):\n+                die(\"Branch %s does not exist\" % self.master)\n         else:\n             return False\n \ndiff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh\nindex 2cb724e..b1f61e3 100755\n--- a/t/t9807-git-p4-submit.sh\n+++ b/t/t9807-git-p4-submit.sh\n@@ -31,6 +31,60 @@ test_expect_success 'submit with no client dir' '\n \t)\n '\n \n+# make two commits, but tell it to apply only from HEAD^\n+test_expect_success 'submit --origin' '\n+\ttest_when_finished cleanup_git &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_commit \"file3\" &&\n+\t\ttest_commit \"file4\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\t\"$GITP4\" submit --origin=HEAD^\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\tp4 sync &&\n+\t\ttest_path_is_missing \"file3.t\" &&\n+\t\ttest_path_is_file \"file4.t\"\n+\t)\n+'\n+\n+test_expect_success 'submit with allowSubmit' '\n+\ttest_when_finished cleanup_git &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_commit \"file5\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit config git-p4.allowSubmit \"nobranch\" &&\n+\t\ttest_must_fail \"$GITP4\" submit &&\n+\t\tgit config git-p4.allowSubmit \"nobranch,master\" &&\n+\t\t\"$GITP4\" submit\n+\t)\n+'\n+\n+test_expect_success 'submit with master branch name from argv' '\n+\ttest_when_finished cleanup_git &&\n+\t\"$GITP4\" clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\ttest_commit \"file6\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\ttest_must_fail \"$GITP4\" submit nobranch &&\n+\t\tgit branch otherbranch &&\n+\t\tgit reset --hard HEAD^ &&\n+\t\ttest_commit \"file7\" &&\n+\t\t\"$GITP4\" submit otherbranch\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\tp4 sync &&\n+\t\ttest_path_is_file \"file6.t\" &&\n+\t\ttest_path_is_missing \"file7.t\"\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.8.534.g03ab.dirty\n"}]}