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.skipSubmitModTimeCheck 206 207 git config [--global] git-p4.skipSubmitModTimeCheck false 208 209If true, submit will not check if the p4 change template has been modified. 210 211git-p4.preserveUser 212 213 git config [--global] git-p4.preserveUser false 214 215If true, attempt to preserve user names by modifying the p4 changelists. See 216the "--preserve-user" submit option. 217 218git-p4.allowMissingPerforceUsers 219 220 git config [--global] git-p4.allowMissingP4Users false 221 222If git-p4 is setting the perforce user for a commit (--preserve-user) then 223if there is no perforce user corresponding to the git author, git-p4 will 224stop. With allowMissingPerforceUsers set to true, git-p4 will use the 225current user (i.e. the behavior without --preserve-user) and carry on with 226the perforce commit. 227 228git-p4.skipUserNameCheck 229 230 git config [--global] git-p4.skipUserNameCheck false 231 232When submitting, git-p4 checks that the git commits are authored by the current 233p4 user, and warns if they are not. This disables the check. 234 235git-p4.detectRenames 236 237Detect renames when submitting changes to Perforce server. Will enable -M git 238argument. Can be optionally set to a number representing the threshold 239percentage value of the rename detection. 240 241 git config [--global] git-p4.detectRenames true 242 git config [--global] git-p4.detectRenames 50 243 244git-p4.detectCopies 245 246Detect copies when submitting changes to Perforce server. Will enable -C git 247argument. Can be optionally set to a number representing the threshold 248percentage value of the copy detection. 249 250 git config [--global] git-p4.detectCopies true 251 git config [--global] git-p4.detectCopies 80 252 253git-p4.detectCopiesHarder 254 255Detect copies even between files that did not change when submitting changes to 256Perforce server. Will enable --find-copies-harder git argument. 257 258 git config [--global] git-p4.detectCopies true 259 260git-p4.branchUser 261 262Only use branch specifications defined by the selected username. 263 264 git config [--global] git-p4.branchUser username 265 266git-p4.branchList 267 268List of branches to be imported when branch detection is enabled. 269 270 git config [--global] git-p4.branchList main:branchA 271 git config [--global] --add git-p4.branchList main:branchB 272 273Implementation Details... 274========================= 275 276* Changesets from Perforce are imported using git fast-import. 277* The import does not require anything from the Perforce client view as it just uses 278 "p4 print //depot/path/file#revision" to get the actual file contents. 279* Every imported changeset has a special [git-p4...] line at the 280 end of the log message that gives information about the corresponding 281 Perforce change number and is also used by git-p4 itself to find out 282 where to continue importing when doing incremental imports. 283 Basically when syncing it extracts the perforce change number of the 284 latest commit in the "p4" branch and uses "p4 changes //depot/path/...@changenum,#head" 285 to find out which changes need to be imported. 286* git-p4 submit uses "git rev-list" to pick the commits between the "p4" branch 287 and the current branch. 288 The commits themselves are applied using git diff/format-patch ... | git apply 289