##The Basics
###Installation
####Windows Users
First off, get msysgit (download here). It is the official Windows Git distribution, and comes with a terminal that has your standard bash commands as well as Git.
If you prefer GUIs, SourceTree is the way to go. This guide is for using Git on the command line, but TortoiseGit has equivalent windows for all commands.
####Mac Users
You can get the Mac installer for Git here.
####Linux Users
Install Git via your standard package manager (apt-get
, yum
, pacman
).
###Basic Setup:
You will want to give Git your name and email - they are used to sign your commits. These commands will do that:
git config --global user.name "John Doe"
git config --global user.email [email protected]
Global Git settings are stored in a .gitconfig
file in your home directory.
Settings can also be set on a repository-specific basis.
See the man page of git config
for a full list of options. Some other useful ones include:
color.ui
- Set this to "auto" in order for Git to provide colored output.core.autocrlf
andcore.safecrlf
- Git can do automatic line-ending conversions to ensure that line endings in files are consistent regardless of which OS each developer is working in.diff.tool
- The commandgit difftool
will use a diff tool to show changes. Use this to set the tool to be used.aliases
- Custom commands can be created (seegit graph
below)
###Cloning a repository:
git clone <repo location> <dir>
will clone a Git repository in a new directory inside your current directory. Leaving out <dir>
will cause it to name the folder after the Git repository. For example,
git clone [email protected]:torvalds/linux.git
clones Github's mirror of the Linux kernel into a directory named "linux".
###Committing files:
Git's commit process involves two steps:
-
Add new files, add changes for existing files (both with
git add <files>
), and/or remove files (withgit rm
). These changes are put in a staging area called the index. -
Call
git commit
to commit the changes.
Git commit will open up a text editor to provide a commit message.
You can set this editor to whatever you want by changing the core.editor
option with git config
.
Alternatively, you can use git commit -m <message>
to supply the commit message without opening the text editor.
Other useful commit tricks:
git commit -a
lets you commit changes you have made to files already under Git control
without having to take the step of adding the changes to the index. You still have to add new files with git add.
git add -p
lets you commit specific parts of files you have changed.
This is useful if you have made a bunch of changes that you think would be best split into several commits.
###Pushing your changes:
To push your changes up to a server (such as Github), use
git push <server name> <branch>
Adding -u
will make this server the default one to push to for this branch.
If you have cloned the repository as described above, the server will default to the location you cloned the
repository from (nicknamed "origin") and the branch will default to the master branch.
In other words, if you have followed this guide's instructions in cloning, git push
will suffice.
You can set up Git to push to multiple servers if you want, but that is a more advanced topic.
Branches will be discussed later in this guide.
###Pulling from the server:
If you are working on multiple machines and want to update your local repository to what the server has, you use
git pull <server name> <branch>
Similarly to push, the server name and branch should have sane defaults, so git pull
should suffice.
Git pull is actually shorthand for doing two things:
-
Calling
git fetch
, which updates the local copy of what the server has. Such branches are called "remote" branches because they are mirroring remote servers. -
Calling
git merge
, which merges what the remote branch has with what you have. If your commit history is the same as the server's commit history, you will be automatically fast-forwarded to the latest commit on the server. If your history does not match (maybe someone else has pushed commits since you last synced), the two histories will be merged.
It is not a bad idea to get into the practice of using these two commands instead of git pull
. This way you can
check to make sure that the server contains what you would expect before merging.
###Examining history
The command git log
shows the history of your current branch. Note that each commit is identified by a SHA-1 hash.
The author, commit date, and commit message follow. A more useful command is
git log --graph --oneline --decorate
which provides a display similar to TortoiseGit's log window. It shows the following:
- The first 7 digits of each commit's SHA-1 hash (enough to be unique)
- The --graph option shows how any branches (if there are others) fork off from the current branch.
- The --oneline option shows only the first line of each commit message
- The --decorate option shows all commit labels (branches and tags)
It may be convenient to alias this command as git graph
by doing the following:
git config --global alias.graph 'log --graph --oneline --decorate'
Now typing git graph
will run git log --graph --oneline --decorate
.
git graph
and git log
may be given the --all
flag in order to view all branches instead of just the current one.
Adding --stat
to one of these commands is also useful -
it shows which files each commit changed and how many lines were changed in each file.
###Dealing With Merges
Merges happen when you pull, as a result of a rebase operation, and when you merge one branch into another.
Like other version control tools, when Git cannot automatically merge a commit, it turns to you.
See this section
of the Git Book for an explanation on how to resolve merge conflicts.
If you screw up and would like to back out of the merge, you can usually abort the merge using the --abort
flag
with whatever command started the merge (e.g. git merge --abort
, git pull --abort
, git rebase --abort
).
###What to Commit
Generally, you should commit
- Actual code files (
.cpp
,.java
,.cs
, etc.) - Project files (Makefiles,
.sln
files in the case of Visual Studio, etc.)
You should not commit
- Files generated by your code or IDE (
.o
object files for C and C++,.class
files for Java,bin/
andobj/
folders for Visual Studio, etc.). This also includes your output program. - User-specific options (such as
.suo
files for Visual Studio)
To make Git automatically ignore files, you can create a text file named .gitignore
. Each line should contain
a file name, directory name, or pattern to ignore. For example, a .gitignore
for a Visual Studio C# project might
contain
bin/
obj/
*.suo
and a .gitignore
for a C++ Makefile-based project might contain
*.o
<program name>
The .gitignore
is automatically applied to the directory it is in and any sub-directories.
##Git Trickery
The above commands only provide the basics. The real power and convenience in Git come from leveraging its local commits and fast branching. A typical Git workflow looks like this:
- Create and check out a branch to add a feature.
- Make as many commits as you would like on that branch while developing that feature.
- Squash, rearrange, and edit your commits until you are satisfied with the commits enough to push them to the central server and make them public.
- Merge your branch back into the main branch.
- Delete your branch, if you desire.
- Push your changes to the central server.
###Creating a branch
git branch <branch name>
can be used to create a branch that will branch off the current commit. After it has been created, you should switch to it using
git checkout <branch name>
A simpler method is to do both in one step with
git checkout -b <branch name>
To see a list of branches, and which branch is currently checked out, use
git branch
###A word on commits
Many of the following commands take commits as arguments. A commit can be identified by any of the following:
- Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)
- Any commit label such as a branch or tag name
- The label
HEAD
always refers to the currently checked-out commit (usually the head of the branch, unless you usedgit checkout
to jump back in history to an old commit) - Any of the above plus
~
to refer to previous commits. For example,HEAD~
refers to one commit beforeHEAD
andHEAD~5
refers to five commits beforeHEAD
.
###Commits as checkpoints
In Subversion and other older, centralized version control systems, commits are permanent - once you make them, they are there on the server for everyone to see. In Git, your commits are local and you can combine, rearrange, and edit them before pushing them to the server. This gives you more flexibility and lets you use commits as checkpoints. Commit early and commit often.
###Editing the previous commit
git commit --amend
allows you to modify the previous commit. The contents of the index will be applied to it, allowing you to add more files or changes you forgot to put in. You can also use it to edit the commit message, if you would like.
###Squashing, rearranging, and changing history
git rebase -i <commit>
will bring up a list of all commits between <commit>
and the present, including HEAD
but excluding <commit>
.
This command allows you rewrite history. To the left of each commit, a command is specified.
Your options are as follows:
- The "pick" command (the default) uses that commit in the rewritten history.
- The "reword" command lets you change a commit message without changing the commit's contents.
- The "edit" command will cause Git to pause during the history rewrite at this commit.
You can then modify it with
git commit --amend
or insert new commits. - The "squash" command will cause a commit to be folded into the previous one. You will be prompted to enter a message for the combined commit.
- The "fixup" command works like squash, but discards the message of the commit being squashed instead of prompting for a new message.
- Commits can be erased from history by deleting them from the list of commits
- Commits can be re-ordered by re-ordering them in the list. When you are done modifying the list, Git will prompt you
to resolve any resulting merge problems (after doing so, continue rebasing with
git rebase --continue
)
When you are done modifying the list, Git will perform the desired actions.
If Git stops at a commit (due to merge conflicts caused by re-ordering the commits or due to the "edit" command),
use git rebase --continue
to resume. You can always back out of the rebase operation with git rebase --abort
.
IMPORTANT: Only use this command on local commits that have not yet been pushed to anybody else. Modifying commits that are on the central server will cause merge problems for obvious reasons.
Side note: Vim makes these rebase operations really simple since lines can be cut and pasted with few keystrokes.
##Additional Links
Try Git - a quick (15 minute), interactive Git tutorial by Github
All Git man pages - manual pages for every Git command