Develop Locally Using Git, Instead of Your Company's Crappy Version Control

At my new company (Ariba), I am forced to use a beastly version control system (Perforce) and it was really cramping my style. I couldn’t easily branch or check in small incremental changes (even locally), so I was going days to weeks without checking in, waiting until my code was production ready. This meant if I made a mistake and had to roll back, or wanted to maintain multiple version of a file, I had to manually maintain version and/or redo/undo work.

This week, I finally had enough, and decided to augment Ariba’s version control system by using Git locally for better control while I developed. The rest of this article describes how to mirror an existing repository with a Git one. We will be building a fictitious repository named example.

How do it…

Create and initialize the remote Git repo

Create the directory:

mkdir -p /pathToDesiredLocation/example.git

Change to that directory:

cd /pathToDesiredLocation/example.git

Initialize the Git repository:

git init --bare

Gitifying your existing version control

When starting a new project, clone the repository and begin coding:

git clone /pathToDesiredLocation/example.git example

Otherwise, if (like me) you are augmenting an existing repository with Git, move to the root of your existing repository or the desired part of the repository that you want to add Git to:

cd /pathToExistingRepoOrPartOfRepo

Activate Git on that directory:

git --init

Connect the remote repository to the local one:

git remote add origin /pathToDesiredLocation/example.git

Add all the existing files to Git and check it in (this may take a few minutes the first time):

git add .
git commit -m "cloning existing repo"
git push origin master

Maintaining your Git repository

Whenever updating the codebase from your company’s version control system, create a new commit with all changes:

# updated local repo from company repository
git add .
git commit -m "syncing to {CompanyRepoSystem} revision {RevisionNum}"
git push origin master

To make finding previous version easier, try tagging the sync commits:

git tag -m "{CompanyRepoSystem} revision {RevisionNum}" {OptionalCodeVersion} {CommitNum}

View existing tags using:

git tag -l -n

Make sure to push the tags to the remote repository:

git push --tags

How it works…

The first group of steps above show how to turn any directory into a Git repository that can be used as the remote for a local git repository. This article puts it on a local disk, but ideally it should be another server. At Ariba I have my remote on a mapped shared drive, in case my hard drive crashes, and so that my coworkers can easily use the remote as well.

The second group of steps show how to initialize your company’s repository (or only part of it) as a Git repository and set the origin to the previously created remote repository. This way, when changes are pushed they live both in the local repository and in the origin repository. If you are not worried about maintaining a remote backup or sharing with peers, then you could get away with only running a local Git repository. I do’t recommend a local only approach, but implementing it would only require the second group of steps and never pushing to the remote.

The last group of steps explains keeping the local Git repository in sync with your company’s version control. Syncing, committing, and pushing is all that needs to be done, but using tagging allows for better tracking of when changes were synced with Git and makes rolling back to previous version easier.

There is not an example of how to check code into your company’s repository, because I do not know your system. However, here are some guidelines that I am using:

  • Do all local development in branches and keep master in sync with your company’s repository to avoid conflicts and make syncing easier.
  • Before checking in, update master to your company’s repository, then merge the development branch and push to your company’s repository system.
  • If your company’s repository requires checkouts, checkout any modified files before merging the development branch.

There’s more…

The solution written here will work for everybody, but requires you to maintain a Git version control that is separate from your company’s version control. For most version control systems (including perforce) somebody has already written a bridge between it and Git. I recommend trying the bridge first, so you have tighter integration, before maintaining two version control systems.

For more Git-related articles, see:

Encrypting Settings Files

When I was developing for Votizen, I always felt uneasy that we had our settings files with many important passwords and auth keys stored unencrypted on a third-party service. Sure, SSL was used for fetching and committing code, and only a few SSH public keys were allowed access to our repository, but it is one more opportunity for your site to be hacked. I recently read John Resig’s post Keeping Passwords in Source ...

Using Git Interactive Rebase With Feature Branches

The next GIT topic to cover is branching and using interactive rebase before merging the branch back into master. This article will cover a workflow strategy where you create a local branch for a new feature where you can make many small commits. Then before merging and committing to master, use interactive rebase to squash some (or all) of the less meaningful commits, keeping the commits to master more concise and feature focused.

Getting ready

...

Git Rebase Versus Git Pull

Before continuing the GIT series, it is worthwhile to tangent a bit and write about using git rebase versus git pull. Using git pull will fetch any changes from the remote branch and merge them on to your local branch, creating a new merge commit. Using git rebase will remove each of your commits temporarily (stored in .git/rebase), update your local branch to match the remote branch, then apply each of your local changes again ...

Amending and Squashing Commits in Git

Have you ever committed code to your Git repository, and then realized that you forgot something or there was an error in your code? Wish there was an easy way to amend your commit with the fix? What about if you've already pushed your code or made several commits? If you run a strong test suite, and commit before running the whole test, this probably happens regularly (at least it does for me). Usually each ...