One of the coolest parts of Git is that once you learn it, you will never need to use another VCS. My company uses Perforce for version control, and it can be painful. So when I got to work on a new greenfield project, I stuck everything in Git. That worked great for a few weeks until I needed to begin collaborating with other developers who would only use Perforce. Fortunately, Git has a Python script that lets you interact with Perforce servers using a special "git p4" command set. The tricky part is getting it all set up on Windows where Git and Python are out of their normal Unix environment.
Install Git
Install msysgit 1.7.10. Version 1.8.0 didn't work for me because it gave an error about being compiled without python support. Once installed, you should be able to execute "git" at a command prompt and see output similar to this:
C:\Users\elathrop>git
usage: git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[-c name=value] [--help]
<command> [<args>]
The most commonly used git commands are:
add Add file contents to the index
bisect Find by binary search the change that introduced a bug
branch List, create, or delete branches
checkout Checkout a branch or paths to the working tree
clone Clone a repository into a new directory
commit Record changes to the repository
diff Show changes between commits, commit and working tree, etc
fetch Download objects and refs from another repository
grep Print lines matching a pattern
init Create an empty git repository or reinitialize an existing one
log Show commit logs
merge Join two or more development histories together
mv Move or rename a file, a directory, or a symlink
pull Fetch from and merge with another repository or a local branch
push Update remote refs along with associated objects
rebase Forward-port local commits to the updated upstream head
reset Reset current HEAD to the specified state
rm Remove files from the working tree and from the index
show Show various types of objects
status Show the working tree status
tag Create, list, delete or verify a tag object signed with GPG
See 'git help <command>' for more information on a specific command.
When using various git commands, you may get a warning about the terminal:
WARNING: terminal is not fully functional
To fix this, you can set the TERM environment variable to "msys".
Install Python
Install python 2.7.3. I didn't try 3.3.0, so it may work. Once installed, you should be able to execute "python" at a command prompt and see output similar to this:
C:\Users\elathrop>python
Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> ^Z
Install Perforce CLI Tools
Install the perforce command line tools if you do not already have them. Once they are installed you should be able to execute "p4" at a command prompt and see output similar to this:
C:\Users\elathrop>p4
Perforce -- the Fast Software Configuration Management System.
p4 is Perforce's client tool for the command line. Try:
p4 help simple list most common commands
p4 help commands list all standard commands
p4 help command help on a specific command
p4 help administration help on specialized administration topics
p4 help charset help on character set translation
p4 help configurables list server configuration variables
p4 help environment list environment and registry variables
p4 help filetypes list supported file types
p4 help jobview help on jobview syntax
p4 help revisions help on specifying file revisions
p4 help streamintro introduction to streams
p4 help usage generic command line arguments
p4 help views help on view syntax
The full user manual is available at http://www.perforce.com/manual.
Server 2012.1/442152.
According to a Perforce git-p4 knowledge base article you should create a separate client workspace for use with git-p4:
Do Not Commingle Perforce and Git
It is safe to submit changes to Perforce using a client workspace other than the one that Git-p4 uses, with a workspace root folder different from the ones that Git-p4 or Git use. This situation is essentially the same as a coworker submitting changes to Perforce, so bear in mind that it can cause conflicts during rebasing.
Do not submit changes to Perforce using the same client workspace that Git-p4 uses. This workspace is only sparsely populated.
git p4 rebase
does not sync files to this area: Git-p4 usesp4 print
to acquire most file content. Files open in pending changelists in the Git-p4 client will interfere withgit p4 submit
.
I used the P4V GUI tool to create a new client workspace named "git". Next, I had to set the P4CLIENT environment variable equal to "git". To verify it works correctly execute:
C:\Users\elathrop>p4 client
then look for a line that says
Client: git
Install git-p4.py
Save the git-p4.py script from GitHub into your "C:\Program Files (x86)\Git\bin" folder. To enable the "git p4" commands, you need to set up an alias. Edit the file "%USERPROFILE%.gitconfig", and add an alias section:
[alias]
p4 = !'C:\\Program Files (x86)\\Git\\bin\\git-p4.py'
At this point the "git p4" commands should work:
C:\Users\elathrop>git p4
usage: C:\Program Files (x86)\Git\bin\git-p4.py <command> [options]
valid commands: clone, rollback, debug, commit, rebase, branches, sync, submit
Try C:\Program Files (x86)\Git\bin\git-p4.py <command> --help for command specific help.
Using git-p4
You should now be able to clone a Perforce depot path into Git:
C:\>git p4 clone "//some/depot/path/" mygitworkspace
Importing from //some/depot/path/ into mygitworkspace
Initialized empty Git repository in C:/mygitworkspace/.git/
Doing initial import of //some/depot/path/ from revision #head into refs/remotes/p4/master
There's plenty of good documentation out there about how to use git-p4:
Git-p4 workflow follows this pattern:
- Edit files
- Submit edits to Git ...repeat...
- git p4 rebase
- git p4 submit
Tweaking git-p4.py
This step is optional. The Perforce depot I was using had a setting that caused all checkouts to be exclusive. This caused the p4 program to output slightly different text, which caused git-p4.py to fail with a message like "Could not determine file type". To fix this, I had to edit the getP4OpenedType method on line 310. I changed this:
match = re.match(".*\((.+)\)\r?$", result)
to this:
match = re.match(".*\((.+)\)( \*exclusive\*)?\r?$", result)
which enabled git-p4.py to parse the output of the p4 command.
A note about core.editor
There's some difficulty getting your git code.editor setting correct on Windows. To get Notepad++ working for commit messages I had to use this .gitconfig entry:
[core]
editor = 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe' -multiInst -notabbar -nosession -noPlugin
For some reason this same configuration fails during a "git p4 submit" command. I am guessing it has something to do with how python is executing the command and interpreting the spaces and escape characters. This command works for "git p4 submit" but fails on "git commit":
[core]
editor = C:\\Progra~2\\Notepad++\\notepad++.exe -multiInst -notabbar -nosession -noPlugin
My workaround is to create a simple batch file wrapper and place it at "C:\Program Files (x86)\Git\bin\editor.bat":
@echo off
"C:\Program Files (x86)\Notepad++\notepad++.exe" -multiInst -notabbar -nosession -noPlugin %*
then set up your .gitconfig to call this script:
[core]
editor = editor.bat
Success!
If you have made it this far, you should now be able to use git-p4 in your day-to-day workflow, collaborating with a team using Perforce.