Git Tutorial 2016
Git Tutorial 2016
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Git Tutorial
Lars Vogel
Version 5.4
Copyright 2009, 2010, 2011, 2012, 2013 Lars Vogel
02.04.2013
Revision History
Revision 0.1 - 5.4
13.09.2009 - 04.12.2013
by Lars Vogel
Lars
Vogel
Git Tutorial
This tutorial explains the usage of the distributed version control system Git via the command line.
The examples were done on Linux (Ubuntu) but should also work on other operating systems like
Microsoft Windows.
Table of Contents
1. Git
1.1. What is a version control system?
1.2. What is a distributed version control
system?
1.3. What is Git?
1.4. Local repository and operations
1.5. Remote repositories
1.6. Branching and merging
1.7. Working tree
1.8. How to add changes to your Git repository
1.9. Adding to the staging area
1.10. Committing to the repository
1.11. Committing and commit objects
2. Tools
3. Terminology
3.1. Important terms
3.2. File states in Git
4. Commit reference
4.1. Using caret and tilde
4.2. Commit ranges with the double dot
operator
4.3. Commit ranges with the triple dot operator
5. Installation
5.1. Ubuntu, Debian and derived systems
5.2. Fedora, Red Hat and derived systems
5.3. Other Linux systems
5.4. Windows
5.5. Mac OS
6. Git Setup
6.1. Global configuration file
6.2. User Configuration
6.3. Push configuration
1 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
2 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
3 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
1. Git
1.1. What is a version control system?
4 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
These snapshots can be used to change your collection of files. You may, for example, revert the
collection of files to a state from 2 days ago. Or you may switch between versions for experimental
features.
5 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
6 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
For example if you want to develop a new feature, you can create a branch and make the changes in
this branch without affecting the state of your files in another branch.
Branches in Git are local to the respository. A branch created in a local repository, which was cloned
from another repository, does not need to have a counterpart in the remote repository. Local
branches can be compared with other local branches and with remote tracking branches. A remote
tracking branch proxies the state of a branch in another remote repository.
Git supports that changes from different branches can be combined. This allows the developer, for
example, to work independently on a branch called production for bugfixes and another branch
called feature_123 for implementing a new feature. The developer can use Git commands to combine
the changes at a later point in time.
For example, the Linux kernel community used to share code corrections (patches) via mailing lists to
combine changes coming from different developers. Git is a system which allows developers to
automate such a process.
You need to mark changes in the working tree to be relevant for Git. This process is called staging or
7 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
immutable.
Tutorials
Training
Books
Shop
Contact us
The staging area keeps track of the snapshots of the files until the staged changes are committed.
For committing the staged changes you use the git commit command.
This process is depicted in the following graphic.
8 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The above picture is simplified. Tree objects point to other tree objects and file blobs. Objects which
didn't change between commits are reused by multiple commits.
2. Tools
The original tooling for Git was based on the command line. These days there is a huge variety of
available Git tools.
You can use graphical tools, for example, the EGit Plugin for the Eclipse IDE. See GUI Clients at the
official git website for an overview.
3. Terminology
3.1. Important terms
The following table provides a summary of important Git terminology.
Table 1. Git Terminology
Term
Branches
Definition
A branch is a named pointer to a commit. Selecting a branch in Git terminology is called to
checkout a branch. If you are working in a certain branch, the creation of a new commit
advances this pointer to the newly created commit.
Each commit knows their parents (predecessors). Successors are retrieved by traversing the
commit graph starting from branches or other refs, symbolic reference (e.g. HEAD) or explicit
commit objects. This way a branch defines its own line of descendants in the overall version
graph formed by all commits in the repository.
9 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
You can create a new branch from an existing one and change the code independently from
other branches. One of the branches is the default (typically named master). The default branch
is the one for which a local branch is automatically created when cloning the repository.
Commit
When you commit your changes into a repository this creates a new commit object in the Git
repository. This commit object uniquely identifies a new revision of the content of the repository.
This revision can be retrieved later, for example, if you want to see the source code of an older
version. Each commit object contains the author and the committer, thus making it possible to
identify who did the change. The author and committer might be different people. The author
did the change and the committer applied the change to the Git repository.
HEAD is a symbolic reference most often pointing to the currently checked out branch.
HEAD
Sometimes the HEAD points directly to a commit object, this is called detached HEAD mode. In
that state creation of a commit will not move any branch.
The first predecessor of HEAD can be addressed via HEAD~1, HEAD~2 and so on. If you switch
branches, the HEAD pointer moves to the last commit in the branch. If you checkout a specific
commit, the HEAD points to this commit.
Index
Repository
A repository contains the history, the different versions over time and all different branches and
tags. In Git each copy of the repository is a complete repository. If the repository is not a bare
repository, it allows you to checkout revisions into your working tree and to capture changes by
creating new commits. Bare repositories are only changed by transporting changes from other
repositories.
This tutorial uses the term repository to talk about a non bare repository. If it talks about a bare
repository, this is explicitly mentioned.
Revision
Represents a version of the source code. Git implements revisions as commit objects (or short
commits). These are identified by an SHA-1 secure hash. SHA-1 ids are 160 bits long and are
represented in hexadecimal notation.
Staging
area
The staging area is the place to store changes in the working tree before the commit. The staging
area contains the set of the snapshots of changes in the working tree (change or new files)
relevant to create the next commit and stores their mode (file type, executable bit).
Tags
A tag points to a commit which uniquely identifies a version of the Git repository. With a tag, you
can have a named point to which you can always revert to. You can revert to any point in a Git
repository, but tags make it easier. The benefit of tags is to mark the repository for a specific
reason e.g. with a release.
Branches and tags are named pointers, the difference is that branches move when a new commit
is created while tags always point to the same commit.
Technically, a tag reference can also point to an annotated tag object.
URL
A URL in Git determines the location of the repository. Git distinguishes between fetchurl for
getting new data from other repositories and pushurl for pushing data to another repository.
Working
tree
The working tree contains the set of working files for the repository. You can modify the content
and commit the changes as new commits to the repository.
10 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
4. Commit reference
4.1. Using caret and tilde
You can use ^ (caret) and ~ (tilde) to reference predecessor commits objects from other references.
Predecessor commits are sometimes also called parent commits. You can combine the ^ and ~
operators.
[reference]~1 describes the first predecessor of the commit object accessed via [reference].
[reference]~2 is the first predecessor of the first predecessor of the [reference] commit. [reference]~3
is the first predecessor of the first predecessor of the first predecessor of the [reference] commit, etc.
[reference]~ is an abbreviation for [reference]~1.
For example you can use the HEAD~1 or HEAD~ reference to access the first [reference] of the
commit to which the HEAD pointer currently points.
[reference]^1 also describes the first predecessor of the commit object accessed via [reference].
The difference is that [reference]^2 describes the second predecessor of a commit. A merge commit
has two predecessors.
[reference]^ is an abbreviation for [reference]^1.
Tip
Think of c1..c2 as all commits as of c1 (not including c1) until commit c2.
For example, you can ask Git to show all commits which happened between HEAD and HEAD~4.
git log HEAD~4..HEAD
This also works for branches. To list all commits which are in the "master" branch but not in the
"testing" branch use the following command.
git log testing..master
You can also list all commits which are in the "testing" but not in the "master" branch.
11 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
5. Installation
5.1. Ubuntu, Debian and derived systems
On Ubuntu and similar systems you can install the Git command line tool via the following command:
sudo apt-get install git
5.4. Windows
A windows version of Git can be found on the msysgit Project site. The URL to this webpage is listed
below. This website also describes the installation process.
http://msysgit.github.io/
5.5. Mac OS
The easiest way to install Git on a Mac is via a graphical installer. This installer can be found under
12 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
http://code.google.com/p/git-osx-installer
As this procedure is not an official Apple one, it may change from time to time. The easiest way to
find the current procedure is to Google for the "How to install Git on a Mac" search term.
Git is also installed by default with the Apple Developer Tools on Mac OS X.
6. Git Setup
6.1. Global configuration file
Git allows you to store global settings in the .gitconfig file located in the user home directory. Git
stores the committer and author of a change in each commit. This and additional information can be
stored in the global settings.
You setup these values with the git config command.
In each Git repository you can also configure the settings for this repository. Global configuration is
done if you include the --global flag, otherwise your configuration is specific for the current Git
repository.
You can also setup system wide configuration. Git stores theses values is in the /etc/gitconfig file,
which contains the configuration for every user and repository on the system. To set this up, ensure
you have sufficient rights, i.e. root rights, in your OS and use the --system option.
The following configures Git so that a certain user and email address is used, enable color coding and
tell Git to ignore certain files.
You learn about the push command in Section 13.2, Push changes to another repository.
13 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Note
This setting depends on the individual workflow. Some teams prefer to
create merge commits, but the author of this tutorial likes to avoid them.
If you want to query the global settings you can use the following command.
14 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
You can create the .gitignore file in the root directory of the working tree to make it specific for the
Git repository.
Note
Files that are committed to the Git repository are not automatically removed
if you add them to a .gitignore file. You can use the git rm -r --cached
[filename]
Tip
The .gitignore file tells Git to ignore the specified files in Git commands.
You can still add ignored files to the staging area of the Git repository by
using the --force parameter, i.e. with the git add --force [filename]
command.
This is useful if you want to add, for example, auto-generated binaries, but
you need to have a fine control about the version which is added and want
to exclude them from the normal workflow.
15 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The local .gitignore file can be committed into the Git repository and therefore is visible to everyone
who clones the repository. The global .gitignore file is only locally visible.
Tip
One problem with this approach is that .gitkeep is unlikely to be ignored by
version control systems or build agents, resulting in .gitkeep being copied
to the output repository. One possible alternative is to create a .gitkeep file
in there, which has the same effect but will more likely be ignored by tools
that do build processing and filtering of SCM specific resources.
16 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
mmkkddiirr datafiles
All files inside the repository folder excluding the .git folder are the working tree for a Git repository.
Note
In case you change one of the files again before committing, you need to
17 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Afterwards run the git status command again to see the current status.
18 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Tip
Alternatively to the git rm command you can use the git commit command
with the -a flag or the -A flag in the git add command. This flag adds
changes of files known by the Git repository to the commit in case of the git
commit
command. In case of the git add command it adds all file changes
19 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
# deleted:
nonsense.txt
#
# no changes added to commit (use "git add" and/or "git commit -a")
# try standard way of committing -> will NOT work
# output of the command listed below
git add .
git commit -m "file has NOT been removed"
# On branch master
# Changes not staged for commit:
#
(use "git add/rm <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted:
nonsense.txt
#
# no changes added to commit (use "git add" and/or "git commit -a")
After validating that this command does not remove the file from the Git
repository you can use the -a parameter. Be aware that the -a adds other
changes, too.
# commit the remove with the -a flag
git commit -a -m "File nonsense.txt is now removed"
# alternatively you could add deleted files to the staging area via
# git add -A .
# git commit -m "File nonsense.txt is now removed"
Note
The old commit is still available until a clean-up job remove it. See
Section 31.2, git reflog for details.
Assume the last commit message was incorrect as it contained a typo. The following command
corrects this via the --amend parameter.
# assume you have something to commit
20 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
You should use the git --amend command only for commits which have not been pushed to a public
branch of another Git repository. The git --amend command creates a new commit ID and people
may have based their work already on the existing commit. In this case they would need to migrate
their work based on the new commit.
Note
This does not remove the file from the repository history. If the file should
also be removed from the history, have a look at git filter-branch which
allows you to rewrite the commit history. See Section 43.1, Using git
filter-branch for details.
Note
Think of remotes as shorter bookmarks for repositories. You can always
connect to a remote repository if you know its URL and if you have access to
it. Without remotes the user would have to type the URL for each and every
command which communicates with another repository.
It is possible that users connect their individual repositories directly, but a typically Git workflow
involves one or more remote repositories which are used to synchronize the individual repository.
Typically the remote repository which is used for synchronization is located on a server which is
21 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Tip
A remote repository can also be hosted in the local file system.
working tree is called a bare repository. You can create such a repository with the --bare option. The
command to create a new empty bare remote repository is displayed below.
# create a bare repository
git init --bare
By convention the name of a bare repository should end with the .git extension.
Note
To create a bare Git repository in the Internet you would, for example,
connect to your server via the ssh protocol or you use some Git hosting
platform, e.g. Github.com.
Execute the following commands to create a bare repository based on your existing Git repository.
# switch to the first repository
22 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Tip
You can convert a normal Git repository into a bare repository by moving
the content of the .git folder into the root of the repository and removing
all others files from the working tree. Afterwards you need to update the Git
repository configuration with the git config core.bare true command. The
problem with this process is that it does not take into account potential
future internal changes of Git, hence cloning a repository with the --bare
option should be preferred.
23 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
To see the details of the remotes, e.g. the URL use the following command.
# show the existing defined remotes
git remote
# show details about the remotes
git remote -v
24 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Note
Training
Books
Shop
Contact us
You can pull in the changes in your first example repository with the following commands.
# switch to the first repository and pull in the changes
ccdd ~/repo01
git pull ../remote-repository.git/
Tip
The git pull command is actually a shortcut for git fetch followed by the
git merge
Section 6.4, Avoid merge commits for pulling you configured your Git
repository so that git pull is a fetch followed by a rebase. See Section 33.1,
Fetch for more information about the fetch command.
25 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Git supports several transport protocols to connect to other Git repositories; the native protocol for
Git is also called git.
The following command clones an existing repository using the Git protocol. The Git protocol uses the
port 9148 which might be blocked by firewalls.
# switch to a new directory
mmkkddiirr ~/online
ccdd ~/online
# clone online repository
git clone git://github.com/vogella/gitbook.git
If you have ssh access to a Git repository, you can also use the ssh protocol. The name preceding @ is
the user name used for the ssh connection.
# clone online repository
git clone sssshh://[email protected]/vogella/gitbook.git
# older syntax
git clone [email protected]:vogella/gitbook.git
Alternatively you could clone the same repository via the http protocol.
# The following will clone via HTTP
git clone http://[email protected]/vogella/gitbook.git
26 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Note
For secured SSL encrypted communication you should use the ssh or https
protocol in order to guarantee security.
Tip
Git is able to store different proxy configurations for different domains, see
core.gitProxy in Git config manpage .
working tree with the content of the commit to which the branch points and moves the HEAD pointer
to the new branch. As explained in Section 3, Terminology HEAD is a symbolic reference most
often pointing to the currently checked out branch.
27 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
git branch
If you want to see all branches (including remote tracking branches), use the -a for the git branch
command. See Section 32.1, Remote tracking branches for information about remote tracking
branches.
# lists all branches including the remote branches
git branch -a
To create a branch and to switch to it at the same time you can use the git checkout command with
the -b parameter.
# Create branch and switch to it
git checkout -b bugreport12
# Creates a new branch based on the master branch
28 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
This way you can decide which branches you want to push to other repositories and which should be
local branches. You learn more about branches and remote repositories in Section 32.1, Remote
tracking branches.
You can also use commmit ranges as described in Section 4.2, Commit ranges with the double
dot operator and Section 4.3, Commit ranges with the triple dot operator. For example, if you
compare a branch called your_branch with the master branch the following command shows the
changes in your_branch and master since these branches diverged.
# shows the differences in your
# branch based on the common
# ancestor for both branches
29 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
See Section 22, Viewing changes with git diff and git show for more examples of the git diff
command.
annotated tag contains additional information about the tag, e.g. the name and email of the person
who created the tag, a tagging message and the date of the tagging. Annotated tags can also be
signed and verified with GNU Privacy Guard (GPG).
30 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Warning
If you checkout a tag, you are in the detached head mode and commits
created in this mode are harder to find after you checkout a branch
again. See Section 31.1, Detached HEAD for details.
31 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The idea is that the patch version is incremented if (only) backwards compatible bug fixes are
introduced, the minor version is incremented if new, backwards compatible functionality is
introduced to the public API and the major version is incremented if any backwards incompatible
changes are introduced to the public API.
For the detailed discussion on naming conventions please see the following URL: Semantic
versioning.
20.2. Example
The following commands create some changes in your Git repository.
# make some changesm, assumes that the test01
# and test02 files exists
# and have been committed in the past
eecchhoo "This is a new change to the file" > test01
eecchhoo "and this is another new change" > test02
# create a new file
llss > newfileanalyzis.txt
The git status command show the current status of your repository and suggest possible actions.
# see the current status of your repository
# (which files are changed / new / deleted)
git status
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The git log commands shows the history of your repository in the current branch, i.e. the list of
commits.
# show the history of commits in the current branch
git log
For more options on the git log command see the Git log manpage.
33 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Note
The double hyphens (--) in Git separate flags from non-flags (usually
filenames).
34 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
35 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Tip
Training
Books
Shop
Contact us
You can avoid using the git stash command. In this case you commit the
changes you want to put aside and use the git commit --amend command to
change the commit later. If you use the approach of creating a commit, you
typically put a marker in the commit message to mark it as a draft, e.g.
"[DRAFT] implement feature x".
of available stashes
be
on
on
on
something like:
master: 273e4a0 Resize issue in Dialog
master: 273e4b0 Silly typo in Classname
master: 273e4c0 Silly typo in Javadoc
36 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
command.
Tutorials
Training
Books
Shop
Contact us
26.2. Example
The following commands demonstrates the usage of the git clean command.
# Create a new file with content
eecchhoo "this is trash to be deleted" > test04
# Make a dry-run to see what would happen
# -n is the same as --dry-run
git clean -n
# delete, -f is required if
# variable clean.requireForce is not set to false
git clean -f
# use -d flag to delete new directories
# use -x to delete hidden files, e.g. ".example"
git clean -fdx
For example, you can restore a directory called data with the following command.
git checkout -- data
37 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Contact us
Note
To learn more about the git reset command see Section 28.1, Use cases
for git reset.
If you specify the --soft parameter, the git reset command moves only the HEAD pointer.
2.
If you specify the --mixed parameter (also the default), the git reset command moves the
HEAD pointer and resets the staging area to the new HEAD.
38 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Via parameters you can define if the staging area and the working tree is updated. As a reminder, the
working tree contains the files and the staging area contains the changes which are marked to be
included in the next commit. These parameters are listed in the following table.
Table 2. git reset options
39 of 65
Reset
HEAD
Working tree
Staging area
soft
Yes
No
No
mixed (default)
Yes
No
Yes
hard
Yes
Yes
Yes
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Tip
Training
Books
Shop
Contact us
The git reset command does not remove untracked files. Use the git clean
command for this.
command in addition.
As the staging area is not changed, you have it after the soft reset in the desired state for your new
commit, i.e. it has all the changes from the commits that you removed with the reset.
# squashes the last two commits
git reset --soft HEAD~1 && git commit -m "new commit message"
The interactive rebase adds more flexibility to squashing commits and allows to use the existing
commit messages. See Section 37.2, Interactive rebase to edit history for details.
40 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The following commands demonstrate that. You can also make a copy of the file.
# [reference] can be a branch, tag, HEAD or commit ID
# [filename] is the filename including path
git show [reference]:[filename]
41 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials Training
git checkout [commit_id]
Books
Shop
Contact us
Warning
If you checkout a commit, you are in the detached head mode and
commits in this mode are harder to find after you checkout another
branch. Before committing it is good practice to create a new branch to
leave the detached head mode. See Section 31.1, Detached HEAD for
details.
The git reflog command also list commits which you have removed.
42 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Tip
Training
Books
Shop
Contact us
There are multiple reflogs: one per branch and one for HEAD. For branches
use the git reflog [branch] command and for HEAD use the git reflog or
the git reflog HEAD command.
31.3. Example
The following example shows how you can use git reflog to reset the current local branch to a commit
which isn't reachable from the git log anymore.
# Assume the ID for the second commit is
# 45ca2045be3aeda054c5418ec3c4ce63b5f269f7
# Resets the head for your tree to the second commit
git reset --hard 45ca2045be3aeda054c5418ec3c4ce63b5f269f7
# See the log
git log
# Output shows the history until the 45ca2045be commit
# See all the history including the deletion
git reflog
# <Output>
cf616d4 HEAD@{1}:
# ...snip....
1f1a73a HEAD@{2}:
45ca204 HEAD@{3}:
cf616d4 HEAD@{4}:
To update remote tracking branches without changing local branches you use the git fetch
command which is covered in Section 33, Updating your remote tracking branches with git
fetch.
43 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
For example if you want to delete the branch called testbranch in the remote repository called origin
you can use the following command.
git push origin :testbranch
Note
Note you can also specify the remote repository's URL. So the following
command also works.
git push sssshh://[URL_to_repo] :testbranch
pull
If you clone a Git repository, your local master branch is created as a tracking branch for the master
branch of the origin repository (short: origin/master) by Git.
Instead of using the git checkout command you can also use the git branch command.
# origin/master used as exmaple but can be replaced
# Create branch based on remote branch
git branch [new_branch] origin/master
44 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
The --no-track allows you to specify that you do not want to track a branch. You are later going to
explicitly add a tracking branch with the git branch -u command.
# instruct Git to create a branch with does
# not track another branch
git branch --no-track [new_branch_notrack] origin/master
# update this branch to track the origin/master branch
git branch -u origin/master [new_branch_notrack]
The fetch command only updates the remote tracking branches and none of the local branches and it
does not change the working tree of the Git repository. Therefore you can run the git fetch
command at any point in time.
After reviewing the changes in the remote tracking branch you can merge the changes into your local
branches or rebase your local branches onto the remote tracking branch.
45 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
commits.
Tutorials
Training
Books
Shop
Contact us
Tip
A detailed description of merge, rebase and cherry-pick can be found in
Section 36, Merging branches.
The above commands shows the changes introduced in HEAD compared to origin. If you want to see
the changes in origin compared to HEAD, you can switch the arguments or use the -R parameter.
33.4. Rebase your local branch onto the remote tracking branch
You can rebase your current local branch onto a remote tracking branch. The following commands
demonstrate that.
# assume you want to rebase master based on the latest fetch
# therefore check it out
git checkout master
# update your remote tracking branch
git fetch
# rebase your master onto origin/master
git rebase origin/master
Tip
46 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Rebasing branches.
34. Merging
Git allows you to combine the changes of two branches. This process is called merging.
47 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
After the fast forward merge the HEAD pointer of "master" points to the existing commit.
48 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
As a result a so-called merge commit is created on the current branch which is combining the
respective changes from the two branches being merged. This commit points to both its
predecessors.
Tip
49 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
with the git merge --no-ff command. This is a question of taste, some
teams prefer to always have merge commits, the author of this tutorial
prefers fast forward merges.
Warning
Be careful if you use the ours merge strategy, it ignores everything from
the branch which is merged.
Note
You typically use the ours merge strategy to document in the Git repository
that you have integrated a branch and decided to ignore all changes from
this branch.
The recursive merge strategy (default) allows you to specify flags with the -X parameter. For example
you can specify here the ours option. This option forces conflicting changes to be auto-resolved
cleanly by favoring the local version. Changes from the other branch that do not conflict with our
local version are reflected to the merge result. For a binary file, the entire contents are taken from
the local version.
Warning
The ours option for the recursive merge strategy should not be confused
with the ours merge strategy.
A similar option to ours is the theirs option. This option prefers the version from the branch which is
merged.
Both options are demonstrated in the following example code.
# Merge changes preferring our version
git merge -s recursive -X ours [branch_to_merge]
# Merge changes preferring the version from
50 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Another useful option is the ignore-space-change parameter which ignores whitespace changes.
For more information about the merge strategies and options see Git merge manpage.
37. Rebase
37.1. Rebasing branches
You can use Git to rebase one branch on another one. As described, the merge command combines
the changes of two branches. If you rebase a branch called A onto another, the git command takes
the changes introduced by the commits of branch A and applies them based on the HEAD of the
other branch. This way the changes in the other branch are also available in branch A.
The processes is displayed in the following picture. We want to rebase the branch onto master.
Running the rebase command creates a new commit with the changes of the branch on top of the
master branch.
51 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Performing a rebase from one branch to another branch does not create a merge commit.
The final result for the source code is the same as with merge but the commit history is cleaner; the
history appears to be linear.
# create new branch
git checkout -b rebasetest
# To some changes
ttoouucchh rebase1.txt
git add . && git commit -m "work in branch"
# do changes in master
git checkout master
# make some changes and commit into testing
eecchhoo "This will be rebased to rebasetest" > rebasefile.txt
git add rebasefile.txt
git commit -m "New file created"
# rebase the rebasetest onto master
git checkout rebasetest
git rebase master
# now you can fast forward your branch onto master
git checkout master
git merge rebasetest
Rebase can be used to place a feature branch in the local Git repository onto the changes of the
master branch. This ensures that your feature is close to the tip of the upstream branch until it is
finally published.
Note
There is a price for using rebase: if you rewrite more than one commit by
52 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
We will combine the last seven commits. You can do this interactively via the following command.
git rebase -i HEAD~7
This will open your editor of choice and let you configure the rebase operation by defining which
commits to pick, squash or fixup.
Pick includes the selected commit. Squash combines the commit messages while fixup will disregard
the commit message. The following shows an example of the selection, we pick the last commit,
squash 5 commits and fix the sixth commit.
p
f
f
f
f
f
s
53 of 65
7c6472e
4f73e68
bc9ec3f
701cbb5
910f38b
31d447d
e08d5c3
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
#
#
#
#
#
#
#
#
#
#
#
#
Tutorials
Training
Books
Shop
Contact us
Commands:
p, pick = use commit
r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit's log message
x, exec = run command (the rest of the line) using shell
These lines can be re-ordered; they are executed from top to bottom.
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Warning
Avoid rebasing changes you already shared with others.
For example, assume that a user has a local feature branch and wants to push it onto a branch on the
remote repository. However, the branch has evolved and therefore pushing is not possible. Now it is
good practice to fetch the latest state of the branch from the remote repository. Afterwards you
rebase the local feature branch onto the remote tracking branch. This avoids an unnecessary merge
commit. This rebasing of a local feature branch is also useful to incorporate the latest changes from
remote into the local development, even if the user does not want to push right away.
Tip
Rebasing and amending commits is safe as long as you did not push any of
the changes involved in the rebase. For example, if you cloned a repository
and worked in this repository. Rebasing is a great way to keep the history
clean when contributing back your modifications.
Warning
In case you want to rewrite history for changes you have shared with
54 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Note
The new commit does not point back to its original commit so do not use
cherry-pick blindly since you may end up with several copies of the same
change. Most often cherry-pick is either used locally (to emulate rebase -i)
or to port individual bug fixes done on a development branch into
maintenance branches.
You can check the commit history for example with the git log --oneline command.
# see change commit history
git log --oneline
The following command selects the first commit based on the commit id and applies its changes to
the master branch. This creates a new commit on the master branch.
55 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials Training
git cherry-pick ebb46b7
Books
Shop
Contact us
The cherry-pick command can be used to change the order of commits. git cherry-pick also
accepts commit ranges for example in the following command.
git checkout master
# pick both commits
git cherry-pick picktest~..picktest~1
Tip
See Section 4.2, Commit ranges with the double dot operator for more
information about commit ranges.
56 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Git marks the conflict in the affected file. This file looks like the following.
<<<<<<< HEAD
Change in the first repository
=======
Change in the second repository
>>>>>>> b29196692f5ebfd10d8a9ca1911c8b08127c85f8
The above is the part from your repository and the below one from the remote repository. You can
edit the file manually and afterwards commit the changes.
Alternatively, you could use the git mergetool command. git mergetool starts a configurable merge
tool that displays the changes in a split screen. git mergetool is not always available. It is also safe to
edit the file with merge conflicts in a normal editor.
# Either edit the file manually or use
git mergetool
# You will be prompted to select which merge tool you want to use
# For example on Ubuntu you can use the tool "meld"
# After merging the changes manually, commit them
git commit -m "merged changes"
Instead of using the -m option in the above example you can also use the git commit command
without this option. In this case the command opens your default editor with a default commit
messages about the merged conflicts. It is good practice to use this message.
Or you can define an alias for a detailed git log command. The following command defines the git
ll
alias.
You can also run external commands. In this case you start the alias definition with a ! character. For
example, the following defines the git ac command which combines git add . -A and git commit
commands.
# define alias
git config --global alias.act '!git add . -A && git commit'
# to use it
git ac -m "message"
57 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Warning
Books
Shop
Contact us
In the past msysGit for Windows had problems with an alias beginning
with !, but it has been reported that this now works with msysGit, too .
command creates the local configuration file for the submodules if it does not yet exist.
Use the git submodule update command to set the submodules to the commit specified by the main
repository.
# setting the submodules to the commit defined by master
git submodule update
Warning
The fact that submodules track commits and not branches frequently
leads to confusion. That is why Git 1.8.2 added the option to also track
branches. Read the following sections to more learn about this.
58 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Warning
This means that if you pull in new changes into the submodules, you need
to create a new commit in your main repository in order to track the
updates of the nested submodules.
If you update your submodule and want to use this update in your main repository, you need to
commit this change in your main repository. The git submodule update command sets the
submodule to the commit referred to in the main repository.
The following example shows how to update a submodule to its latest commit in its master branch.
# update submodule in the master branch
# skip this if you use --recurse-submodules
# and have the master branch checked out
ccdd [submodule directory]
git checkout master
git pull
# commit the change in main repo
# to use the latest commit in master of the submodule
ccdd ..
git add [submodule directory]
git commit -m "moved submodule to latest commit in master"
# share your changes
git push
Another developer can get the update by pulling in the changes and running the submodules update
command.
# another developer wants to get the changes
git pull
# this updates the submodule to the latest
# commit in master as set in the last example
git submodule update
Warning
With this setup you are tracking commits, so if the master branch in the
submodule moves on, you are still pointing to the existing commit. You
need to repeat this procedure every time you want to use new changes of
the submodules. See the next chapter for an alternative with a Git release
of version 1.8.2 or higher.
59 of 65
command.
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Afterwards use the git bisect command to find the bad commit. First you use the git bisect start
command to define a commit known to be bad (showing the problem) and a commit known to be
good (not showing the problem).
# define that bisect should check
# the last 5 commits
git bisect start HEAD HEAD~5
60 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Tip
Training
Books
Shop
Contact us
The above serves as example. The existence of a file can be easier verified
with the git bisect command: git bisect run test -f test1.txt
Warning
Using filter-branch is dangerous as it changes the Git repository. It
changes the commit IDs and reacting on such a change requires explicit
action from the developer, e.g. he may try to rebase his stale local branch
onto the corresponding rewritten remote tracking branch.
Note
A practical case for using git filter-branch is where you have added a file
which contains a password to the Git repository, and you want to remove
the password from the history.
message, etc) and also contains the diff of any binary data in the commit, for example, an image.
61 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
Contact us
Alternatively you could create a diff file with the git diff command, but this diff file does not contain
the metadata information.
To apply this patch to your master branch in a different clone of the repository, switch to it and use
the git apply command.
# Switch to the master
git checkout master
# Apply the patch
git apply 0001-First-commit-in-the-branch.patch
Afterwards you can commit the changes introduced by the patches and delete the patch file.
# Patch is applied to master
# Change can be committed
git add .
git commit -a -m "Applied patch"
# Delete the patch file
rrmm 0001-First-commit-in-the-branch.patch
Tip
Use the git am command to apply and commit the changes in a single step.
To apply and commit all patch files in the directory use, for example, the git
am *.patch
command.
62 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
and post-receive script to check the input or to trigger actions after the commit.
If you create a new Git repository, Git creates example scripts in the .git/hooks directory. The
example scripts end with .sample. To activate them make them executable and remove the .sample
from the filename.
The hooks are documented under the following URL: Git hooks manual page.
On Linux and Mac you can tell Git to convert CRLF during a checkout to LF with the following setting.
git config --global core.autocrlf input
63 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
Let's say you have a repository called http://svn.example.com/repo with the default layout (trunk,
branches, tags) and already prepared a local git repository where you want to put everything, then
navigate to your git directory and use the following commands:
svn2git http://svn.example.com/repo --verbose
svn2git --rebase
The parameter --verbose adds detailed output to the commandline so you can see what is going on
including potential errors. The second svn2git --rebase command aligns your new git repository
with the svn import. You are now ready to push to the web and get forked! If your svn layout deviates
from the standard or other problems occur, seek svn2git --help for documentation on additional
parameters.
64 of 65
12/25/2013, 9:57 PM
Git Tutorial
http://www.vogella.com/articles/Git/article.html
vogella.com
Tutorials
Training
Books
Shop
Contact us
65 of 65
12/25/2013, 9:57 PM