Saturday, February 12, 2011

Keeping Git in sync with Perforce

This post is not about how great is Git and how "great" is perforce. It doesn't matter which one you prefer, in the end it is a matter of taste. If you don't know much about Git, you could find interesting this presentation: Linus Torvalds on Git

Unfortunately, the company I'm working for has a strict policy regarding SCM usage. For some reason we are forced to use perforce. For a git lover developer this is not nice at all. That is why I started to search for a way to enjoy the Git while keeping in sync from time to time the master branch with perforce.

My first attempt was related to git p4 plugin. Unfortunately it wasn't easy at all to make it work and after several hours I gave up.

My next attempt was to use a manual approach, which can be later simplified by creating a bash script. The idea is simple: since perforce doesn't pollute each folder of the project with all scm specific files (like: .svn or .cvs), the sync is reduced to copying everything from perforce
project folder to Git project folder and vice versa.

Let's say you have a project called testProject and you keep it at the following locations:

a) perforce: /se/perforce/testProject (Lets call it A)
b) Git: /git/testProject (Lets call it B)
Let's say you have developed several new features in your Git repository and pushed the changes to origin. Now you want to sync the changes with perforce.

Here are the steps you would follow:

  1. Get the latest changes from perforce
  2. Go to folder B and create a branch in Git called 'perforce' and delete all project files from here
  3. Copy everything from A to B. Because all the files are read-only, you should change the mode using the following command:
    chmod -v 777 * -R
    
    (we don't want the files to be read-only in Git project folder)
  4. Go to folder B and merge Git 'perforce' branch with the master branch (where your latest developed changes resides). After merge succeeds, you can 'push' the synced version to perforce.
  5. Delete all the project files from folder A.
  6. Copy all the project files from folder B to A.
  7. Make all the files back to read-only in folder A
    chmod -v 755 * -R
  8. Use 'reconcile offline work' in perforce and commit the changes. Now you are done with perforce and it has the latest changes.
  9. Bring the changes from the synced 'perforce' branch to the master and since you don't need the perforce branch anymore, you can delete it:
    git checkout master
    git merge perforce
    git branch -d perforce
    

And that's it.
To automate this steps, a bash script can be created. It would have the following parameters: perforce project location and Git project location. This way you can enjoy developing in Git and be compliant with your company rules in the same time.

2 comments:

  1. You might be able to remove the two chmod steps by setting your Perforce client to "allwrite". Then Perforce would leave all files writeable.

    You might also skip the perforce folder entirely. Set your Perforce client to sync all files directly into /git/testProject (folder B). Then you can Reconcile Offline Work directly from your git folder. Be careful to git commit or at least git stash before p4 sync: you probably don't want to clobber new work.

    # Save current work
    git commit -a -m "saving work"
    # pull from perforce
    git checkout [-b] perforce
    p4 sync
    git commit -a -m "stuff from p4"
    # merge into your work
    git checkout master
    git merge perforce
    # push to perforce
    p4 "Reconcile Offline Work"
    p4 submit

    (Full disclosure: I work for Perforce.)

    ReplyDelete
  2. Thanks for your comment :). I didn't expect to have a better approach from a perforce employee. I'll try your suggestions.

    One more question: are you also forced to use perforce inside your company? :D... just kidding.

    ReplyDelete