share
Stack OverflowGit for beginners: The definitive practical guide
[+856] [37] Adam Davis
[2008-11-24 23:50:29]
[ git version-control ]
[ http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide ]

Ok, after seeing this post by PJ Hyett [1], I have decided to skip to the end and go with Git [2].

So what I need is a beginner's practical guide to Git. "Beginner" being defined as someone who knows how to handle their compiler, understands to some level what a Makefile [3] is, and has touched source control without understanding it very well.

"Practical" being defined as this person doesn't want to get into great detail regarding what Git is doing in the background, and doesn't even care (or know) that it's distributed. Your answers might hint at the possibilities, but try to aim for the beginner that wants to keep a 'main' repository on a 'server' which is backed up and secure, and treat their local repository as merely a 'client' resource.

So:

Installation/Setup

Working with the code

Tagging, branching, releases, baselines

Other

Other Git beginner's references

Delving into Git

I will go through the entries from time to time and 'tidy' them up so they have a consistent look/feel and it's easy to scan the list - feel free to follow a simple "header - brief explanation - list of instructions - gotchas and extra info" template. I'll also link to the entries from the bullet list above so it's easy to find them later.

[+118] [2008-11-26 09:26:46] dbr

How do you create a new project/repository?

A git repository is simply a directory containing a special .git directory.

This is different from "centralised" version-control systems (like subversion), where a "repository" is hosted on a remote server, which you checkout into a "working copy" directory. With git, your working copy is the repository.

Simply run git init in the directory which contains the files you wish to track.

For example,

cd ~/code/project001/
git init

This creates a .git (hidden) folder in the current directory.

To make a new project, run git init with an additional argument (the name of the directory to be created):

git init project002

(This is equivalent to: mkdir project002 && cd project002 && git init)

To check if the current current path is within a git repository, simply run git status - if it's not a repository, it will report "fatal: Not a git repository"

You could also list the .git directory, and check it contains files/directories similar to the following:

$ ls .git
HEAD         config       hooks/       objects/
branches/    description  info/        refs/

If for whatever reason you wish to "de-git" a repository (you wish to stop using git to track that project). Simply remove the .git directory at the base level of the repository.

cd ~/code/project001/
rm -rf .git/

Caution: This will destroy all revision history, all your tags, everything git has done. It will not touch the "current" files (the files you can currently see), but previous changes, deleted files and so on will be unrecoverable!


(3) Git makes its objects read-only, so you'll want rm -rf .git to obliterate git's database. - Josh Lee
Normally a .gitignore file will need to be created during normal usage to specify files/trees to ignore in versioning, so to be complete about the last part on "de-gitting", besides removing .git you would also need to remove the .gitignore file. :) - Monoman
How about bare repositories? They are somehow "centralized", and I think they're a good thing for many projects that need some sort of centralization (eg: projects developed by many people) - peoro
WRT running git status to ensure you're within a repository: this has one gotcha: if you have the environment variable $GIT_DIR set in your current shell, git will ignore your current location and use the repository at $GIT_DIR. I should know, I lost an hour to that yesterday. - sanmiguel
1
[+110] [2008-11-27 11:56:59] dylanfm

GUIs for git


Git GUI

Included with git — Run git gui from the command line, and the Windows msysgit [1] installer adds it to the Start menu.

Git GUI can do a majority of what you'd need to do with git. Including stage changes, configure git and repositories, push changes, create/checkout/delete branches, merge, and many other things.

One of my favourite features is the "stage line" and "stage hunk" shortcuts in the right-click menu, which lets you commit specific parts of a file. You can achieve the same via git add -i, but I find it easier to use.

It isn't the prettiest application, but it works on almost all platforms (being based upon Tcl/Tk)

Screenshots [2] | a screencast [3]


GitK [4]

Also included with git. It is a git history viewer, and lets you visualise a repository's history (including branches, when they are created, and merged). You can view and search commits.

Goes together nicely with git-gui.


Gitnub [5]

Mac OS X application. Mainly an equivalent of git log, but has some integration with github [6] (like the "Network view").

Looks pretty, and fits with Mac OS X. You can search repositories. The biggest critisism of Gitnub is that it shows history in a linear fashion (a single branch at a time) - it doesn't visualise branching and merging, which can be important with git, although this is a planned improvement.

Download links, change log and screenshots [7] | git repository [8]


GitX [9]

Intends to be a "gitk clone for OS X".

It can visualise non-linear branching history, perform commits, view and search commits, and it has some other nice features like being able to "Quicklook" any file in any revision (press space in the file-list view), export any file (via drag and drop).

It is far better integrated into OS X than git-gui/gitk, and is fast and stable even with exceptionally large repositories.

The original git repository pieter [10] has not updated recently (over a year at time of writing). A more actively maintained branch is available at brotherbard/gitx [11] - it adds "sidebar, fetch, pull, push, add remote, merge, cherry-pick, rebase, clone, clone to"

Download [12] | Screenshots [13] | git repository [14] | brotherbard fork [15] | laullon fork [16]


SmartGit [17]

From the homepage:

SmartGit is a front-end for the distributed version control system Git and runs on Windows, Mac OS X and Linux. SmartGit is intended for developers who prefer a graphical user interface over a command line client, to be even more productive with Git — the most powerful DVCS today.

You can download it from their website [18].

Download [19]


TortoiseGit [20]

TortoiseSVN Git version for Windows users.

It is porting TortoiseSVN to TortoiseGit The latest release 1.2.1.0 This release can complete regular task, such commit, show log, diff two version, create branch and tag, Create patch and so on. See ReleaseNotes [21] for detail. Welcome to contribute this project.

Download [22]


QGit [23]

QGit is a git GUI viewer built on Qt/C++.

With qgit you will be able to browse revisions history, view patch content and changed files, graphically following different development branches.

Download [24]


gitg [25]

gitg is a git repository viewer targeting gtk+/GNOME. One of its main objectives is to provide a more unified user experience for git frontends across multiple desktops. It does this not be writing a cross-platform application, but by close collaboration with similar clients for other operating systems (like GitX for OS X).

Features

  • Browse revision history.
  • Handle large repositories (loads linux repository, 17000+ revisions, under 1 second).
  • Commit changes.
  • Stage/unstage individual hunks.
  • Revert changes.
  • Show colorized diff of changes in revisions.
  • Browse tree for a given revision.
  • Export parts of the tree of a given revision.
  • Supply any refspec which a command such as 'git log' can understand to built the history.
  • Show and switch between branches in the history view.

Download: releases [26] or source [27]


Gitbox [28]

Gitbox is a Mac OS X graphical interface for Git version control system. In a single window you see branches, history and working directory status.

Everyday operations are easy: stage and unstage changes with a checkbox. Commit, pull, merge and push with a single click. Double-click a change to show a diff with FileMerge.app.

Download [29]


Gity [30]

The Gity website doesn't have much information, but from the screenshots on there it appears to be a feature rich open source OS X git gui.

Download [31] or source [32]


Meld [33]

Meld is a visual diff and merge tool. You can compare two or three files and edit them in place (diffs update dynamically). You can compare two or three folders and launch file comparisons. You can browse and view a working copy from popular version control systems such such as CVS, Subversion, Bazaar-ng and Mercurial [and Git].

Downloads [34]


Katana [35]

A Git GUIfor OSX by Steve Dekorte.

At a glance, see which remote branches have changes to pull and local repos have changes to push. The git ops of add, commit, push, pull, tag and reset are supported as well as visual diffs and visual browsing of project hieracy that highlights local changes and additions.

Free for 1 repository, $25 for more.

Download [36]


Sprout (formerly GitMac) [37]

Focuses on making Git easy to use. Features a native Cocoa (mac-like) UI, fast repository browsing, cloning, push/pull, branching/merging, visual diff, remote branches, easy access to the Terminal, and more.

By making the most commonly used Git actions intuitive and easy to perform, Sprout (formerly GitMac) makes Git user-friendly. Compatible with most Git workflows, Sprout is great for designers and developers, team collaboration and advanced and novice users alike.

Download [38] | Website [39]


Tower [40]

A feature-rich Git GUI for Mac OSX. 30-day free trial, $59USD for a single-user license.

Download [41] | Website [42]


EGit [43]

EGit is an Eclipse Team provider for the Git version control system. Git is a distributed SCM, which means every developer has a full copy of all history of every revision of the code, making queries against the history very fast and versatile.

The EGit project is implementing Eclipse tooling on top of the JGit Java implementation of Git.

Download [44] | Website [45]


Git Extensions [46]

Open Source for Windows - installs everything you need to work with Git in a single package, easy to use.

Git Extensions is a toolkit to make working with Git on Windows more intuitive. The shell extension will intergrate in Windows Explorer and presents a context menu on files and directories. There is also a Visual Studio plugin to use git from Visual Studio.

Download [47]

Big thanks to dbr [48] for elaborating on the git gui stuff.


SourceTree [49]

SourceTree is a free Mac client for Git, Mercurial and SVN. Built by Atlassian, the folks behind BitBucket, it seems to work equally well with any VC system, which allows you to master a single tool for use with all of your projects, however they're version-controlled. Feature-packed, and FREE.

Expert-Ready & Feature-packed for both novice and advanced users:

Review outgoing and incoming changesets. Cherry-pick between branches. Patch handling, rebase, stash / shelve and much more.

Download [50] | Website [51]


[1] http://code.google.com/p/msysgit/
[2] http://www.spearce.org/2007/01/git-gui-screenshots.html
[3] http://www.simplicidade.org/notes/archives/2008/10/gitgui_screenca.html
[4] http://www.kernel.org/pub/software/scm/git/docs/gitk.html
[5] http://github.com/Caged/gitnub/wikis
[6] http://github.com/Caged/gitnub/tree/master
[7] http://github.com/Caged/gitnub/wikis
[8] http://github.com/Caged/gitnub/tree/master
[9] http://gitx.frim.nl/
[10] https://github.com/pieter
[11] https://github.com/brotherbard/gitx
[12] http://gitx.frim.nl/index.html
[13] http://gitx.frim.nl/seeit.html
[14] http://github.com/pieter/gitx/tree/master
[15] https://github.com/brotherbard/gitx
[16] http://gitx.laullon.com/
[17] http://www.syntevo.com/smartgit/index.html
[18] http://www.syntevo.com/smartgit/index.html
[19] http://www.syntevo.com/smartgit/early-access.html
[20] http://code.google.com/p/tortoisegit/
[21] http://code.google.com/p/tortoisegit/wiki/ReleaseNotes
[22] http://code.google.com/p/tortoisegit/downloads/list
[23] http://digilander.libero.it/mcostalba/
[24] http://digilander.libero.it/mcostalba/#Download
[25] http://trac.novowork.com/gitg/
[26] http://trac.novowork.com/gitg/wiki/Releases
[27] http://trac.novowork.com/gitg/wiki/WikiStart#Source
[28] http://gitbox.pierlis.com/
[29] http://gitbox.pierlis.com/
[30] http://macendeavor.com/gity
[31] http://macendeavor.com/gity/download/
[32] http://github.com/beheadedmyway/gity
[33] http://meld.sourceforge.net/
[34] http://ftp.gnome.org/pub/gnome/sources/meld/
[35] http://dekorte.com/projects/shareware/Katana
[36] http://dekorte.com/projects/shareware/Katana
[37] http://www.sproutmacapp.com/sprout
[38] http://www.sproutmacapp.com/sprout
[39] http://www.sproutmacapp.com/sprout
[40] http://www.git-tower.com/
[41] http://www.git-tower.com/download
[42] http://www.git-tower.com/
[43] http://eclipse.org/egit/
[44] http://eclipse.org/egit/download/
[45] http://eclipse.org/egit/
[46] http://code.google.com/p/gitextensions/
[47] http://code.google.com/p/gitextensions/downloads/list
[48] http://stackoverflow.com/users/745/dbrBlockquote
[49] http://www.sourcetreeapp.com/
[50] http://www.sourcetreeapp.com/download/
[51] http://www.sourcetreeapp.com/

(2) You have some good answers (especially gitcasts, and the push/pull answer), but could I recommend splitting it into a separate answers? The question'er requested that you "don't try to jam a bunch of information into one answer"! - dbr
Thanks for elaborating and formatting it much nicer dbr. I'll split the GUIs into a separate answer. - dylanfm
(1) Hope I didn't stuff up hyperlinks. I think they're fine. - dylanfm
No problem! and all the links seem fine - dbr
(2) Also SmartGit is maturing nicely now syntevo.com/smartgit - Steve Folly
(3) Maybe you should add TortoiseGit code.google.com/p/tortoisegit to your list, for Windows gitters... - kret
+1 for git gui stage line - Ikke
you can thank dbr for that bit :) - dylanfm
(1) What about qgit? - tstenner
Cheers tstenner, just added QGit. - dylanfm
(1) Can you please add gitg. gitg is a git repository viewer targeting gtk+/GNOME. It looks a lot like GitX. Much more eye-friendly than gitk. trac.novowork.com/gitg - Benjamin Cremer
Just added gitg Benjamin. Cheers. - dylanfm
(1) Gity (macendeavor.com/gity) is an option, but is still in development (OS X) - Dave DeLong
(1) Meld: blog.sarathonline.com/2009/02/… - Tarnay Kálmán
(2) Tower ("The most powerful Git client for Mac") is a beautiful new client for Git. - rubiii
(1) EGit extension for Eclipse - grep
2
[+59] [2008-11-25 00:49:37] Pat Notz

Well, despite the fact that you asked that we not "simply" link to other resources, it's pretty foolish when there already exists a community grown (and growing) resource that's really quite good: the Git Community Book [1]. Seriously, this 20+ questions in a question is going to be anything but concise and consistent. The Git Community Book is available as both HTML and PDF and answers many of your questions with clear, well formatted and peer reviewed answers and in a format that allows you to jump straight to your problem at hand.

Alas, if my post really upsets you then I'll delete it. Just say so.

[1] http://book.git-scm.com/

No, don't delete your post - it's a valid question. I qrote a much longer question giving reasons for 'yet another git resource' but cut it back. Main reason being that other helps try to teach you DVCS theory, and jump in the deep end. I want something concise, simplistic, and easy to get here. - Adam Davis
A couple of people have favorite'd it, so it looks like people would like to see a reference here. These references you link to should make it easy for others to fill in the details... - Adam Davis
(2) If you're not using git because it's a DVCS, why bother using git at all? This question is silly and diverts resources that could be spent on other things to satisfy a questionable goal. - Randal Schwartz
3
[+56] [2008-11-25 01:04:13] Brian Gianforcaro

How to configure it to ignore files:

The ability to have git ignore files you don't wish it to track is very useful.

To ignore a file or set of files you supply a pattern. The pattern syntax for git is fairly simple, but powerful. It is applicable to all three of the different files I will mention bellow.

  • A blank line ignores no files, it is generally used as a separator.
  • Lines staring with # serve as comments.
  • The ! prefix is optional and will negate the pattern. Any negated pattern that matches will override lower precedence patterns.
  • Supports advanced expressions and wild cards
    • Ex: The pattern: *.[oa] will ignore all files in the repository ending in .o or .a (object and archive files)
  • If a pattern has a directory ending with a slash git will only match this directory and paths underneath it. This excludes regular files and symbolic links from the match.
  • A leading slash will match all files in that path name.
    • Ex: The pattern /*.c will match the file foo.c but not bar/awesome.c

Great Example from the gitignore(5) [1] man page:

$ git status
[...]
# Untracked files:
[...]
#       Documentation/foo.html
#       Documentation/gitignore.html
#       file.o
#       lib.a
#       src/internal.o
[...]
$ cat .git/info/exclude
  # ignore objects and archives, anywhere in the tree.
  *.[oa]
$ cat Documentation/.gitignore
# ignore generated html files,
*.html
# except foo.html which is maintained by hand
!foo.html
$ git status
[...]
# Untracked files:
[...]
#       Documentation/foo.html
[...]


Generally there are three different ways to ignore untracked files.

1) Ignore for all users of the repository:

Add a file named .gitignore to the root of your working copy.

Edit .gitignore to match your preferences for which files should/shouldn't be ignored.

git add .gitignore

and commit when you're done.

2) Ignore for only your copy of the repository:

Add/Edit the file $GIT_DIR/info/exclude in your working copy, with your preferred patterns.

Ex: My working copy is ~/src/project1 so I would edit ~/src/project1/.git/info/exclude

You're done!

3) Ignore in all situations, on your system:

Global ignore patterns for your system can go in a file named what ever you wish.

Mine personally is called ~/.gitglobalignore

I can then let git know of this file by editing my ~/.gitconfig file with the following line:

core.excludesfile = ~/.gitglobalignore

You're done!

I find the gitignore [2] man page to be the best resource for more information.

[1] http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
[2] http://www.kernel.org/pub/software/scm/git/docs/gitignore.html

I am keen on saying that *~ should ignore backups. - Masi
Could somebody, please, add one minor but important detail to this post? This works only for files already not tracked by git. To 'untrack' file but leave it in filesystem, you need 'git rm --cached filename'. Thanks! - Nikita Rybak
I just want to note that adding the core.excludesfile line didn't work for me. I had to [git config --global core.excludesfile ~/.gitglobalignore] to make it work. - Coding District
There's now a project on Github called gitignore that has gitignore files for a variety of languages and development environments: github.com/github/gitignore - Kyralessa
4
[+47] [2008-11-27 04:58:56] dbr

How do you 'tag' a particular set of revisions

How do you 'mark' 'tag' or 'release' a particular set of revisions for a particular set of files so you can always pull that one later?

Using the git tag command.

To simply "tag" the current revision, you would just run..

git tag -a thetagname
git tag -a 0.1
git tag -a 2.6.1-rc1 -m 'Released on 01/02/03'

To list the current tags, simply run git tag with no arguments, or -l (lower case L):

$ git tag -a thetagname # and enter a message, or use -m 'My tag annotation'
$ git tag -l
thetagname

To delete a tag, you use the -d flag:

$ git tag -d thetagname 
Deleted tag 'thetagname'
$ git tag
[no output]

To tag a specific (previous) commit, you simply do..

git tag [tag name] [revision SHA1 hash]

For example:

git tag 1.1.1 81b15a68c6c3e71f72e766931df4e6499990385b


Note: by default, git creates a "lightweight" tag (basically a reference to a specific revision). The "right" way is to use the -a flag. This will launch your editor asking for a tag message (identical to asking for a commit message, you can also use the -m flag to supply the tag message on the command line). Using an annotated tag creates an object with its own ID, date, tagger (author), and optionally a GPG signature (using the -s tag). For further information on this, see this post [1]

git tag mytagwithmsg -a -m 'This is a tag, with message'

And to list the tags with annotations, use the -n1 flag to show 1 line of each tag message (-n245 to show the first 245 lines of each annotation, and so on):

$ git tag -l -n1
mytagwithmsg    This is a tag, with message

For more information, see the git-tag(1) Manual Page [2]

[1] http://www.rockstarprogrammer.org/post/2008/oct/16/git-tag-does-wrong-thing-default/
[2] http://www.kernel.org/pub/software/scm/git/docs/git-tag.html

git tag does not create tags by default, just lightweight references. You must use either -a or -s to create a tag object (which things like describe will use): rockstarprogrammer.org/post/2008/oct/16/… - Dustin
Ah, interesting. Thanks, I've updated the answer to reflect this - dbr
And how do you tag a previously committed revision? (sorry it's too long so I skimmed through, did I miss something?) - hasenj
hasen j: Added info to answer, basically git tag tagname revision_SHA1 - dbr
(1) To push tags into the remote repo, add --tags when using git push (info from github help area). - Hector Ramos
5
[+46] [2011-05-11 18:06:43] ashwoods

Workflow example with GIT.

Git is extremely flexible and adapts good to any workflow, but not enforcing a particular workflow might have the negative effect of making it hard to understand what you can do with git beyond the linear "backup" workflow, and how useful branching can be for example.

This blog post [1] explains nicely a very simple but effective workflow that is really easy to setup using git.

quoting from the blog post: We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state:

The workflow has become popular enough to have made a project that implements this workflow: git-flow [2]

Nice illustration of a simple workflow, where you make all your changes in develop, and only push to master when the code is in a production state:

simple workflow

Now let's say you want to work on a new feature, or on refactoring a module. You could create a new branch, what we could call a "feature" branch, something that will take some time and might break some code. Once your feature is "stable enough" and want to move it "closer" to production, you merge your feature branch into develop. When all the bugs are sorted out after the merge and your code passes all tests rock solid, you push your changes into master.

During all this process, you find a terrible security bug, that has to be fixed right away. You could have a branch called hotfixes, that make changes that are pushed quicker back into production than the normal "develop" branch.

Here you have an illustration of how this feature/hotfix/develop/production workflow might look like (well explained in the blog post, and I repeat, the blog post explains the whole process in a lot more detail and a lot better than I do.

Git workflow example

[1] http://nvie.com/posts/a-successful-git-branching-model/
[2] https://github.com/nvie/gitflow

I am a git newbie, and this diagram makes it more confusing for me. - finnw
Which one, the first one, or the last one? I didn't really want to make the post too long, but I'll add a small explanation of both diagrams later. - ashwoods
The second one. - finnw
Read the full article. I got confused by this diagram as well, but the blog post is very well written nvie.com/posts/a-successful-git-branching-model - Felipe Sabino
is it better now? i only wanted to qive a rough overview, not repost the whole blog post here :) - ashwoods
6
[+39] [2010-04-20 20:02:59] Adam Davis

Here's a copy of PJ Hyett's post, as it is not available anymore:

Git Isn't Hard

Nov 23, 2008

When we tell people why they should use Git over Subversion, the go-to line is, “Git does Subversion better than Subversion, but it does a lot more than that.”

The “lot more” is comprised of a bunch of stuff that makes Git really shine, but it can be pretty overwhelming for those coming from other SCM’s like Subversion.

That said, there’s nothing stopping you from using Git just like you use Subversion while you’re making the transition.

Assuming you’ve installed the necessary software and have a remote repository somewhere, this is how you would grab the code and push your changes back with Subversion:

$ svn checkout svn://foo.googlecode.com/svn/trunk foo
# make your changes
$ svn commit -m "my first commit"

And how would you do it in Git:

$ git clone git@github.com:pjhyett/foo.git
# make your changes
$ git commit -a -m "my first commit"
$ git push

One more command to make it happen in Git. That extra command has large implications, but for the purposes of this post, that’s all we’re talking about, one extra command.

See, it really isn’t that hard.

Update: I’d be remiss to not also mention that the equivalent of updating your local copy in Subversion compared to Git is svn update and git pull, respectively. Only one command in both cases.


(3) Original link was pjhyett.com/posts/234-git-isn-t-hard - Adam Davis
In the first example I see you are checking out to a relative path ./foo but there is not path specified for the get clone though, where are you checking out to? - JD Isaacks
7
[+33] [2008-11-27 13:25:31] dbr

How to install Git

On Windows:

Install msysgit [1]

There are several downloads:

  • Git: Use this unless you specifically need one of the other options below.
  • PortableGit: Use this if you want to run Git on a PC without installing on that PC (e.g. running Git from a USB drive)
  • msysGit: Use this if you want to develop Git itself. If you just want to use Git for your source code, but don't want to edit Git's source code, you don't need this.

This also installs a Cygwin bash shell, so you can use the git in a nicer shell (than cmd.exe), and also includes git-gui (accessible via git gui command, or the Start > All Programs > Git menu)

Mac OS X

Use the git-osx-installer [2], or you can also install from source

Via a package manager

Install git using your native package manager. For example, on Debian (or Ubuntu):

apt-get install git-core

Or on Mac OS X, via MacPorts [3]:

sudo port install git-core+bash_completion+doc

…or fink:

fink install git

…or Homebrew [4]:

brew install git

On Red Hat based distributions, such as Fedora:

yum install git

In Cygwin the Git package can be found under the "devel" section

From source (Mac OS X/Linux/BSD/etc.)

In Mac OS X, if you have the Developer Tools installed, you can compile Git from source very easily. Download the latest version of Git as a .tar.bz or .tar.gz from http://git-scm.com/, and extract it (double click in Finder)

On Linux/BSD/etc. it should be much the same. For example, in Debian (and Ubuntu), you need to install the build-essential package via apt.

Then in a Terminal, cd to where you extracted the files (Running cd ~/Downloads/git*/ should work), and then run..

./configure && make && sudo make install

This will install Git into the default place (/usr/local - so git will be in /usr/local/bin/git)

It will prompt you to enter your password (for sudo), this is so it can write to the /usr/local/ directory, which can only be accessed by the "root" user so sudo is required!

If you with to install it somewhere separate (so Git's files aren't mixed in with other tools), use --prefix with the configure command:

./configure --prefix=/usr/local/gitpath
make
sudo make install

This will install the git binary into /usr/local/bin/gitpath/bin/git - so you don't have to type that every time you, you should add into your $PATH by adding the following line into your ~/.profile:

export PATH="${PATH}:/usr/local/bin/gitpath/bin/"

If you do not have sudo access, you can use --prefix=/Users/myusername/bin and install into your home directory. Remember to add ~/bin/ to $PATH

The script x-git-update-to-latest-version [5] automates a lot of this:

This script updates my local clone of the git repo (localy at ~/work/track/git), and then configures, installs (at /usr/local/git-git describe) and updates the /usr/local/git symlink.

This way, I can have /usr/local/git/bin in my PATH and I'm always using the latest version.

The latest version of this script also installs the man pages. You need to tweak your MANPATH to include the /usr/local/git/share/man directory.

[1] http://code.google.com/p/msysgit/
[2] http://code.google.com/p/git-osx-installer/
[3] http://www.macports.org/
[4] http://github.com/mxcl/homebrew
[5] http://www.simplicidade.org/notes/archives/2008/09/updated_xgitupd.html

(5) On Fedora: yum install git. For the GUI run yum install git-gui. - Cristian Ciupitu
(2) On Mac, sudo port install git-core+bash_completion+doc - Singletoned
I downloaded fink for mac, but running fink install git gives me error: "Failed: no package found for specification 'git'!" - quano
@quano It should be there, pdb.finkproject.org/pdb/package.php/git - check Fink is properly updated - I think running fink self-update should help - dbr
8
[+32] [2008-11-27 14:25:15] Dean Rather

Git Reset

Say you make a pull, merge it into your code, and decide you don't like it. Use git-log, or tig, and find the hash of wherever you want to go back to (probably your last commit before the pull/merge) copy the hash, and do:

# Revert to a previous commit by hash:
git-reset --hard <hash>

Instead of the hash, you can use HEAD^ as a shortcut for the previous commit.

# Revert to previous commit:
git-reset --hard HEAD^

(4) This is the analog to a revert in most other centralized version control systems. - Jeremy Wall
"$ git-reset --hard HEAD^" should be shorthand for the parent of head (i.e. the previous state before last commit). - Ben Page
(6) just a plain old git reset should unstage accidental git add - slf
9
[+31] [2010-06-03 08:43:19] Asgeir S. Nilsen

How do you set up a shared team repository?

How to set up a normal repository is described here [1] -- but how do you set up a team repository that everybody can pull and push from and to?

Using a shared NFS file system

Assuming your team already has for instance a shared group membership that can be used.

mkdir /your/share/folder/project.git
cd /your/share/folder/project.git
newgrp yourteamgroup # if necessary
git init --bare --shared

To start using this repository the easiest thing to do is start from a local repository you already have been using:

cd your/local/workspace/project
git remote add origin /your/share/folder/project.git
git push origin master

Others can now clone this and start working:

cd your/local/workspace
git clone /your/share/folder/project.git

Using SSH

Set up a user account on the target server. Whether you use an account with no password, an account with a password, or use authorized_keys really depend on your required level of security. Take a look at Configuring Git over SSH [2] for some more information.

If all developers use the same account for accessing this shared repository, you do not need to use the --shared option as above.

After initing the repository in the same way as above, you do the initial push like this:

cd your/local/workspace/project
git remote add origin user@server:/path/to/project.git
git push origin master

See the similarity with the above? The only thing that might happen in addition is SSH asking for a password if the account has a password. If you get this prompt on an account without a password the SSH server probably has disabled PermitEmptyPasswords.

Cloning now looks like this:

cd your/local/workspace
git clone user@server:/path/to/project.git
[1] http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide/320140#320140
[2] http://stackoverflow.com/questions/1595848/configuring-git-over-ssh

besides NFS - how do you set up git server to work over ssh? - Like a tiny-scale instance of github.com? - daf
Is it necessary to have a group sticky bit set on the relevant directories, or does git take care of all that? If the latter, how does git know what group to use on the permissions for the Unix files? - Norman Ramsey
I've added a section on SSH as requested. The sticky bit is needed if not all developers have the shared group as their primary group. If any of the users have a different primary group they would by default create files with this group ownership. This happens below git and is thus not always within git's control. - Asgeir S. Nilsen
what git repo-config core.sharedRepository group is useful for? - systempuntoout
10
[+28] [2008-11-26 01:20:06] Peter Burns

git status is your friend, use it often. Good for answering questions like:

  • What did that command just do?
  • What branch am I on?
  • What changes am I about to commit, and have I forgotten anything?
  • Was I in the middle of something last time I worked on this project (days, weeks, or perhaps months ago)?

Unlike, say svn status, git status runs nigh-instantly even on large projects. I often found it reassuring while learning git to use it frequently, to make sure my mental model of what was going on was accurate. Now I mostly just use it to remind myself what I've changed since my last commit.

Obviously, it's much more useful if your .gitignore is sanely configured. [1]

[1] #316062

11
[+27] [2008-11-25 01:01:00] Adam Davis

Commit Changes

Once you've edited a file, you need to commit your changes to git. When you execute this command it will ask for a commit message - which is just a simple bit of text that tells everyone what you've changed.

$ git commit source/main.c

Will commit the file main.c in the directory ./source/

$ git commit -a # the -a flag pulls in all modified files

will commit all changed files (but not new files, those need to be added to the index with git-add). If you want to commit only certain files then you will need to stage them first with git-add and then commit without the -a flag.

Commiting only changes your local repository though not the remote repositories. If you want to send the commits to the remote repository then you will need to do a push.

$ git push <remote> <branch> # push new commits to the <branch> on the <remote> repository

For someone coming from CVS or SVN this is a change since the commit to the central repository now requires two steps.


12
[+27] [2009-05-03 08:56:11] Markus Dulghier

How do you branch?

The default branch in a git repository is called master.

To create a new branch use

git branch <branch-name>

To see a list of all branches in the current repository type

git branch

If you want to switch to another branch you can use

git checkout <branch-name>

To create a new branch and switch to it in one step

git checkout -b <branch-name>

To delete a branch, use

git branch -d <branch-name>

To create a branch with the changes from the current branch, do

git stash
git stash branch <branch-name>

(11) you should mention the shortcut git checkout -b <branch-name> which creates a branch and switches to it in one step. It's probably the most common use case for a beginner and even advanced git user. - Jeremy Wall
13
[+21] [2009-08-29 01:33:15] Jeremy Wall

Getting the latest Code

$ git pull <remote> <branch> # fetches the code and merges it into 
                             # your working directory
$ git fetch <remote> <branch> # fetches the code but does not merge
                              # it into your working directory

$ git pull --tag <remote> <branch> # same as above but fetch tags as well
$ git fetch --tag <remote> <branch> # you get the idea

That pretty much covers every case for getting the latest copy of the code from the remote repository.


14
[+20] [2010-07-15 21:00:56] aldux

The Pro Git [1] free book is definitely my favorite, especially for beginners.

[1] http://progit.org

15
[+18] [2008-11-25 01:02:49] Andrew

Git Magic [1] is all you'll ever need. Guaranteed or your money back!

[1] http://www-cs-students.stanford.edu/~blynn/gitmagic/

(14) Sigh, I want my money back. Buggy software (msysGit) with an incomplete tutorial (GitMagic) == hours of work, which is hardly free - SamGoody
/me too... Sucks! - wishi
16
[+16] [2009-05-03 09:08:01] Markus Dulghier

How do you merge branches?

If you want to merge a branch (e.g. master to release), make sure your current branch is the target branch you'd like to merge into (use git branch or git status to see your current branch).

Then use

git merge master

(where master is the name of the branch you want to merge with the current branch).

If there are any conflicts, you can use

git diff

to see pending conflicts you have to resolve.


(1) So how do you resolve conflicts and complete the merge? - Steve Folly
(2) There is git mergetool which does a three-way-diff with your favourite tool (gvimdiff, kdiff3 or some more) - Dave Vogt
17
[+16] [2009-10-31 17:21:09] Jordan

I've also found Git Internals [1] to be very useful. It is written by Scott Chacon (author of Pro Git, and maintainer of the Git Community Book). What I like about Git Internals is it focuses on the concepts first and then the commands [2], and being that it is ~100 small pages it is quickly digestible.

[1] http://peepcode.com/products/git-internals-pdf
[2] http://blog.jordanterrell.com/post/Favor-Concepts-Over-Commands.aspx

18
[+13] [2010-01-22 03:59:11] Pierre-Antoine LaFayette

How do you see the history of revisions to a file?

git log -- filename

Maybe mention --follow? - torek
19
[+12] [2009-10-19 20:02:18] innaM

How to track remote branches

Assuming there is a remote repository that you cloned your local repository from and also assuming that there is a branch named 'some_branch' on that remote repository, here is how to track it locally:

# list remote branches
git branch -r

# start tracking one remote branch
git branch --track some_branch origin/some_branch

# change to the branch locally
git checkout some_branch

# make changes and commit them locally
....

# push your changes to the remote repository:
git push

It seems that in git 1.7 remote branches get automatically tracked when you make a local branch from them. I don't know in which version this behavior started. - Doppelganger
Actually, you can list all remote branches by using git remote show REMOTENAME - Felipe Sabino
20
[+11] [2009-11-19 10:25:40] EricSchaefer

A real good paper for understanding how Git works is The Git Parable [1]. Very recommended!

[1] http://tom.preston-werner.com/2009/05/19/the-git-parable.html

21
[+10] [2009-11-19 11:21:41] kret

How do you compare two revisions of a file, or your current file and a previous revision?

Compare command is git diff.

To compare 2 revisions of a file:

$ git diff <commit1> <commit2> <file_name>

That diffs commit1 against commit2; if you change order then files are diffed the other way round, which may not be what you expect...

To compare current staged file against the repository:

$ git diff --staged <file_name>

To compare current unstaged file against the repository:

$ git diff <file_name>

22
[+9] [2008-11-25 00:52:48] Piotr Lesnicki

Why yet another howto? There are really good ones on the net, like the git guide [1] which is perfect to begin. It has good links including the git book [2] to which one can contribute (hosted on git hub) and which is perfect for this collective task.

On stackoverflow, I would really prefer to see your favorite tricks !

Mine, which I discovered only lately, is git stash, explained here [3], which enables you to save your current job and go to another branch

EDIT: as the previous post, if you really prefer stackoverlow format with posts as a wiki I will delete this answer

[1] http://www.sourcemage.org/Git_Guide
[2] http://book.git-scm.com/
[3] http://book.git-scm.com/4_stashing.html

No, don't delete. Your answer is perfectly valid - and pointing others to good resources isn't a bad thing. I would also like the most common operations listed here, but it's a bit of work and I don't expect others to do it. I'll do it over time as I learn and this'll be a reference for me. - Adam Davis
23
[+9] [2008-11-27 05:23:15] Dean Rather

Console UI - Tig

Installation:

apt-get install tig

Usage

While inside a git repo, type 'tig', to view an interactive log, hit 'enter' on any log to see more information about it. h for help, which lists the basic functionality.

Trivia

"Tig" is "Git" backwards.


Shouldn't it be a "Console UI", since "console" and "graphical" are a bit.. contradictory? - dbr
it's a lot more graphical than git-log... however, it is a lot lot more interfaceable... - Dean Rather
24
[+8] [2009-04-06 03:56:20] hasenj

I got started with the official Git tutorial [1]. I think it's practical enough for beginners (I was, and still am, a beginner, by your definition! I barely grasp makefiles, I've only played a bit with Apache Subversion, etc.).

[1] http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html

25
[+8] [2009-10-19 20:05:56] innaM

How can I create a branch on a remote repository?

Assuming that you have cloned your remote repository from some single remote repository.

# create a new branch locally
git branch name_of_branch
git checkout name_of_branch
# edit/add/remove files    
# ... 
# Commit your changes locally
git add fileName
git commit -m Message
# push changes and new branch to remote repository:
git push origin name_of_branch:name_of_branch

(11) why name_of_branch:name_of_branch ? - Seun Osewa
Yes, why? As far as I know you only need git push origin name_of_branch and the branch will already be created in your remote - Felipe Sabino
the first name_of_branch is the local name, the second is the (desired) remote branch name, so it could be local_name_of_branch:remote_name_of_branch if you want the names to differ. If you want them the same, you still have to specify it like this b/c git doesn't make the assumption that you want the name to be the same unless you tell it so (there are other methods to do so as well, however) - johnny
26
[+8] [2011-05-12 11:58:27] Felipe Sabino

How do I delete a branch on a remote repository?

Perform a push in your remote using : before the name of the branch

git push origin :mybranchname

being origin the name of your remote and mybranchname the name of the branch about to be deleted

http://help.github.com/remotes/


27
[+7] [2008-11-27 13:21:13] dylanfm

Push and pull changes

In an simplified way, just do git push and git pull. Changes are merged and if there's a conflict git will let you know and you can resolve it manually.

When you first push to a remote repository you need to do a git push origin master (master being the master branch). From then on you just do the git push.

Push tags with git push --tags.


28
[+7] [2008-11-27 14:27:51] Dean Rather

Checking Out Code

First go to an empty dir, use "git init" to make it a repository, then clone the remote repo into your own.

git clone user@host.com:/dir/to/repo

Wherever you initially clone from is where "git pull" will pull from by default.


(7) I think clone does the init step for you removing the need to run init first. git init is really mostly for creating the first repository or for special configurations with multiple remotes that you want to set up different than a standard clone. - Jeremy Wall
29
[+7] [2010-03-27 23:18:01] gngrwzrd
File not found. - ripper234
30
[+5] [2008-11-27 13:14:18] dylanfm

Resource: Definitely check out Scott Chacon's Gitcasts [1], especially the Railsconf talk [2].

Github [3] is awesome and also has some helpful guides [4].

[1] http://www.gitcasts.com/
[2] http://www.gitcasts.com/posts/railsconf-git-talk
[3] https://github.com/
[4] http://github.com/guides/home

31
[+5] [2009-03-13 18:58:26] none

WRT good GUIs/frontends, you may also want to check out qgit [1] which is a cross-platform (Linux/Win32) repository viewer for Git and can be also used as high level frontend for the most common Git operations, in fact it can be easily enhanced by so called "custom actions" so that users can provide customized actions.

[1] http://sourceforge.net/projects/qgit

32
[+5] [2009-10-16 06:20:42] Jake

Seriously add the link featured in Tim's answer [1] in the Stack Overflow post Setup Git Server with Msysgit on Windows [2].

It flawlessly told me how to setup Git on Windows with msysgit [3], and is an incredibly detailed article.

[1] http://stackoverflow.com/questions/1482824/setup-git-server-with-msysgit-on-windows/1503986#1503986
[2] http://stackoverflow.com/questions/1482824/setup-git-server-with-msysgit-on-windows
[3] http://code.google.com/p/msysgit/

Thanks, I added it. - Adam Davis
33
[+5] [2011-05-12 22:09:50] Felipe Sabino

What is rebasing?

Rebase explanation taken from the book Pragmatic Guide to Git - Travis Swicegood [1]

Chapter III

16 . Rewriting History by Rebasing

Rebasing commits is the one concept in Git that has no counterpart inside the traditional version control world. Using git rebase, you can rewrite the history of a repository in a variety of ways. It is one of the most powerful commands in Git, which makes it one of the most dangerous.

rebase takes a series of commits (normally a branch) and replays them on top of another commit (normally the last commit in another branch). The parent commit changes so all the commit IDs are recalculated. This can cause problems for other developers who have your code because the IDs don’t match up.

There’s a simple rule of thumb with git rebase: use it as much as you want on local commits. Once you’ve shared changes with another developer, the headache is generally not worth the trouble.

[1] http://rads.stackoverflow.com/amzn/click/1934356727

(1) Worth mentioning: if a rebase hits a merge conflict and you want to stop the rebase, use git rebase --abort. Everything will be back to the way it was before you started. And: Don't know if you want to mention this here (it seems less beginner-y), but you can also rebase --onto. - torek
I think one extremely important aspect, which isn't mentioned here, is how rebase reorders history. Rebase orders history so the commits are stored clean and linear instead of interleaving from merge conflict resolutions during fetch/merge operations. Rebase also extracts your changes from origin and applies remote changes first, so you only have to resolve conflicts in reference to your changes, not the incoming changes. - Jason Huntley
34
[+4] [2009-05-21 00:50:09] tundal45

I found this post [1] to be very useful to get me started. I still need to read the book and other resources but the post was helpful in, as the title says, "understanding git conceptually". I also recommend taking the Git & GitHub course offered at RubyLearning [2].

[1] http://www.eecs.harvard.edu/~cduan/technical/git/
[2] http://www.rubylearning.org

(1) Not really the goal of the posters question since he wants this question to work as a one stop shop for new git users. - Jeremy Wall
35
[+4] [2012-03-23 07:59:26] torek

One more item I really think should be in this list, probably very useful for beginners:

Don't Panic

What if I've done some commits and then I did something scary, like maybe a rebase, and now something—or even everything—seems to be lost? (Rebase seems to be the one that gets most people the first time, so I'm concentrating on it. While git rebase --abort helps a lot, sometimes you'll find that you botched an edit during an interactive rebase, for instance, and let the rebase finish and now you want to get your old stuff back. And then there are things like filter-branch...)

One key git principle is that it never actually deletes anything you've committed. ("What, never?" "No, never!" "What, never?" "Well, hardly ever!") If you have not run git gc, it's still in there. It may take some digging around to find your previous work, but if you did some successful git commits earlier, then, for instance, even your apparently-wrecked series of commits from a tragic rebase error are still in there, normally for at least a month (technically, until the "reflogs" expire).

It's important to keep in mind that each branch name labels—or points to—a "commit-ID". These are the the funny numbers like 7cc5272. Many of the things you do, like adding a new commit to a branch, make the branch name point to a new, different commit-ID. Each commit-ID has a link pointing back to some previous commit-ID(s), and this is what actually makes up a "branch" full of commits.

The rebase entry talks about "rewriting history," and commands like git filter-branch also "rewrite history," but they do it not by destroying the previous history, but rather by adding new history. Once the new history is in place, git will "move the labels around" so that it looks like history has changed. If you are on your fix-nasty-bug branch and do a git rebase and manage to wreck things, the label fix-nasty-bug now refers to the wreckage, but the original versions are still there. Rebase in particular makes a temporary (non-moving, not-a-branch) label spelled ORIG_HEAD that lets you find them. The filter-branch command saves all the original names as well. In some cases, there may be no obvious name, but the commits can always be found. If necessary, find yourself a "git guru" and explain what you did that led to the wreckage.

(The command git reflog show can also help with finding commit-IDs.)

If you have found what you think is some or all of your previous work, try:

git log <commit-ID>   # ORIG_HEAD after a bad rebase, for instance
git show <commit-ID>  # or some long SHA1 value you can still see in a window

If it looks right or useful, put a name to it:

git branch recover-my-stuff ORIG_HEAD

and it's all back again! In fact, now both your bad rebase and your original work are in your git repo "forever" (or at least, until you delete the branch names and let a few months go by, and then they get garbage-collected). You can put as many names to as many recovered commits as you like. (Branch names are virtually free, except for cluttering up your git branch output, and of course they also keep commits from being garbage-collected. You can also, or instead, put tags on specific commit-IDs, if you prefer those.)


36
[0] [2012-05-10 08:47:01] rdamborsky

Very good post on merging with conflicts - GitGuys: Merging With a Conflict - Conflicts And Resolutions [1]

The blog is really great - illustrative, clean examples and understandable. Definitely worth checking out.

[1] http://www.gitguys.com/topics/merging-with-a-conflict-conflicts-and-resolutions/

37