| 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.skipSubmitModTimeCheck |
| |
| git config [--global] git-p4.skipSubmitModTimeCheck false |
| |
| If true, submit will not check if the p4 change template has been modified. |
| |
| 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 |
| |