Using git-p4

From LSDevLinux
Revision as of 10:30, 24 November 2010 by Mayhewn (talk | contribs) (Reverted edits by Okopacare (Talk); changed back to last version by Eberhard)

Jump to: navigation, search

Using git as a front-end to the Perforce FieldWorks repository.

While p4v has many good features, some developers may be more comfortable using a different front-end to the Perforce FieldWorks repository, such as git-p4. Note that you will still need a Perforce checkout on your machine for git-p4 to commit back to Perforce (see Build_FieldWorks#Check_out_from_VCS for information on checking out from Perforce).

Install git-p4

Install dependencies

Install p4

The latest version of p4 can be found at

$ cd $(mktemp -dt)
$ wget ''
$ sudo install p4 /usr/local/bin

Append to ~/.bashrc:

export P4CLIENT=your_workspace_name
export (or hydra:1935)
export P4USER=your_username (or anonymous)

Close and re-open your terminal.


~$ git clone git://

Link to the git-p4 script from a directory in your PATH, such as ~/bin:

$ mkdir -p ~/bin && cd ~/bin
bin$ ln -s ~/git-p4/git-p4

Set git-p4 to work with file renames/integrations:

$ git config --global git-p4.detectRename true

Updating git-p4

To update git-p4, do

$ cd ~/git-p4
git-p4$ git pull

Check out repository using git-p4

Prepare a place for the code:

$ mkdir -p ~/gp/Calgary
$ cd ~/gp/Calgary

Check out from Perforce using git-p4:

gp/Calgary$ git p4 clone //depot/Calgary/WW

In the gp/Calgary directory, you will need COM, Win32Base, and Win32More, or symlinks to them if they are already checked out elsewhere. See Build_FieldWorks#Check_out_libcom_from_svn for information on checking out libcom from svn.

If you already have COM, Win32Base, and Win32More checked out where Build_FieldWorks#Check_out_libcom_from_svn prescribes, then you can just symlink to them by doing:

gp/Calgary$ for dir in ~/p4repo/Calgary/{COM,Win32Base,Win32More}; do ln -s $dir; done


There is a readme about a different version of git-p4 at .

Updating and pushing

Your workflow might look like:

  • Edit files
$ vim foo.cs
  • Commit locally
$ git commit
  • Update from Perforce
$ git stash
$ git p4 rebase
$ git stash pop
  • Update and commit your work to Perforce
$ git stash
$ git p4 rebase
$ git p4 submit
$ git stash pop

With a topic branch

To work on a topic branch, you can use a workflow similar to the following example.

  [master] $ git checkout -b crashbug
[crashbug] $ vim program.cs && git commit -am "fixed bug"
[crashbug] $ git p4 rebase # rebase crashbug onto head of p4
[crashbug] $ git p4 submit
[crashbug] $ git checkout master
  [master] $ git p4 rebase
  [master] $ git branch -d crashbug


If your master is tracking remotes/p4/master, you made a topic branch "crashbug" from master to work on a bug or feature, and you've made several commits to crashbug but don't want to push all of them since they aren't all ready, but you do want to push just one or two right now, you can push by:

# Cherry pick some_commit from crashbug:
$ git checkout master && git p4 rebase && git cherry-pick some_commit
$ git p4 submit
$ git checkout crashbug && git rebase master

Sending for Code Review

You are on a topic branch based on remotes/p4/master, and you want all commits in the branch to be sent for code review.

$ git p4 rebase # Then make sure it is still what you want to send for review.
$ tinydesc="couple-word description"
$ myaddr=""
$ toaddr=""
$ server=""
$ git send-email --compose --subject="Code Review for $tinydesc" --subject-prefix="$tinydesc patch" \
  --to=$toaddr --smtp-server=$server --from=$myaddr --cc=$myaddr remotes/p4/master..


Protecting csproj files

Since your files are read-write by default when you use git-p4 (rather than read-only when using p4v), you may want to protect .csproj files sometimes so that monodevelop does not rewrite them when you don't want it to. (Though this may make monodevelop unsuccessful at managing your solution file.) You can easily do that by running:

gp/Calgary/WW$ find -name \*csproj -print0 | xargs -0 chmod u-w

To make a csproj writable again, run:

gp/Calgary/WW$ chmod u+w Src/Foo/Baz.csproj

It may be easier to edit the csproj by hand depending on what you want to change.

Git GUI tools

There are numerous git GUI tools available.

You may find it helpful to browse and view history using gitk and make commits and manage your index using git-cola.

Resolving conflicts

If you have work on an old branch, check out that branch and run git rebase master, it may not cleanly apply, saying:

CONFLICT (content): Merge conflict in Src/Foo.cs
Failed to merge in the changes.
Patch failed at 0002 My Patch

To resolve the conflicts, try:

$ sudo aptitude install git-cola kdiff3-qt
$ git config --global --add merge.conflictstyle diff3
$ git-cola &

Choose Edit > Options. In the Merge Tool box, enter kdiff3 and click Save. In the Repository Status pane, click a file in the Unmerged section. The Diff Viewer pane will show something like:

   public void DoSomething()
++<<<<<<< HEAD
 +   if (!true)                           // Their modification
 +     return;
++   throw new NotImplementedException(); // Original code
+    if (!true)                           // Your modification
+      throw new Exception();
++>>>>>>> My Patch

The lines between ||||||| and ======= is the original code. You modified it to say what's between ======= and >>>>>>> My Patch, while someone else (possibly you) modified it to say what's between <<<<<<< HEAD and |||||||.

Right-click the file in the Unmerged section and choose Launch Merge Tool. Use kdiff3 to resolve the merge conflicts (Learn about kdiff3 here and here). Choose File > Save, File > Quit.

Do this for each file in the Unmerged section in git-cola. When you are finished, if git-cola didn't update all the way on its own, choose File > Rescan.

(Note that when you quit kdiff3, git-cola might print "fatal: Unable to create '/home/user/gp/Calgary/WW/.git/index.lock': File exists." to the terminal. If so, you could close and reopen git-cola and resolve that conflict again, or you might be able to click the file in the Unmerged section and click Stage.)

Examine the diffs in the Staged section. Choose File > Quit. In the terminal, type:

$ git rebase --continue