1git-p4 - Perforce <-> Git converter using git-fast-import 2 3Usage 4===== 5 6git-p4 can be used in two different ways: 7 81) To import changes from Perforce to a Git repository, using "git-p4 sync". 9 102) To submit changes from Git back to Perforce, using "git-p4 submit". 11 12Importing 13========= 14 15Simply start with 16 17 git-p4 clone //depot/path/project 18 19or 20 21 git-p4 clone //depot/path/project myproject 22 23This will: 24 251) Create an empty git repository in a subdirectory called "project" (or 26"myproject" with the second command) 27 282) Import the head revision from the given Perforce path into a git branch 29called "p4" (remotes/p4 actually) 30 313) Create a master branch based on it and check it out. 32 33If you want the entire history (not just the head revision) then you can simply 34append a "@all" to the depot path: 35 36 git-p4 clone //depot/project/main@all myproject 37 38 39 40If you want more control you can also use the git-p4 sync command directly: 41 42 mkdir repo-git 43 cd repo-git 44 git init 45 git-p4 sync //path/in/your/perforce/depot 46 47This will import the current head revision of the specified depot path into a 48"remotes/p4/master" branch of your git repository. You can use the 49--branch=mybranch option to import into a different branch. 50 51If you want to import the entire history of a given depot path simply use: 52 53 git-p4 sync //path/in/depot@all 54 55 56Note: 57 58To achieve optimal compression you may want to run 'git repack -a -d -f' after 59a big import. This may take a while. 60 61Incremental Imports 62=================== 63 64After an initial import you can continue to synchronize your git repository 65with newer changes from the Perforce depot by just calling 66 67 git-p4 sync 68 69in your git repository. By default the "remotes/p4/master" branch is updated. 70 71Advanced Setup 72============== 73 74Suppose you have a periodically updated git repository somewhere, containing a 75complete import of a Perforce project. This repository can be cloned and used 76with git-p4. When updating the cloned repository with the "sync" command, 77git-p4 will try to fetch changes from the original repository first. The git 78protocol used with this is usually faster than importing from Perforce 79directly. 80 81This behaviour can be disabled by setting the "git-p4.syncFromOrigin" git 82configuration variable to "false". 83 84Updating 85======== 86 87A common working pattern is to fetch the latest changes from the Perforce depot 88and merge them with local uncommitted changes. The recommended way is to use 89git's rebase mechanism to preserve linear history. git-p4 provides a convenient 90 91 git-p4 rebase 92 93command that calls git-p4 sync followed by git rebase to rebase the current 94working branch. 95 96Submitting 97========== 98 99git-p4 has support for submitting changes from a git repository back to the 100Perforce depot. This requires a Perforce checkout separate from your git 101repository. To submit all changes that are in the current git branch but not in 102the "p4" branch (or "origin" if "p4" doesn't exist) simply call 103 104 git-p4 submit 105 106in your git repository. If you want to submit changes in a specific branch that 107is not your current git branch you can also pass that as an argument: 108 109 git-p4 submit mytopicbranch 110 111You can override the reference branch with the --origin=mysourcebranch option. 112 113The Perforce changelists will be created with the user who ran git-p4. If you 114use --preserve-user then git-p4 will attempt to create Perforce changelists 115with the Perforce user corresponding to the git commit author. You need to 116have sufficient permissions within Perforce, and the git users need to have 117Perforce accounts. Permissions can be granted using 'p4 protect'. 118 119If a submit fails you may have to "p4 resolve" and submit manually. You can 120continue importing the remaining changes with 121 122 git-p4 submit --continue 123 124Example 125======= 126 127# Clone a repository 128 git-p4 clone //depot/path/project 129# Enter the newly cloned directory 130 cd project 131# Do some work... 132 vi foo.h 133# ... and commit locally to gi 134 git commit foo.h 135# In the meantime somebody submitted changes to the Perforce depot. Rebase your latest 136# changes against the latest changes in Perforce: 137 git-p4 rebase 138# Submit your locally committed changes back to Perforce 139 git-p4 submit 140# ... and synchronize with Perforce 141 git-p4 rebase 142 143 144Configuration parameters 145======================== 146 147git-p4.user ($P4USER) 148 149Allows you to specify the username to use to connect to the Perforce repository. 150 151 git config [--global] git-p4.user public 152 153git-p4.password ($P4PASS) 154 155Allows you to specify the password to use to connect to the Perforce repository. 156Warning this password will be visible on the command-line invocation of the p4 binary. 157 158 git config [--global] git-p4.password public1234 159 160git-p4.port ($P4PORT) 161 162Specify the port to be used to contact the Perforce server. As this will be passed 163directly to the p4 binary, it may be in the format host:port as well. 164 165 git config [--global] git-p4.port codes.zimbra.com:2666 166 167git-p4.host ($P4HOST) 168 169Specify the host to contact for a Perforce repository. 170 171 git config [--global] git-p4.host perforce.example.com 172 173git-p4.client ($P4CLIENT) 174 175Specify the client name to use 176 177 git config [--global] git-p4.client public-view 178 179git-p4.allowSubmit 180 181 git config [--global] git-p4.allowSubmit false 182 183git-p4.syncFromOrigin 184 185A useful setup may be that you have a periodically updated git repository 186somewhere that contains a complete import of a Perforce project. That git 187repository can be used to clone the working repository from and one would 188import from Perforce directly after cloning using git-p4. If the connection to 189the Perforce server is slow and the working repository hasn't been synced for a 190while it may be desirable to fetch changes from the origin git repository using 191the efficient git protocol. git-p4 supports this setup by calling "git fetch origin" 192by default if there is an origin branch. You can disable this using: 193 194 git config [--global] git-p4.syncFromOrigin false 195 196git-p4.useclientspec 197 198 git config [--global] git-p4.useclientspec false 199 200The P4CLIENT environment variable should be correctly set for p4 to be 201able to find the relevant client. This client spec will be used to 202both filter the files cloned by git and set the directory layout as 203specified in the client (this implies --keep-path style semantics). 204 205git-p4.skipSubmitEdit 206 207 git config [--global] git-p4.skipSubmitEdit false 208 209Normally, git-p4 invokes an editor after each commit is applied so 210that you can make changes to the submit message. Setting this 211variable to true will skip the editing step, submitting the change as is. 212 213git-p4.skipSubmitEditCheck 214 215 git config [--global] git-p4.skipSubmitEditCheck false 216 217After the editor is invoked, git-p4 normally makes sure you saved the 218change description, as an indication that you did indeed read it over 219and edit it. You can quit without saving to abort the submit (or skip 220this change and continue). Setting this variable to true will cause 221git-p4 not to check if you saved the change description. This variable 222only matters if git-p4.skipSubmitEdit has not been set to true. 223 224git-p4.preserveUser 225 226 git config [--global] git-p4.preserveUser false 227 228If true, attempt to preserve user names by modifying the p4 changelists. See 229the "--preserve-user" submit option. 230 231git-p4.allowMissingPerforceUsers 232 233 git config [--global] git-p4.allowMissingP4Users false 234 235If git-p4 is setting the perforce user for a commit (--preserve-user) then 236if there is no perforce user corresponding to the git author, git-p4 will 237stop. With allowMissingPerforceUsers set to true, git-p4 will use the 238current user (i.e. the behavior without --preserve-user) and carry on with 239the perforce commit. 240 241git-p4.skipUserNameCheck 242 243 git config [--global] git-p4.skipUserNameCheck false 244 245When submitting, git-p4 checks that the git commits are authored by the current 246p4 user, and warns if they are not. This disables the check. 247 248git-p4.detectRenames 249 250Detect renames when submitting changes to Perforce server. Will enable -M git 251argument. Can be optionally set to a number representing the threshold 252percentage value of the rename detection. 253 254 git config [--global] git-p4.detectRenames true 255 git config [--global] git-p4.detectRenames 50 256 257git-p4.detectCopies 258 259Detect copies when submitting changes to Perforce server. Will enable -C git 260argument. Can be optionally set to a number representing the threshold 261percentage value of the copy detection. 262 263 git config [--global] git-p4.detectCopies true 264 git config [--global] git-p4.detectCopies 80 265 266git-p4.detectCopiesHarder 267 268Detect copies even between files that did not change when submitting changes to 269Perforce server. Will enable --find-copies-harder git argument. 270 271 git config [--global] git-p4.detectCopies true 272 273git-p4.branchUser 274 275Only use branch specifications defined by the selected username. 276 277 git config [--global] git-p4.branchUser username 278 279git-p4.branchList 280 281List of branches to be imported when branch detection is enabled. 282 283 git config [--global] git-p4.branchList main:branchA 284 git config [--global] --add git-p4.branchList main:branchB 285 286Implementation Details... 287========================= 288 289* Changesets from Perforce are imported using git fast-import. 290* The import does not require anything from the Perforce client view as it just uses 291 "p4 print //depot/path/file#revision" to get the actual file contents. 292* Every imported changeset has a special [git-p4...] line at the 293 end of the log message that gives information about the corresponding 294 Perforce change number and is also used by git-p4 itself to find out 295 where to continue importing when doing incremental imports. 296 Basically when syncing it extracts the perforce change number of the 297 latest commit in the "p4" branch and uses "p4 changes //depot/path/...@changenum,#head" 298 to find out which changes need to be imported. 299* git-p4 submit uses "git rev-list" to pick the commits between the "p4" branch 300 and the current branch. 301 The commits themselves are applied using git diff/format-patch ... | git apply 302