Git is a free and open source, distributed version control system designed to handle everything from small to very large projects with speed and efficiency. HFC has standardized on Git as a method of source control for web management.

Note: This post is an adaptation of internal instructions I've written for the web team at Henry Ford College. I'm reposting it here, because I have too many times when I want to send it to people, and this is the easiest way to do that. It's highly unoriginal, mostly culled from the sources listed at the end. I've removed all of the internal HFC links I could find . Also, this post was never finished from its original writing back in 2010, hence the TODO section at the end.

Installation and Setup

To install on Windows, see the Git home page.

Now you need to set up some basic info:

git config --global user.name "Your Name"
git config --global user.email you@domain.com

You can also set your default editor (used for things like commit messages and interactive rebase) and set some nice color options.

git config --global color.status auto
git config --global color.branch auto
git config --global color.interactive auto
git config --global color.diff auto
git config --global core.autocrlf false
git config --global core.safecrlf false
git config --global core.ignorecase false
git config --global core.whitespace "fix,blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2"
git config --global diff.colorMoved zebra
git config --global diff.renames copies
git config --global fetch.prune true
git config --global alias.st status
git config --global alias.rso "remote show origin"
git config --global alias.df '!git diff --no-prefix && git diff --staged --no-prefix'
git config --global alias.ds "diff --staged"
git config --global alias.ss "submodule status"
git config --global alias.sup "submodule update"
git config --global alias.wa "log --pretty=format:'* %s ' --reverse --since=yesterday"
git config --global alias.lg "log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %an)%Creset' --abbrev-commit --date=relative"

This last alias -- from soulston on the #drupal-gitsupport IRC channel -- creates an incredibly useful git lg command that creates a color-coded one-line log that shows the relationships between all local and remote branches known to the current log history.

Setting up a simple repository

It is insanely easy to turn any subdirectory into a managed Git repository. Simply get to a prompt in the desired folder and run the following commands:

git init
(add some files)
git add .
git commit -m 'Initial commit'

To ignore files, create a .gitignore file in your directory:

cat .gitignore
tmp/*
*~

Now you can make changes to the files and pack them up for changes. There are shortcuts, but it's probably best to break this up into multiple commands until your more comfortable with the process. First you can check to see what was changed:

git status

(Hint: using the aliases created above, this can be abbreviated as git st)

Next, flag any files that were changed for addition.

git add path/to/changed_file_name

Now commit the changes.

git commit -m 'Summary of your changes.'

To see a log of your changes:

git log

Check out Git for the lazy for more details about these commands.

This is great for managing changes in standalone systems, but what about sharing changes across systems?

Best Practices for commit messages

This section is based on Commit messages - providing history and credit from Drupal.org.

Use this syntax for commit messages:

Issue #[issue number] by [comma-separated usernames]: [Short summary of the change].

For example:

Issue #331 by micah: Updated Computer Literacy page with new information.

or (on Drupal.org):

Issue #52287 by sun, Dries: Fixed outdated commit message standards.

In scenarios where there are no issue numbers (like the /etc directory on the dhcpd server) simply use attribution and summary.

by micah, joe: Removed Mac Server from VLAN 11.

Note that the summary generally begins with a past tense verb. This makes the commit log very readable.

Shared repositories on Bitbucket

Git repositories can be moved across the network over ssh (among other means). At HFC, we use Bitbucket.org to house code repositories. In order to use this, you'll need to create an account on Bitbucket, then configure an ssh private/public keypair and add your public key to your account via the website..

ssh-keygen -o -a 100 -t ed25519 -C  'yourname'

This will create two files in your ~/.ssh folder: id_rsa (your private key) and id_rsa.pub (your public key). On Windows, see my tutorial on creating keys with puttygen.

Creating the origin repository

Creating a new repository on BitBucket is pretty easy. For team projects, set the owner to the hfccwebdev team. For your own projects, just use your personal account. I've written a separate bulletin on guidelines for team repositories (PDF). Once you've created a new repo, just follow the on-screen directions for connecting to it from an existing local repository or for starting a new project.

(NOTE: you could also do this with accounts on github.com or with project repositories on drupal.org)

Populating the origin repository

Using the URL for the new repository you created on BitBucket, connect the remote and push your current branch.

git remote add origin git@bitbucket.org:hfccwebdev/MY_NEW_PROJECT.git
git push -u origin master

Updating the origin repository

As you continue to work on a project, changes can also be pushed to the origin master.

git commit -m 'Some new changes.'
git push

Retrieving code from the origin repository

On a third computer, you can now retrieve the contents of MY_NEW_PROJECT from Bitbucket.

git clone git@bitbucket.org:hfccwebdev/MY_NEW_PROJECT.git

Once a repository has been cloned, updates can be pulled from the master at any time.

git pull

Fixing broken remote tracking

If you forget the -u flag during the initial push to the remote, then git won't add automatic tracking for the branch, making it a pain to pull updates later without specifying repository and branch on the command line. Use set-upstream to fix the link:

git branch --set-upstream branchname origin/branchname

(This assumes that the remote is named "origin" and you replace "branchname" appropriately.)

Basic Submodule Support

If you put one git repository inside another, the contents of that repository will be ignored by default. By creating a submodule, git will track a specific commit of the submodule to be part of the main repository, but it will still need to be retrieved and managed separately.

This git submodule tutorial explains it all pretty well, but here's the quick summary of commands:

Creating a submodule

git submodule add [-b branch] source-repo-location path
git commit
git push
git submodule init
git submodule status

Retrieving a submodule

git pull
sit submodule init
git submodule update

Important

When adding the containing subdirectory to the main repo, do not use a trailing slash!

What is missing from this document?

TODO: View what is newer on origin without actually merging it.

hint:

git fetch
git log origin/master

Note: We don't use master branch for Drupal modules, themes or features. Use d.o version branches. See also Git for Drupal best practices.

See also: How I manage Drupal with Git.

TODO: Simply put, these instructions are far too simplified and don't cover everything you need to know for multiple developers committing to the same repository.

Additional Resources