Skip to content

Instantly share code, notes, and snippets.

@andrewsardone
Created September 9, 2009 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewsardone/183402 to your computer and use it in GitHub Desktop.
Save andrewsardone/183402 to your computer and use it in GitHub Desktop.

Git Resources

This page provides links to documents, how-tos, cheat sheets, tips, and tricks related to learning and using git. (inspired by 37signals’ Git Resources page)

Links

Tips & Tricks

Setup

Set your Git username globally, i.e., what appears in the logs when you make commits:

$ git config --global user.name "Max Power"
$ git config --global user.email "homer.simpson@jstor.org"

Configure colors globally (quite handy):

$ git config --global color.diff auto
$ git config --global color.status auto
$ git config --global color.branch auto
$ git config --global color.interactive auto

Create a global git excludes file:

$ touch ~/.gitexcludes
$ git config --global core.excludesfile ~/.gitexcludes

Example .gitexcludes:

.DS_Store
*~

Creating a remote repository

First, create a bare remote repository on the remote server:

$ sudo -u app mkdir -m 770 /u/git/plugins/plugin_name.git
$ cd /u/git/plugins/plugin_name.git
$ sudo -u app git --bare init --shared=group

On your machine, cd to where your project is, create a new local repository and track the remote repository:

$ cd /path/to/project
$ git init
$ git remote add origin ssh://dev.example.com/u/git/plugins/plugin_name.git

Make a change, add it to the index, and commit it:

$ touch .gitignore
$ git add .
$ git commit -m “Initial commit”

Finally, push to the remote repository:

$ git push --all

Anyone will be able to clone and track the remote repository:

$ git clone ssh://dev.example.com/u/git/plugins/plugin_name.git

Run git merge --no-ff when merging

Scenario

You're on your master branch, the main line of development, and decide to branch off to hack on a feature (git checkout -b feature). After a series of commits you decide the feature is complete and want to merge the changes back into master. Alright, git checkout master; git pull origin master; git merge feature, and all is good, right? Well, if there haven't been any commits to the master branch while you were working on the feature branch, git-merge does not generate a merge commit as the merge resolved as a fast-forward, i.e., git-merge replaces the master branch with a clone of the master branch. Git thinks:

Well, nobody else has worked on the master branch, so I could just make the feature branch become the new master branch and that would be logically equivalent. (via http://robey.lag.net/2008/07/13/git-for-the-real-world.html)

This can be problematic as there's no merge commit, so your commit history never reflects that certain changes were done on the feature branch and then brought in to master. Without that merge commit, removing the changes done within the feature branch requires you addressing multiple commits, as opposed to the single point of merge.

Therefore, when merging two branches, add the --no-ff flag (this should be on by default!) to force a merge commit, and preserve the branching history.

Avoid git rebase and git reset

git rebase erases every local commit and replaces them with patches. When you push to a remote repository, the patches are re-applied one by one and the repository’s history is changed. Instead, do a merge.

git reset erases commits from your local history and will make a future push difficult or impossible.

Both of these commands go back in time and change the past, and violate the core philosophy of DVCS: “Everyone has their own view of the repository, but these views obey entropy and flow in only one time direction.”

via http://robey.lag.net/2008/07/13/git-for-the-real-world.html

Git Commit Message Style

First, it’s a best practice to form your Git commit messages to be no wider than 72 characters. The git log command uses the default pager (less -s) so it’s more comfortable to review log messages without having to worry about long ones flowing off the edge of the screen.

Second, a commit message should include a short, one-line description (acting as the summary) of the change on the first line, with any further descriptions handled in paragraphs below.

A Model Git Commit Message

SHORT (50 CHARS OR LESS) SUMMARY OF CHANGES

MORE DETAILED EXPLANATORY TEXT, IF NECESSARY. WRAP IT TO ABOUT 72 CHARACTERS OR SO. IN SOME CONTEXTS, THE FIRST LINE IS TREATED AS THE SUBJECT OF AN EMAIL AND THE REST OF THE TEXT AS THE BODY. THE BLANK LINE SEPARATING THE SUMMARY FROM THE BODY IS CRITICAL (UNLESS YOU OMIT THE BODY ENTIRELY); TOOLS LIKE REBASE CAN GET CONFUSED IF YOU RUN THE TWO TOGETHER.

FURTHER PARAGRAPHS COME AFTER BLANK LINES.

  • BULLET POINTS ARE OKAY, TOO

  • TYPICALLY A HYPHEN OR ASTERISK IS USED FOR THE BULLET, PRECEDED BY A SINGLE SPACE, WITH BLANK LINES IN BETWEEN, BUT CONVENTIONS VARY HERE

  • USE A HANGING INDENT

This commit style helps conform to standards used by these helpful commands:

  • git log --pretty=online shows a terse history mapping containing the commit id and the summary
  • git shortlog uses summary lines in the changelog like output it produces
  • git format-path, git send mail, and related tools use it as the subject for emails reflogs, a local history accessible with git reflog intended to help you recover from stupid mistakes, get a copy of the summary
  • GitHub uses the summary in various places in their user interface

(For an extended discussion, see http://www.tpope.net/node/106, which the above list and example message were taken from.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment