Anda di halaman 1dari 58

3/6/14

Git - Tutorial
Search Training Books Blog Shop Contact us vogella.com Tutorials

Support free tutorials: Get the book

Git - Tutorial
Lars Vogel
Version 5.6 Copyright 2009, 2010, 2011, 2012, 2013, 2014 Lars Vogel 08.02.2014
Revision History Revision 0.1 - 5.6 13.09.2009 - 08.02.2014 Lars Vogel bug fixes and improvements

Training Books

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

www.vogella.com/tutorials/Git/article.html

1/58

3/6/14
5.5. Mac OS 6. Git Setup 6.1. Global configuration file 6.2. User Configuration 6.3. Push configuration 6.4. Avoid merge commits for pulling 6.5. Color Highlighting 6.6. Setting the default editor 6.7. Setting the default merge tool 6.8. More settings 6.9. Query Git settings

Git - Tutorial

7. Setup rules for ignoring files and directories 7.1. Creating a .gitignore file for your repository 7.2. Global (cross-repository) .gitignore settings 7.3. Local per-repository ignore rules 8. Tracking empty directories with .gitkeep 9. Getting started with Git 9.1. Target of this chapter 9.2. Create directory 9.3. Create Git repository 9.4. Create content 9.5. See the current status of your repository 9.6. Add files to the staging area 9.7. Commit to Git repository 10. Looking at the result 10.1. Results 10.2. Directory structure 11. Remove files and adjust the last commit 11.1. Remove files 11.2. Remove a file from the staging area 11.3. Correct the last commit with git amend 11.4. Remove files based on .gitignore changes 12. Remote repositories 12.1. What are remotes? 12.2. Bare repositories 12.3. Setting up a bare Git repository 12.4. Cloning and the remote called "origin" 12.5. Adding more remote repositories 12.6. Synchronizing with remote repositories 12.7. Show the existing remotes 13. Cloning remote repositories and push and pull 13.1. Clone your repository 13.2. Push changes to another repository 13.3. Pull changes 14. Online remote repositories 14.1. Cloning online repositories 14.2. Add more remote repositories 14.3. Rename remote repositories 14.4. Remote operations via http and a proxy 15. What are branches? 16. Commands to working with branches 16.1. List available branches 16.2. Create new branch 16.3. Checkout branch 16.4. Rename a branch 16.5. Delete a branch 16.6. Push changes of a branch to a remote repository 17. Differences between branches 18. Tags in Git 18.1. What are tags? 18.2. Lightweight and annotated tags

www.vogella.com/tutorials/Git/article.html

2/58

3/6/14
19. Tagging in Git 19.1. List tags 19.2. Search by pattern for a tag 19.3. Creating lightweight tags 19.4. Creating annotated tags 19.5. Signed tags 19.6. Checkout tags 19.7. Push tags 19.8. Delete tags 19.9. Naming conventions for tags

Git - Tutorial

20. Viewing changes in the working tree with git status 20.1. Viewing the status of the working tree with git status 20.2. Example 21. Analyzing the repository history with git log 21.1. Using git log 21.2. Helpful parameters for git log 21.3. View the change history of a file 21.4. Find out which commit deleted a file or directory 21.5. See all commits of a certain user 22. Viewing changes with git diff and git show 22.1. See unstaged changes since the last commit 22.2. See differences between staging area and last commit 22.3. See the differences introduced by a commit 22.4. See the difference between two commits 22.5. See the files changed by a commit 23. Analyzing line changes with git blame 24. git shortlog for release announcements 25. Stashing committed changes with git stash 25.1. The stash command 25.2. Using the Git stash command 26. Remove untracked files with git clean 26.1. Removing untracked files in the working tree 26.2. Example 27. Revert uncommitted changes 27.1. Checkout version from the staging area 27.2. Checkout with staged changes 27.3. Remove staged changes for new files 27.4. Remove staged changes for previously committed files 28. Moving the HEAD pointer with git reset 28.1. Use cases for git reset 28.2. Finding commits which you have reset 28.3. git reset and deleting all unstaged files 28.4. Using git reset to squash commits 29. Retrieving files from the history 29.1. View file in different revision 29.2. Restore a deleted file in a Git repo 29.3. See which commit deleted a file 30. Checkout or revert commits 30.1. Checkout commits versions 30.2. Reverting a commit 31. Recovering lost commits 31.1. Detached HEAD 31.2. git reflog

www.vogella.com/tutorials/Git/article.html

3/58

3/6/14
31.3. Example 32. Remote and local tracking branches

Git - Tutorial

32.1. Remote tracking branches 32.2. Delete a remote tracking branch in your local repository 32.3. Delete a branch in a remote repository 32.4. Tracking branches 32.5. Setting up tracking branches 32.6. See the branch information for a remote repository 33. Updating your remote tracking branches with git fetch 33.1. Fetch 33.2. Fetch from all remote repositories 33.3. Compare remote tracking branch with local branch 33.4. Rebase your local branch onto the remote tracking branch 33.5. Fetch compared with pull 34. Merging 35. Command to merge two branches 36. Merging branches 36.1. Fast-forward merge 36.2. Merge commit 36.3. Specifying merge strategies and parameters 37. Rebase 37.1. Rebasing branches 37.2. Interactive rebase to edit history 37.3. Good practice for rebase 38. Selecting individual commits with git cherry-pick 38.1. Applying a single commit 38.2. Using cherry-pick 39. Solving merge conflicts 39.1. What is a merge conflict 39.2. Example for solving a merge conflict 40. Define alias 40.1. Using an alias 40.2. Alias examples 41. Submodules - repositories inside other Git repositories 41.1. Using submodules 41.2. Updating submodules 41.3. Tracking commits 41.4. Tracking branches with submodules 42. Error search with git bisect 42.1. Using git bisect 42.2. git bisect example 43. Rewriting commit history with git filter-branch 43.1. Using git filter-branch 43.2. filter-branch example 44. Create and apply patches 44.1. What is a patch? 44.2. Create and apply patches 44.3. Create a patch for a selected commit 45. Git commit and other hooks 45.1. Usage of Git hooks 45.2. Client and server side commit hooks

www.vogella.com/tutorials/Git/article.html

4/58

3/6/14
46. Line endings on different platforms 47. Migrating from SVN 48. Frequently asked questions 48.1. Can Git handle symlinks? 49. Git series 50. Get the Book 51. Support free vogella tutorials 51.1. Thank you 51.2. Questions and Discussion 52. Links and Literature

Git - Tutorial

Learn Source Control Free IPv6 Certification $0.01 Web Hosting

Fast training on version control Subversion & Generic Training amazon.co.uk Get started in minutes! Become an IPv6 Guru ipv6.he.net

Scalable, Secure Web Hosting. Try Our Aw ard-Winning Service Now ! w w w .hostgator.com/1Penny

1. Git
1.1. What is a version control system?
A version control system allows you to track the history of a collection of files and includes the functionality to revert the collection of files to another version. Each version captures a snapshot of the files at a certain point in time. The collection of files is usually source code for a programming language but a typical version control system can put any type of file under version control. The collection of files and their complete history are stored in a repository. The process of creating different versions (snapshots) in the repository is depicted in the following graphic. Please note that this picture fits primarily to Git, other version control systems like CVS don't create snapshots but store file deltas.

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.

1.2. What is a distributed version control system?


www.vogella.com/tutorials/Git/article.html 5/58

3/6/14

Git - Tutorial

A distributed version control system does not necessarily have a central server which stores the data. The user can copy an existing repository. This copying process is typically called cloning in a distributed version control system and the resulting repository can be referred to as clone. Typically there is a central server for keeping a repository but each cloned repository is a full copy of this repository. The decision which of the copies is considered to be the central server repository is pure convention and not tied to the capabilities of the distributed version control system itself. Every clone contains the full history of the collection of files and a cloned repository has the same functionality as the original repository. Every repository can exchange versions of the files with other repositories by transporting these changes. This is typically done via a repository running on a server which is, other than the local machine of a developer, always online.

1.3. What is Git?


Git is a distributed version control system. Git originates from the Linux kernel development and is used by many popular Open Source projects, e.g. the Android or the Eclipse developer teams, as well as many commercial organizations. The core of Git was originally written in the programming language C, but Git has also been reimplemented in other languages, e.g. Java, Ruby and Python.

1.4. Local repository and operations


After cloning or creating a repository the user has a complete copy of the repository. The user performs version control operations against this local repository, e.g. create new versions, revert changes, etc. You can configure your repository to be a bare or a non-bare repositories. bare repositories are used on servers to share changes coming from different developers non-bare repositories allow you to create new changes through modification of files and to create new versions in the repository If you want to delete a Git repository, you can simply delete the folder which contains the repository.

1.5. Remote repositories


Git allows the user to synchronize the local repository with other (remote) repositories. Users with sufficient authorization can push changes from their local repository to remote repositories. They can also fetch or pull changes from other repositories to their local Git repository.
www.vogella.com/tutorials/Git/article.html 6/58

3/6/14

Git - Tutorial

1.6. Branching and merging


Git supports branching which means that you can work on different versions of your collection of files. A branch separates these different versions and allows the user to switch between these version to work on them. 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.

1.7. Working tree


The user works on a collection of files which may originate from a certain point in time of the repository. The user may also create new files or change and delete existing ones. The current collection of files is called the working tree. A standard Git repository contains the working tree (single checkout of one version of the project) and the full history of the repository. You can work in this working tree by modifying content and committing the changes to the Git repository.

1.8. How to add changes to your Git repository


If you modify your working tree, e.g. by creating a new file or by changing an existing file, you need to perform two steps in Git to persist the changes in the Git repository. You first add selected files to the staging area and afterwards you commit the changes of the staging area to the Git repository.

1.9. Adding to the staging area Note


The staging area term is currently preferred by the Git community over the old index term. Both terms mean the same thing.

You need to mark changes in the working tree to be relevant for Git. This process is called staging or to add changes to the staging area . You add changes in the working tree to the staging area with the g i ta d dcommand. This command stores a snapshot of the specified files in the staging area . The g i ta d dcommand allows you to incrementally modify files, stage them, modify and stage them again until you are satisfied with your changes.

1.10. Committing to the repository


After adding the selected files to the staging area , you can commit these files to permanently add them to the Git repository. Committing creates a new persistent snapshot (called commit or commit object) of the complete working tree in the Git repository. A commit object, like all objects in Git, are immutable.
www.vogella.com/tutorials/Git/article.html 7/58

3/6/14

Git - Tutorial

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 g i tc o m m i tcommand. This process is depicted in the following graphic.

1.11. Committing and commit objects


If you commit changes to your Git repository, you create a new commit object in the Git repository. This commit object is addressable via a SHA-1 checksum. This checksum is 40 bytes long and is a secure hash of the content of the files, the content of the directories, the complete history of up to the new commit, the committer and several other factors. This means that Git is safe, you cannot manipulate a file in the Git repository without Git noticing that SHA-1 checksum does not fit anymore to the content. The commit object points to the individual files in this commit via a tree object. The files are stored in the Git repository as blob objects and might be packed by Git for better performance and more compact storage. Blobs are addressed via their SHA-1 hash. Packing involves storing changes as deltas, compression and storage of many objects in a single pack file. Pack files are accompanied by one or multiple index files which speedup access to individual objects stored in these packs. A commit object is depicted in the following picture.

www.vogella.com/tutorials/Git/article.html

8/58

3/6/14

Git - Tutorial

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. 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

www.vogella.com/tutorials/Git/article.html

9/58

3/6/14

Git - Tutorial
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 HEAD is a symbolic reference most often pointing to the currently checked out branch. 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 Index is an alternative term for the staging area. 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 book 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. 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). 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. 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.

Staging area

Tags

Working tree

3.2. File states in Git


A file in the working tree of a Git repository can have different states. These states are the following: untracked: the file is not tracked by the Git repository, this means it was neither staged, i.e. added to the staging area nor committed tracked: committed and not staged staged: staged to be included in the next commit dirty / modified: the file has changed but the change is not staged

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.
www.vogella.com/tutorials/Git/article.html 10/58

3/6/14

Git - Tutorial

[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.

4.2. Commit ranges with the double dot operator


You can also specify ranges of commits. This is useful for certain Git commands, for example, for seeing the changes between a series of commits. The double dot operator allows you to select all commits which are reachable from a commit c2 but not from commit c1. The syntax for this is "c1..c2". A commit A is reachable from another commit B if A is a direct or indirect predecessor of B.

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.
g i tl o gH E A D ~ 4 . . H E A D

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.
g i tl o gt e s t i n g . . m a s t e r

You can also list all commits which are in the "testing" but not in the "master" branch.
g i tl o gm a s t e r . . t e s t i n g

4.3. Commit ranges with the triple dot operator


The triple dot operator allows you to select all commits which are reachable either from commit c1 or commit c2 but not from both of them. This is useful to show all commits in two branches which have not yet been combined.
#s h o wa l lc o m m i t sw h i c h #c a nb er e a c h e db ym a s t e ro rt e s t i n g #b u tn o tb o t h g i tl o gm a s t e r . . . t e s t i n g

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:
s u d oa p t g e ti n s t a l lg i t

5.2. Fedora, Red Hat and derived systems


www.vogella.com/tutorials/Git/article.html 11/58

3/6/14

Git - Tutorial

On Fedora, Red Hat and similar systems you can install the Git command line tool via the following command:
y u mi n s t a l lg i t

5.3. Other Linux systems


To install Git on other Linux distributions please check the documentation of your distribution. The following listing contains the commands for the most popular ones.
#A r c hL i n u x p a c m a nSg i t #G e n t o o e m e r g ea vg i t #S U S E z y p p e ri n s t a l lg i t

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.
h t t p : / / m s y s g i t . g i t h u b . i o /

5.5. Mac OS
The easiest way to install Git on a Mac is via a graphical installer. This installer can be found under the following URL.
h t t p : / / c o d e . g o o g l e . c o m / p / g i t o s x i n s t a l l e r

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 . g i t c o n f i gfile 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 g i tc o n f i gcommand. In each Git repository you can also configure the settings for this repository. Global configuration is done if you include the g l o b a lflag, otherwise your configuration is specific for the current Git repository. You can also setup system wide configuration. Git stores theses values is in the / e t c / g i t c o n f i gfile, 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 s y s t e m 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.

6.2. User Configuration


Configure your user and email for Git via the following command.
www.vogella.com/tutorials/Git/article.html 12/58

3/6/14

Git - Tutorial
#c o n f i g u r et h eu s e rw h i c hw i l lb eu s e db yg i t #O fc o u r s ey o us h o u l du s ey o u rn a m e g i tc o n f i gg l o b a lu s e r . n a m e" E x a m p l eS u r n a m e " #S a m ef o rt h ee m a i la d d r e s s g i tc o n f i gg l o b a lu s e r . e m a i l" y o u r . e m a i l @ g m a i l . c o m "

6.3. Push configuration


The following command configure Git so that the g i tp u s hcommand pushes only the active branch (in case it is connected to a remote branch, i.e.configured as remote tracking branches) to your Git remote repository. As of Git version 2.0 this is the default and therefore it is good practice to configure this behavior.
#s e td e f a u l ts ot h a to n l yt h ec u r r e n tb r a n c hi sp u s h e d g i tc o n f i gg l o b a lp u s h . d e f a u l ts i m p l e #a l t e r n a t i v e l yc o n f i g u r eG i tt op u s ha l lm a t c h i n gb r a n c h e s #g i tc o n f i gg l o b a lp u s h . d e f a u l tm a t c h i n g

You learn about the push command in Section 13.2, Push changes to another repository.

6.4. Avoid merge commits for pulling


If you pull in changes from a remote repository, Git by default creates merge commits if you pull in divergent changes. This may not be desired and you can avoid this via the following setting.
#s e td e f a u l ts ot h a ty o ua v o i du n n e c e s s a r yc o m m i t s g i tc o n f i gg l o b a lb r a n c h . a u t o s e t u p r e b a s ea l w a y s

Note
This setting depends on the individual workflow. Some teams prefer to create merge commits, but the author of this book likes to avoid them.

6.5. Color Highlighting


The following commands enables color highlighting for Git in the console.
g i tc o n f i gg l o b a lc o l o r . u it r u e g i tc o n f i gg l o b a lc o l o r . s t a t u sa u t o g i tc o n f i gg l o b a lc o l o r . b r a n c ha u t o

6.6. Setting the default editor


By default Git uses the system default editor which is taken from the VISUAL or EDITOR environment variables if set. You can configure a different one via the following setting.
#s e t u pv i ma sd e f a u l te d i t o rf o rG i t( L i n u x ) g i tc o n f i gg l o b a lc o r e . e d i t o rv i m

6.7. Setting the default merge tool


Git does not provide a default merge tool for integrating conflicting changes into your working tree. You have to use third party visual merge tools like tortoisemerge, p4merge, kdiff3 etc. A Google search for these tools help you to install them on your platform. Once you have installed them you can set your selected tool as default merge tool with the following command.
#s e t u pk d i f f 3a sd e f a u l tm e r g et o o l( L i n u x ) g i tc o n f i gg l o b a lm e r g e . t o o lk d i f f 3

www.vogella.com/tutorials/Git/article.html

13/58

3/6/14
#t oi n s t a l li tu n d e rU b u n t uu s e s u d oa p t g e ti n s t a l lk d i f f 3

Git - Tutorial

6.8. More settings


All possible Git settings are described under the following link: git-config manual page

6.9. Query Git settings


To query your Git settings of the local repository, execute the following command:
g i tc o n f i gl i s t

If you want to query the global settings you can use the following command.
g i tc o n f i gg l o b a ll i s t

7. Setup rules for ignoring files and directories


7.1. Creating a .gitignore file for your repository
Git can be configured to ignore certain files and directories. This is configured in a . g i t i g n o r efile. This file can be in any directory and can contain patterns for files. You can use certain wildcards in this file. *matches several characters. The ?parameter matches one character. More patterns are possible and described under the following URL: gitignore manpage For example, the following . g i t i g n o r efile tells Git to ignore the b i nand t a r g e tdirectories and all files ending with a ~.
#i g n o r ea l lb i nd i r e c t o r i e s #m a t c h e s" b i n "i na n ys u b f o l d e r b i n / #i g n o r ea l lt a r g e td i r e c t o r i e s t a r g e t / #i g n o r ea l lf i l e se n d i n gw i t h~ * ~

You can create the . g i t i g n o r efile 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 . g i t i g n o r efile. You can use the g i tr mrc a c h e d [ f i l e n a m e ]command to remove existing files from a Git repository.

Tip
The . g i t i g n o r efile 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 f o r c eparameter, i.e. with the g i ta d df o r c e[ f i l e n a m e ]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.

www.vogella.com/tutorials/Git/article.html

14/58

3/6/14

Git - Tutorial

7.2. Global (cross-repository) .gitignore settings


You can also setup a global . g i t i g n o r efile valid for all Git repositories via the c o r e . e x c l u d e s f i l e setting. The setup of this setting is demonstrated in the following code snippet.
#C r e a t ea~ / . g i t i g n o r ei ny o u ru s e rd i r e c t o r y c d~ / t o u c h. g i t i g n o r e #E x c l u d eb i na n d. m e t a d a t ad i r e c t o r i e s e c h o" b i n "> >. g i t i g n o r e e c h o" . m e t a d a t a "> >. g i t i g n o r e e c h o" * ~ "> >. g i t i g n o r e e c h o" t a r g e t / "> >. g i t i g n o r e #C o n f i g u r eG i tt ou s et h i sf i l e #a sg l o b a l. g i t i g n o r e g i tc o n f i gg l o b a lc o r e . e x c l u d e s f i l e~ / . g i t i g n o r e

The local . g i t i g n o r efile can be committed into the Git repository and therefore is visible to everyone who clones the repository. The global . g i t i g n o r efile is only locally visible.

7.3. Local per-repository ignore rules


You can also create local per-repository rules by editing the . g i t / i n f o / e x c l u d efile in your repository. These rules are not committed with the repository so they are not shared with others. This allows you to exclude, for example, locally generated files.

8. Tracking empty directories with .gitkeep


Git ignores empty directories, i.e. it does not put them under version control. If you want to track such a directory, it is a common practice to put a file called . g i t k e e pin the directory. The file could be called anything; Git assigns no special significance to this name. As the directory now contains a file, Git includes it into its version control mechanism.

Tip
One problem with this approach is that . g i t k e e pis unlikely to be ignored by version control systems or build agents, resulting in . g i t k e e pbeing copied to the output repository. One possible alternative is to create a . g i t k e e pfile 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.

9. Getting started with Git


9.1. Target of this chapter
In this chapter you create a few files, create a local Git repository and commit your files into this repository. The comments (marked with #) before the commands explain the specific actions. Open a command shell for the operations.

9.2. Create directory


The following commands create an empty directory which you will use as Git repository.
#s w i t c ht oh o m e c d~ / #c r e a t ead i r e c t o r ya n ds w i t c hi n t oi t m k d i r~ / r e p o 0 1

www.vogella.com/tutorials/Git/article.html

15/58

3/6/14
c dr e p o 0 1 #c r e a t ean e wd i r e c t o r y m k d i rd a t a f i l e s

Git - Tutorial

9.3. Create Git repository


The following explanation is based on a non-bare repository. See Section 3, Terminology for the difference between a bare repository and a non-bare repository with a working tree. Every Git repository is stored in the . g i tfolder of the directory in which the Git repository has been created. This directory contains the complete history of the repository. The . g i t / c o n f i gfile contains the configuration for the repository. The following command creates a Git repository in the current directory.
#I n i t i a l i z et h eG i tr e p o s i t o r y #f o rt h ec u r r e n td i r e c t o r y g i ti n i t

All files inside the repository folder excluding the . g i tfolder are the working tree for a Git repository.

9.4. Create content


The following commands create some files with some content that will be placed under version control.
#s w i t c ht oy o u rn e wr e p o s i t o r y c d~ / r e p o 0 1 #c r e a t ea n o t h e rd i r e c t o r y t o u c hd a t a f i l e s / d a t a . t x t #c r e a t eaf e wf i l e sw i t hc o n t e n t l s>t e s t 0 1 e c h o" b a r ">t e s t 0 2 e c h o" f o o ">t e s t 0 3

9.5. See the current status of your repository


The g i ts t a t u scommand shows the working tree status, i.e. which files have changed, which are staged and which are not part of the staging area. It also shows which files have merge conflicts and gives an indication what the user can do with these changes, e.g. add them to the staging area or remove them, etc. Run it via the following command.
g i ts t a t u s

9.6. Add files to the staging area


Before committing change to a Git repository you need to mark the changes that should be committed. This is done by adding the new and changed files to the staging area. This creates a snapshot of the affected files.

Note
In case you change one of the files again before committing, you need to add it again to the staging area to commit the new changes.

#a d da l lf i l e st ot h ei n d e xo ft h e #G i tr e p o s i t o r y g i ta d d.

Afterwards run the g i ts t a t u scommand again to see the current status.


www.vogella.com/tutorials/Git/article.html 16/58

3/6/14

Git - Tutorial

9.7. Commit to Git repository


After adding the files to the Git staging area, you can commit them to the Git repository. This creates a new commit object with the staged changes in the Git repository and the HEAD reference points to the new commit. The mparameter allows you to specify the commit message. If you leave this parameter out, your default editor is started and you can enter the message in the editor.
#c o m m i ty o u rf i l et ot h el o c a lr e p o s i t o r y g i tc o m m i tm" I n i t i a lc o m m i t "

10. Looking at the result


10.1. Results
The Git operations you performed have created a local Git repository in the . g i tfolder and added all files to this repository via one commit. Run the g i tl o gcommand
#s h o wt h eG i tl o gf o rt h ec h a n g e g i tl o g

You see an output similar to the following.


c o m m i te 7 4 4 d 6 b 2 2 a f e 1 2 c e 7 5 c b d 1 b 6 7 1 b 5 8 d 6 7 0 3 a b 8 3 f 5 A u t h o r :L a r sV o g e l< L a r s . V o g e l @ g m a i l . c o m > D a t e : M o nF e b2 51 1 : 4 8 : 5 02 0 1 3+ 0 1 0 0 I n i t i a lc o m m i t

10.2. Directory structure


Your directory contains the Git repository as well as the Git working tree for your files. This directory structure is depicted in the following screenshot.

11. Remove files and adjust the last commit


11.1. Remove files
If you delete a file which is under version control, g i ta d d .does not record this file deletion. You can use the g i tr mcommand to delete the file from your working tree and record the deletion of the file in the staging area.
#C r e a t eaf i l ea n dc o m m i ti t t o u c hn o n s e n s e 2 . t x t g i ta d d. g i tc o m m i tm" m o r en o n s e n s e "

www.vogella.com/tutorials/Git/article.html

17/58

3/6/14

Git - Tutorial
#r e m o v et h ef i l ea n dr e c o r dt h ed e l e t i o ni nG i t g i tr mn o n s e n s e 2 . t x t #c o m m i tt h er e m o v a l g i tc o m m i tm" R e m o v e sn o n s e n s e 2 . t x tf i l e "

Tip
Alternatively to the g i tr mcommand you can use the g i tc o m m i tcommand with the aflag or the Aflag in the g i ta d dcommand. This flag adds changes of files known by the Git repository to the commit in case of the g i tc o m m i t command. In case of the g i ta d dcommand it adds all file changes including deletions to the staging area. For this test, commit a new file and remove it afterwards.
#c r e a t eaf i l ea n dp u ti tu n d e rv e r s i o nc o n t r o l t o u c hn o n s e n s e . t x t g i ta d d. g i tc o m m i tm" an e wf i l eh a sb e e nc r e a t e d " #r e m o v et h ef i l e r mn o n s e n s e . t x t #s h o ws t a t u s ,o u t p u tl i s t e db e l o wt h ec o m m a n d g i ts t a t u s #o nb r a n c hm a s t e r #C h a n g e sn o ts t a g e df o rc o m m i t : # ( u s e" g i ta d d / r m< f i l e > . . . "t ou p d a t ew h a tw i l lb ec o m m i t t e d ) # ( u s e" g i tc h e c k o u t-< f i l e > . . . "t od i s c a r dc h a n g e si nw o r k i n gd i r e c t o r y ) # # d e l e t e d : n o n s e n s e . t x t # #n oc h a n g e sa d d e dt oc o m m i t( u s e" g i ta d d "a n d / o r" g i tc o m m i t a " ) #t r ys t a n d a r dw a yo fc o m m i t t i n g>w i l lN O Tw o r k #o u t p u to ft h ec o m m a n dl i s t e db e l o w g i ta d d. g i tc o m m i tm" f i l eh a sN O Tb e e nr e m o v e d " #O nb r a n c hm a s t e r #C h a n g e sn o ts t a g e df o rc o m m i t : # ( u s e" g i ta d d / r m< f i l e > . . . "t ou p d a t ew h a tw i l lb ec o m m i t t e d ) # ( u s e" g i tc h e c k o u t-< f i l e > . . . "t od i s c a r dc h a n g e si nw o r k i n gd i r e c t o r y ) # # d e l e t e d : n o n s e n s e . t x t # #n oc h a n g e sa d d e dt oc o m m i t( u s e" g i ta d d "a n d / o r" g i tc o m m i t a " )

After validating that this command does not remove the file from the Git repository you can use the aparameter. Be aware that the aadds other changes, too.
#c o m m i tt h er e m o v ew i t ht h eaf l a g g i tc o m m i tam" F i l en o n s e n s e . t x ti sn o wr e m o v e d " #a l t e r n a t i v e l yy o uc o u l da d dd e l e t e df i l e st ot h es t a g i n ga r e a v i a #g i ta d dA. #g i tc o m m i tm" F i l en o n s e n s e . t x ti sn o wr e m o v e d "

11.2. Remove a file from the staging area


You can use the g i tr e s e t[ f i l e n a m e ]command to remove a file from the staging area, which you added with g i ta d d[ f i l e n a m e ] . Removing a file from the staging area, avoids that it included in the next commit.
www.vogella.com/tutorials/Git/article.html 18/58

3/6/14
#c r e a t eaf i l ea n da d dt oi n d e x t o u c hu n w a n t e d s t a g e d . t x t g i ta d du n w a n t e d s t a g e d . t x t #r e m o v ei tf r o mt h ei n d e x g i tr e s e tu n w a n t e d s t a g e d . t x t #t oc l e a n u p ,d e l e t ei t r mu n w a n t e d s t a g e d . t x t

Git - Tutorial

11.3. Correct the last commit with git amend


The g i ta m e n dcommand makes it possible to replace the last commit. This allows you to change the last commit including the commit message.

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 a m e n dparameter.
#a s s u m ey o uh a v es o m e t h i n gt oc o m m i t g i tc o m m i tm" m e s s a g ew i t hat p y oh e r e "

g i tc o m m i ta m e n dm" M o r ec h a n g e s-n o wc o r r e c t "

You should use the g i ta m e n dcommand only for commits which have not been pushed to a public branch of another Git repository. The g i ta m e n dcommand 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.

11.4. Remove files based on .gitignore changes


Sometimes you change your . g i t i g n o r e file. Git will stop tracking the new entries from this moment. The last version is still in the Git repository. If you want to remove the last version of the files from your Git repository, you need to do this explicitly via the following command.
#R e m o v ed i r e c t o r y. m e t a d a t af r o mg i tr e p o g i tr mrc a c h e d. m e t a d a t a #R e m o v ef i l et e s t . t x tf r o mr e p o g i tr mc a c h e dt e s t . t x t

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 g i tf i l t e r b r a n c h which allows you to rewrite the commit history. See Section 43.1, Using git filterbranch for details.

12. Remote repositories


12.1. What are remotes?
Remotes are URLs in a Git repository to other remote repositories that are hosted on the Internet, locally or in the network.
www.vogella.com/tutorials/Git/article.html 19/58

3/6/14

Git - Tutorial

Such remotes can be used to synchronize the changes of several Git repositories. A local Git repository can be connected to multiple remote repositories and you can synchronize your local repository with them via Git operations.

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 always available.

Tip
A remote repository can also be hosted in the local file system.

12.2. Bare repositories


A remote repository on a server typically does not require a working tree. A Git repository without a working tree is called a bare repository. You can create such a repository with the b a r eoption. The command to create a new empty bare remote repository is displayed below.
#c r e a t eab a r er e p o s i t o r y g i ti n i tb a r e

By convention the name of a bare repository should end with the . g i textension.

12.3. Setting up a bare Git repository


In this section you create a bare Git repository. In order to simplify the following examples, the Git repository is hosted locally in the filesystem and not on a server in the Internet.

Note
www.vogella.com/tutorials/Git/article.html 20/58

3/6/14

Git - Tutorial

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.
#s w i t c ht ot h ef i r s tr e p o s i t o r y c d~ / r e p o 0 1 #c r e a t ean e wb a r er e p o s i t o r yb yc l o n i n gt h ef i r s to n e g i tc l o n eb a r e.. . / r e m o t e r e p o s i t o r y . g i t #c h e c kt h ec o n t e n to ft h eg i tr e p o ,i ti ss i m i l a r #t ot h e. g i td i r e c t o r yi nr e p o 0 1 #f i l e sm i g h tb ep a c k e di nt h eb a r er e p o s i t o r y l s~ / r e m o t e r e p o s i t o r y . g i t

Tip
You can convert a normal Git repository into a bare repository by moving the content of the . g i tfolder 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 g i tc o n f i gc o r e . b a r et r u ecommand. 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 b a r eoption should be preferred.

12.4. Cloning and the remote called "origin"


If you clone a repository, Git implicitly creates a remote named origin by default. The origin remote links back to the cloned repository. If you create a Git repository from scratch with the g i ti n i tcommand, the origin remote is not created automatically.

12.5. Adding more remote repositories


You add more remotes to your repository with the g i tr e m o t ea d d command. You created a new Git repository from scratch earlier. Use the following command to add a pointer to your new bare repository using the origin name.
#A d d. . / r e m o t e r e p o s i t o r y . g i tw i t ht h en a m eo r i g i n g i tr e m o t ea d do r i g i n. . / r e m o t e r e p o s i t o r y . g i t

12.6. Synchronizing with remote repositories


You can synchronize your local Git repository with remote repositories. These commands are covered in detail in later sections but the following command demonstrates how you can send changes to your remote repository.
#d os o m ec h a n g e s e c h o" Ia d d e dar e m o t er e p o ">t e s t 0 2 #c o m m i t g i tc o m m i tam" T h i si sat e s tf o rt h en e wr e m o t eo r i g i n " #t op u s hu s et h ec o m m a n d : #g i tp u s h[ t a r g e t ] #d e f a u l tf o r[ t a r g e t ]i so r i g i n g i tp u s ho r i g i n

www.vogella.com/tutorials/Git/article.html

21/58

3/6/14

Git - Tutorial

12.7. Show the existing remotes


To see the existing definitions of the remote repositories, use the following command.
#s h o wt h ed e t a i l so ft h er e m o t er e p oc a l l e do r i g i n g i tr e m o t es h o wo r i g i n

To see the details of the remotes, e.g. the URL use the following command.
#s h o wt h ee x i s t i n gd e f i n e dr e m o t e s g i tr e m o t e #s h o wd e t a i l sa b o u tt h er e m o t e s g i tr e m o t ev

13. Cloning remote repositories and push and pull


13.1. Clone your repository
Clone a repository and checkout a working tree in a new directory via the following commands.
#S w i t c ht oh o m e c d~ #M a k en e wd i r e c t o r y m k d i rr e p o 0 2 #S w i t c ht on e wd i r e c t o r y c d~ / r e p o 0 2 #C l o n e g i tc l o n e. . / r e m o t e r e p o s i t o r y . g i t.

13.2. Push changes to another repository


The g i tp u s hcommand allows you to send data to other repositories. By default it sends data from your current branch to the same branch of the remote repository. See Section 16.6, Push changes of a branch to a remote repository for details on pushing branches or Git push manpage for general information. Make some changes in your local repository and push them from your first repository to the remote repository via the following commands.
#M a k es o m ec h a n g e si nt h ef i r s tr e p o s i t o r y c d~ / r e p o 0 1 #M a k es o m ec h a n g e si nt h ef i l e e c h o" H e l l o ,h e l l o .T u r ny o u rr a d i oo n ">t e s t 0 1 e c h o" B y e ,b y e .T u r ny o u rr a d i oo f f ">t e s t 0 2 #C o m m i tt h ec h a n g e s ,aw i l lc o m m i tc h a n g e sf o rm o d i f i e df i l e s #b u tw i l ln o ta d da u t o m a t i c a l l yn e wf i l e s g i tc o m m i tam" S o m ec h a n g e s " #P u s ht h ec h a n g e s g i tp u s h. . / r e m o t e r e p o s i t o r y . g i t

Note
By default you can only push to bare repositories (repositories without working tree). Also you can only push a change to a remote repository which results in a fast-forward merge. See Section 34, Merging to learn about fast-forward merges.

13.3. Pull changes


www.vogella.com/tutorials/Git/article.html 22/58

3/6/14

Git - Tutorial

The g i tp u l lcommand allows you to get the latest changes from another repository for the current branch. To test this in your example Git repositories, switch to your second repository, pull in the recent changes in the remote repository, make some changes, push them to your remote repository via the following commands.
#s w i t c ht os e c o n dd i r e c t o r y c d~ / r e p o 0 2 #p u l li nt h el a t e s tc h a n g e so fy o u rr e m o t er e p o s i t o r y g i tp u l l #m a k ec h a n g e s e c h o" Ac h a n g e ">t e s t 0 1 #c o m m i tt h ec h a n g e s g i tc o m m i tam" Ac h a n g e " #p u s hc h a n g e st or e m o t er e p o s i t o r y #o r i g i ni sa u t o m a t i c a l l yc r e a t e da sw ec l o n e do r i g i n a lf r o mt h i sr e p o s i t o r y g i tp u s ho r i g i n

You can pull in the changes in your first example repository with the following commands.
#s w i t c ht ot h ef i r s tr e p o s i t o r ya n dp u l li nt h ec h a n g e s c d~ / r e p o 0 1 g i tp u l l. . / r e m o t e r e p o s i t o r y . g i t / #c h e c kt h ec h a n g e s g i ts t a t u s

Tip
The g i tp u l lcommand is actually a shortcut for g i tf e t c hfollowed by the
g i tm e r g eor g i tr e b a s ecommand depending on your configuration. In

Section 6.4, Avoid merge commits for pulling you configured your Git repository so that g i tp u l lis a fetch followed by a rebase. See Section 33.1, Fetch for more information about the fetch command.

14. Online remote repositories


14.1. Cloning online repositories
Git supports several transport protocols to connect to other Git repositories; the native protocol for Git is also called g i t . The following command clones an existing repository using the Git protocol. The Git protocol uses the port 9148 which might be blocked by firewalls.
#s w i t c ht oan e wd i r e c t o r y m k d i r~ / o n l i n e c d~ / o n l i n e #c l o n eo n l i n er e p o s i t o r y g i tc l o n eg i t : / / g i t h u b . c o m / v o g e l l a / g i t b o o k . g i t

If you have ssh access to a Git repository, you can also use the s s hprotocol. The name preceding @ is the user name used for the ssh connection.
#c l o n eo n l i n er e p o s i t o r y

www.vogella.com/tutorials/Git/article.html

23/58

3/6/14

Git - Tutorial
g i tc l o n es s h : / / g i t @ g i t h u b . c o m / v o g e l l a / g i t b o o k . g i t #o l d e rs y n t a x g i tc l o n eg i t @ g i t h u b . c o m : v o g e l l a / g i t b o o k . g i t

Alternatively you could clone the same repository via the h t t pprotocol.
#T h ef o l l o w i n gw i l lc l o n ev i aH T T P g i tc l o n eh t t p : / / v o g e l l a @ g i t h u b . c o m / v o g e l l a / g i t b o o k . g i t

14.2. Add more remote repositories


As discussed earlier cloning repository creates a remote called o r i g i npointing to the remote repository which you cloned from. You can push changes to this origin repository via g i tp u s has Git uses o r i g i nas default. Of course, pushing to a remote repository requires write access to this repository. You can add more remotes via the g i tr e m o t ea d d[ n a m e ][ U R L _ t o _ G i t _ r e p o ] command. For example, if you cloned the repository from above via the Git protocol, you could add a new remote with the name github_http for the http protocol via the following command.
#A d dt h eh t t p sp r o t o c o l g i tr e m o t ea d dg i t h u b _ h t t ph t t p s : / / v o g e l l a @ g i t h u b . c o m / v o g e l l a / g i t b o o k . g i t

14.3. Rename remote repositories


To rename an existing remote repository use the g i tr e m o t er e n a m ecommand. This is demonstrated by the following listing.
#r e n a m et h ee x i s t i n gr e m o t er e p o s i t o r yf r o m #g i t h u b _ h t t pt og i t h u b _ t e s t i n g g i tr e m o t er e n a m eg i t h u b _ h t t pg i t h u b _ t e s t i n g

14.4. Remote operations via http and a proxy


It is possible to use the HTTP protocol to clone Git repositories. This is especially helpful if your firewall blocks everything except http or https. Git also provides support for http access via a proxy server. The following Git command could, for example, clone a repository via http and a proxy. You can either set the proxy variable in general for all applications or set it only for Git. This example uses environment variables.
#L i n u x e x p o r th t t p _ p r o x y = h t t p : / / p r o x y : 8 0 8 0 e x p o r th t t p s _ p r o x y = h t t p s : / / p r o x y : 8 4 4 3 #W i n d o w s s e th t t p _ p r o x yh t t p : / / p r o x y : 8 0 8 0 s e th t t p s _ p r o x yh t t p : / / p r o x y : 8 0 8 0 g i tc l o n eh t t p : / / d e v . e c l i p s e . o r g / g i t / o r g . e c l i p s e . j f a c e / o r g . e c l i p s e . j f a c e . s n i p p e t s . g i t

Note
For secured SSL encrypted communication you should use the ssh or https protocol in order to guarantee security.

This example uses the following Git config settings.


#s e tp r o x yf o rg i tg l o b a l l y g i tc o n f i gg l o b a lh t t p . p r o x yh t t p : / / p r o x y : 8 0 8 0

www.vogella.com/tutorials/Git/article.html

24/58

3/6/14

Git - Tutorial
#t oc h e c kt h ep r o x ys e t t i n g s g i tc o n f i gg e th t t p . p r o x y #j u s ti nc a s ey o un e e dt oy o uc a na l s or e v o k et h ep r o x ys e t t i n g s g i tc o n f i gg l o b a lu n s e th t t p . p r o x y

Tip
Git is able to store different proxy configurations for different domains, see
c o r e . g i t P r o x yin Git

config manpage.

15. What are branches?


Git allows you to create branches, i.e. named pointers to commits. You can work on different branches independently from each other. The default branch is most often called master. A branch pointer in Git is 41 bytes large, 40 bytes of characters and an additional new line character. Therefore the creating of branches in Git is very fast and cheap in terms of resource consumption. Git encourages the usage of branches on a regular basis. If you decide to work on a branch, you checkout this branch. This means that Git populates the 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.

16. Commands to working with branches


16.1. List available branches
The g i tb r a n c hcommand lists all local branches. The currently active branch is marked with * .
#l i s t sa v a i l a b l eb r a n c h e s g i tb r a n c h

If you want to see all branches (including remote tracking branches), use the afor the g i tb r a n c h command. See Section 32.1, Remote tracking branches for information about remote tracking branches.
#l i s t sa l lb r a n c h e si n c l u d i n gt h er e m o t eb r a n c h e s g i tb r a n c ha

The voption lists more information about the branches. In order to list branches or tags in a remote repository use the g i tl s r e m o t ecommand as demonstrated in the following example.
#l i s t sb r a n c h e sa n dt a g si nt h e #r e m o t er e p o s i t o r yc a l l e do r i g i n g i tl s r e m o t eo r i g i n

16.2. Create new branch


You can create a new branch via the g i tb r a n c h[ n e w n a m e ]command. This command allows to specify the starting point (commit id, tag, remote or local branch). If not specified the commit to which the HEAD reference points is used to create the branch.
#S y n t a x :g i tb r a n c h< n a m e >< h a s h > #< h a s h >i nt h ea b o v ei so p t i o n a l g i tb r a n c ht e s t i n g

16.3. Checkout branch


www.vogella.com/tutorials/Git/article.html 25/58

3/6/14

Git - Tutorial

To start working in a branch you have to checkout the branch. If you checkout a branch, the HEAD pointer moves to the last commit in this branch and the files in the working tree are set to the state of this commit. The following commands demonstrates how you switch to the branch called testing, perform some changes in this branch and switch back to the branch called master.
#s w i t c ht oy o u rn e wb r a n c h g i tc h e c k o u tt e s t i n g #d os o m ec h a n g e s e c h o" C o o ln e wf e a t u r ei nt h i sb r a n c h ">t e s t 0 1 g i tc o m m i tam" n e wf e a t u r e " #s w i t c ht ot h em a s t e rb r a n c h g i tc h e c k o u tm a s t e r #c h e c kt h a tt h ec o n t e n to f #t h et e s t 0 1f i l ei st h eo l do n e c a tt e s t 0 1

To create a branch and to switch to it at the same time you can use the g i tc h e c k o u tcommand with the bparameter.
#C r e a t eb r a n c ha n ds w i t c ht oi t g i tc h e c k o u tbb u g r e p o r t 1 2 #C r e a t e san e wb r a n c hb a s e do nt h em a s t e rb r a n c h # w i t h o u tt h el a s tc o m m i t g i tc h e c k o u tbm y b r a n c hm a s t e r ~ 1

16.4. Rename a branch


Renaming a branch can be done with the following command.
#r e n a m eb r a n c h g i tb r a n c hm[ o l d _ n a m e ][ n e w _ n a m e ]

16.5. Delete a branch


To delete a branch which is not needed anymore, you can use the following command.
#d e l e t eb r a n c ht e s t i n g g i tb r a n c hdt e s t i n g #c h e c ki fb r a n c hh a sb e e nd e l e t e d g i tb r a n c h

16.6. Push changes of a branch to a remote repository


You can push the changes in the current active branch to a remote repository by specifying the target branch. This creates the target branch in the remote repository if it does not yet exist.
#p u s hc u r r e n tb r a n c ht oab r a n c hc a l l e d" t e s t i n g "t or e m o t er e p o s i t o r y g i tp u s ho r i g i nt e s t i n g #s w i t c ht ot h et e s t i n gb r a n c h g i tc h e c k o u tt e s t i n g #s o m ec h a n g e s e c h o" N e w sf o ry o u ">t e s t 0 1 g i tc o m m i tam" n e wf e a t u r ei nb r a n c h " #p u s ha l li n c l u d i n gb r a n c h g i tp u s h

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.

www.vogella.com/tutorials/Git/article.html

26/58

3/6/14

Git - Tutorial

17. Differences between branches


To see the difference between two branches you can use the following command.
#s h o w st h ed i f f e r e n c e sb e t w e e n #c u r r e n th e a do fm a s t e ra n dy o u r _ b r a n c h g i td i f fm a s t e ry o u r _ b r a n c h

You can also use commit 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.
#s h o w st h ed i f f e r e n c e si ny o u r #b r a n c hb a s e do nt h ec o m m o n #a n c e s t o rf o rb o t hb r a n c h e s g i td i f fm a s t e r . . . y o u r _ b r a n c h

See Section 22, Viewing changes with git diff and git show for more examples of the g i td i f f command.

18. Tags in Git


18.1. What are tags?
Git has the option to tag a commit in the repository history so that you find it easier at a later point in time. Most commonly, this is used to tag a certain version which has been released. If you tag a commit, you create an annotated or lightweight tag.

18.2. Lightweight and annotated tags


Git supports two different types of tags, lightweight and annotated tags. A lightweight tag is a pointer to a commit, without any additional information about the tag. An 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).

19. Tagging in Git


19.1. List tags
You can list the available tags via the following command:
g i tt a g

19.2. Search by pattern for a tag


You can use the lparameter in the g i tt a gcommand to search for a pattern in the tag.
g i tt a gl< p a t t e r n >

19.3. Creating lightweight tags


To create a lightweight tag don't use the m ,aor soption. Lightweight tags are often used for build tags which do not need additional information other than the build number or the timestamp.
#c r e a t el i g h t w e i g h tt a g

www.vogella.com/tutorials/Git/article.html

27/58

3/6/14
g i tt a g1 . 7 . 1 #S e et h et a g g i ts h o w1 . 7 . 1

Git - Tutorial

19.4. Creating annotated tags


You can create a new annotated tag via the g i tt a gacommand. An annotated tag can also be created using the m parameter, which is used to specify the description of the tag. The following command tags the current active HEAD.
#c r e a t et a g g i tt a g1 . 6 . 1m' R e l e a s e1 . 6 . 1 ' #s h o wt h et a g g i ts h o w1 . 6 . 1

You can also create tags for a certain commit id.


g i tt a g1 . 5 . 1m' v e r s i o n1 . 5 '[ c o m m i ti d ]

19.5. Signed tags


You can use the option sto create a signed tag. These tags are signed with GNU Privacy Guard (GPG) and can also be verified with GPG. For details on this please see the following URL: Git tag manpage.

19.6. Checkout tags


If you want to use the code associated with the tag, use:
g i tc h e c k o u t< t a g _ n a m e >

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.

19.7. Push tags


By default the g i tp u s hcommand does not transfer tags to remote repositories. You explicitly have to push the tag with the following command.
#p u s hat a go rb r a n c hc a l l e dt a g n a m e g i tp u s ho r i g i n[ t a g n a m e ] #t oe x p l i c i t l yp u s hat a ga n dn o tab r a n c h g i tp u s ho r i g i nt a g< t a g n a m e >

19.8. Delete tags


You can delete tags with the dparameter. This deletes the tag from your local repository. By default Git does not push tag deletions to a remote repository, you have to trigger that explicitly. The following commands demonstrate how to push a tag deletion.
#d e l e t et a gl o c a l l y g i tt a gd1 . 7 . 0 #d e l e t et a gi nr e m o t er e p o s i t o r y #c a l l e do r i g i n g i tp u s ho r i g i n: r e f s / t a g s / 1 . 7 . 0

www.vogella.com/tutorials/Git/article.html

28/58

3/6/14

Git - Tutorial

19.9. Naming conventions for tags


Tags are frequently used to tag the state of a release of the Git repository. In this case they are typically called release tags. Convention is that release tags are labeled based on the [major].[minor].[patch] naming scheme, for example "1.0.0". Several projects also use the "v" prefix. 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. Viewing changes in the working tree with git status


20.1. Viewing the status of the working tree with git status
The g i ts t a t u scommand shows the status of the working tree, i.e. which files have changed, which are staged and which are not part of the index. It also shows which files have merge conflicts and gives an indication what the user can do with these changes, e.g. add them to the staging area or remove them, etc.

20.2. Example
The following commands create some changes in your Git repository.
#m a k es o m ec h a n g e s m ,a s s u m e st h a tt h et e s t 0 1 #a n dt e s t 0 2f i l e se x i s t s #a n dh a v eb e e nc o m m i t t e di nt h ep a s t e c h o" T h i si san e wc h a n g et ot h ef i l e ">t e s t 0 1 e c h o" a n dt h i si sa n o t h e rn e wc h a n g e ">t e s t 0 2 #c r e a t ean e wf i l e l s>n e w f i l e a n a l y z i s . t x t

The g i ts t a t u scommand show the current status of your repository and suggest possible actions.
#s e et h ec u r r e n ts t a t u so fy o u rr e p o s i t o r y #( w h i c hf i l e sa r ec h a n g e d/n e w/d e l e t e d ) g i ts t a t u s

The output of the command looks like the following.


#O nb r a n c hm a s t e r #Y o u rb r a n c hi sa h e a do f' o r i g i n / m a s t e r 'b y1c o m m i t . # ( u s e" g i tp u s h "t op u b l i s hy o u rl o c a lc o m m i t s ) # #C h a n g e sn o ts t a g e df o rc o m m i t : # ( u s e" g i ta d d< f i l e > . . . "t ou p d a t ew h a tw i l lb ec o m m i t t e d ) # ( u s e" g i tc h e c k o u t-< f i l e > . . . "t od i s c a r dc h a n g e si nw o r k i n gd i r e c t o r y ) # # m o d i f i e d : t e s t 0 1 # m o d i f i e d : t e s t 0 2 # #U n t r a c k e df i l e s : # ( u s e" g i ta d d< f i l e > . . . "t oi n c l u d ei nw h a tw i l lb ec o m m i t t e d ) # # n e w f i l e a n a l y z i s . t x t n oc h a n g e sa d d e dt oc o m m i t( u s e" g i ta d d "a n d / o r" g i tc o m m i ta " )

21. Analyzing the repository history with git log


21.1. Using git log
www.vogella.com/tutorials/Git/article.html 29/58

3/6/14

Git - Tutorial

The g i tl o gcommands shows the history of your repository in the current branch, i.e. the list of commits.
#s h o wt h eh i s t o r yo fc o m m i t si nt h ec u r r e n tb r a n c h g i tl o g

21.2. Helpful parameters for git log


The o n e l i n eparameter fits the output of the g i tl o gcommand in one line. If you use the a b b r e v c o m m i tparameter, the g i tl o gcommand uses shorter versions of the SHA-1 identifier for a commit object but keeps the SHA-1 unique. The g r a p hparameter draws a text-based graphical representation of the branches and the merge history of the Git repository.
#u s e ss h o r t e n db u tu n i q u eS H A 1v a l u e s #f o rt h ec o m m i to b j e c t s g i tl o ga b b r e v c o m m i t #s h o wt h eh i s t o r yo fc o m m i t si no n el i n e #w i t has h o r t e n e dv e r s i o no ft h ec o m m i ti d #o n l i n ei sas h o r t h a n df o r" p r e t t y = o n e l i n ea b b r e v c o m m i t " g i tl o go n e l i n e

#s h o wt h eh i s t o r ya sg r a p hi n c l u d i n gb r a n c h e s g i tl o gg r a p ho n e l i n e

For more options on the g i tl o gcommand see the Git log manpage.

21.3. View the change history of a file


To see changes in a file you can use the poption in the g i tl o gcommand.
#g i tl o gf i l e n a m es h o w st h ec o m m i t sf o rt h i sf i l e g i tl o g[ f i l ep a t h ] #U s ept os e et h ed i f f so fe a c hc o m m i t g i tl o gpf i l e n a m e #f o l l o ws h o w st h ee n t i r eh i s t o r y #i n c l u d i n gr e n a m e s g i tl o gf o l l o wpf i l e

21.4. Find out which commit deleted a file or directory


To see which commit deleted a file you can use the following command.
#s e et h ec h a n g e so faf i l e ,w o r k se v e n #i ft h ef i l ew a sd e l e t e d g i tl o g-[ f i l ep a t h ] #l i m i tt h eo u t p u to fG i tl o gt ot h e #l a s tc o m m i t ,i . e .t h ec o m m i tw h i c hd e l e t et h ef i l e #1t os e eo n l yt h el a s tc o m m i t #u s e2t os e et h el a s t2c o m m i t se t c g i tl o g1-[ f i l ep a t h ] #i n c l u d es t a tp a r a m e t e rt os e e #s o m es t a t i c s ,e . g .h o wm a n yf i l e sw e r e #d e l e t e d g i tl o g1s t a t-[ f i l ep a t h ]

Note
The double hyphens (--) in Git separate flags from non-flags (usually filenames).

www.vogella.com/tutorials/Git/article.html

30/58

3/6/14

Git - Tutorial

21.5. See all commits of a certain user


You can use the a u t h o rtag to filter the log output by a certain author. You do not need to use the full name, if a substring matches, the commit is included in the log output. The following command lists all commits with an author name containing the word "lvogel".
g i tl o ga u t h o r = l v o g e l

22. Viewing changes with git diff and git show


22.1. See unstaged changes since the last commit
The g i td i f fcommand allows the user to see the changes made. In order to test this, make some changes to a file and check what the g i td i f fcommand shows to you. Afterwards commit the changes to the repository.
#m a k es o m ec h a n g e st ot h ef i l e e c h o" T h i si sac h a n g e ">t e s t 0 1 e c h o" a n dt h i si sa n o t h e rc h a n g e ">t e s t 0 2 #c h e c kt h ec h a n g e sv i at h ed i f fc o m m a n d g i td i f f #o p t i o n a ly o uc a na l s os p e c i f yap a t ht of i l t e rt h ed i s p l a y e dc h a n g e s #p a t hc a nb eaf i l eo rd i r e c t o r y g i td i f f[ p a t h ]

22.2. See differences between staging area and last commit


To see which changes you have staged, i.e., you are going to commit with the next commit, use the following command.
#m a k es o m ec h a n g e st ot h ef i l e g i td i f fc a c h e d

22.3. See the differences introduced by a commit


To see the changes introduced by a commit use the following command.
g i ts h o w< c o m m i t _ i d >

22.4. See the difference between two commits


To see the differences introduced between two commits you use the g i td i f fcommand specifying the commits. For example, the following command shows the differences introduced in the last commit.
g i td i f fH E A D ~ 1H E A D

22.5. See the files changed by a commit


To see the files which have been changed in a commit use the g i td i f f t r e ecommand. The n a m e o n l y tells the command to show only the names of the files.
g i td i f f t r e en a m e o n l yr< c o m m i t _ i d >

23. Analyzing line changes with git blame


The g i tb l a m ecommand allows you to see which commit and author modified a file on a per line base.

www.vogella.com/tutorials/Git/article.html

31/58

3/6/14

Git - Tutorial
#g i tb l a m es h o w st h ea u t h o ra n dc o m m i tp e r #l i n eo faf i l e g i tb l a m e[ f i l e n a m e ] #t h eLo p t i o na l l o w st ol i m i tt h es e l e c t i o n #f o re x a m p l eb yl i n en u m b e r #o n l ys h o wl i n e1a n d2i ng i tb l a m e g i tb l a m eL1 , 2[ f i l e n a m e ]

24. git shortlog for release announcements


The g i ts h o r t l o gcommand summarizes the g i tl o goutput, it groups all commits by author and includes the first line of the commit message. The soption suppresses the commit message and provides a commit count. The noption sorts the output based on the number of commits by author.
#g i v e sas u m m a r yo ft h ec h a n g e sb ya u t h o r g i ts h o r t l o g #c o m p r e s s e ds u m m a r y g i ts h o r t l o gs n

25. Stashing committed changes with git stash


25.1. The stash command
Git provides the g i ts t a s hcommand which allows you to record the current state of the working directory and the staging area and go back to the last committed revision. This allows you to pull in the latest changes or to develop an urgent fix. Afterwards you can restore the stashed changes, which will reapply the changes to the current version of the source code. In general using the stash command should be the exception in using Git. Typically you would create new branches for new features and switch between branches. You can also commit frequently in your local Git repository and use interactive rebase to combine these commits later before pushing them to another Git repository.

Tip
You can avoid using the g i ts t a s hcommand. In this case you commit the changes you want to put aside and use the g i tc o m m i ta m e n dcommand 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".

25.2. Using the Git stash command


25.2.1. Git stash example The following commands will save a stash and reapply them after some changes.
#C r e a t eas t a s hw i t hu n c o m m i t t e dc h a n g e s g i ts t a s h #T O D Od oc h a n g e st ot h es o u r c e ,e . g .b yp u l l i n g #n e wc h a n g e sf r o mar e m o t er e p o #A f t e r w a r d sr e a p p l yt h es t a s h e dc h a n g e s #a n dd e l e t et h es t a s hf r o mt h el i s to fs t a s h e s g i ts t a s hp o p

It is also possible to keep a list of stashes.


www.vogella.com/tutorials/Git/article.html 32/58

3/6/14

Git - Tutorial
#c r e a t eas t a s hw i t hu n c o m m i t t e dc h a n g e s g i ts t a s hs a v e #s e et h el i s to fa v a i l a b l es t a s h e s g i ts t a s hl i s t #R e s u l tm i g h tb es o m e t h i n gl i k e : s t a s h @ { 0 } :W I Po nm a s t e r :2 7 3 e 4 a 0R e s i z ei s s u ei nD i a l o g s t a s h @ { 1 } :W I Po nm a s t e r :2 7 3 e 4 b 0S i l l yt y p oi nC l a s s n a m e s t a s h @ { 2 } :W I Po nm a s t e r :2 7 3 e 4 c 0S i l l yt y p oi nJ a v a d o c #y o uc a nu s et h eI Dt oa p p l yas t a s h g i ts t a s ha p p l ys t a s h @ { 0 } #O ra p p l yt h el a t e s ts t a s ha n dd e l e t ei ta f t e r w a r d s g i ts t a s hp o p #a l s oy o uc a nr e m o v eas t a s h e dc h a n g e #w i t h o u ta p p l y i n gi t g i ts t a s hd r o ps t a s h @ { 0 } #o rd e l e t ea l ls t a s h e s g i ts t a s hc l e a r

25.2.2. Create branch from stash You can also create a branch for your stash if you want to continue to work on the stashed changes in a branch. This can be done with the following command.
#c r e a t ean e wb r a n c hf r o my o u rs t a c ka n d #s w i t c ht oi t g i ts t a s hb r a n c hn e w b r a n c h f o r s t a s h

26. Remove untracked files with git clean


26.1. Removing untracked files in the working tree
If you have untracked files in your working tree which you want to remove, you can use the g i tc l e a n command.

26.2. Example
The following commands demonstrates the usage of the g i tc l e a ncommand.
#C r e a t ean e wf i l ew i t hc o n t e n t e c h o" t h i si st r a s ht ob ed e l e t e d ">t e s t 0 4 #M a k ead r y r u nt os e ew h a tw o u l dh a p p e n #ni st h es a m ea sd r y r u n g i tc l e a nn #d e l e t e ,fi sr e q u i r e di f #v a r i a b l ec l e a n . r e q u i r e F o r c ei sn o ts e tt of a l s e g i tc l e a nf #u s edf l a gt od e l e t en e wd i r e c t o r i e s #u s ext od e l e t eh i d d e nf i l e s ,e . g ." . e x a m p l e " g i tc l e a nf d x

27. Revert uncommitted changes


27.1. Checkout version from the staging area
Changes in the working tree which are unstaged can be undone with g i tc h e c k o u tcommand. This command resets the file in the working tree to the last staged or committed version.
#d e l e t eaf i l e r mt e s t 0 1 #r e v e r tt h ed e l e t i o n g i tc h e c k o u t-t e s t 0 1 #n o t eg i tc h e c k o u tt e s t 0 1a l s ow o r k sb u tu s i n g #t w o-e n s u r e st h a tG i tu n d e r s t a n d st h a tt e s t 0 1

www.vogella.com/tutorials/Git/article.html

33/58

3/6/14
#i sap a t ha n dn o tap a r a m e t e r #c h a n g eaf i l e e c h o" o v e r r i d e ">t e s t 0 1 #r e s t o r et h ef i l e g i tc h e c k o u t-t e s t 0 1

Git - Tutorial

For example, you can restore a directory called d a t awith the following command.
g i tc h e c k o u t-d a t a

27.2. Checkout with staged changes


If you want to undo a staged but uncommitted change, you can still use the g i tc h e c k o u tcommand if you specify a commit pointer to use. The following demonstrates the usage of this to restore a delete directory.
#a s s u m i n gy o ud e l e t e dat r a c k e dd i r e c t o r y #a n ds t a g e dt h ec h a n g e s #r e s t o r et h ew o r k i n gt r e ea n dr e s e tt h es t a g i n ga r e a g i tc h e c k o u tH E A D-y o u r _ d i r _ t o _ r e s t o r e

The additional commit pointer parameter instructs the g i tc h e c k o u tcommand to reset the working tree and to also remove the staged changes.

27.3. Remove staged changes for new files


If you added a new file to the staging area but do not want to commit the file, you can remove it from the staging area via the g i tr e s e tf i l ecommand.
#c r e a t eaf i l ea n d #a c c i d e n t l ya d di tt ot h ei n d e x t o u c hi n c o r r e c t . t x t g i ta d d. # r e m o v ei tf r o mt h ei n d e x g i tr e s e ti n c o r r e c t . t x t #t oc l e a nu p ,d e l e t et h ef i l e #n o tn e c c e s s a r y ,m a y b ey o uw a n tt oa d di tl a t e rt ot h ei n d e x r mi n c o r r e c t . t x t

Note
To learn more about the g i tr e s e tcommand see Section 28.1, Use cases for git reset.

27.4. Remove staged changes for previously committed files


If you have added the changes of a file to the staging area, you can also revert the changes in the staging area and checkout the file from the index.
#s o m en o n s e n s ec h a n g e e c h o" c h a n g ew h i c hs h o u l db er e m o v e dl a t e r ">t e s t 0 1 #a d dt h ef i l et ot h es t a g i n ga r e a g i ta d dt e s t 0 1 #r e s t o r et h ef i l ei nt h es t a g i n ga r e a g i tr e s e tH E A Dt e s t 0 1 #g e tt h ev e r s i o nf r o mt h es t a g i n ga r e a #i n t ot h ew o r k i n gt r e e g i tc h e c k o u tt e s t 0 1

www.vogella.com/tutorials/Git/article.html

34/58

3/6/14

Git - Tutorial

Best Car Deals

Free Word Games

Chitika | Opt out?

28. Moving the HEAD pointer with git reset


28.1. Use cases for git reset
28.1.1. Moving the HEAD pointer The g i tr e s e tcommand allows you to set the current HEAD to a specified state, e.g. commit. This way you can continue your work from another commit. Depending on the specified parameters the g i tr e s e tcommand performs the following: 1. 2. If you specify the s o f tparameter, the g i tr e s e tcommand moves only the HEAD pointer. If you specify the m i x e dparameter (also the default), the g i tr e s e tcommand moves the HEAD pointer and resets the staging area to the new HEAD. 3. If you specify the h a r dparameter, the g i tr e s e tcommand moves the HEAD pointer and resets the staging area and the working tree to the new HEAD.

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
Reset HEAD Working tree Staging area

www.vogella.com/tutorials/Git/article.html

35/58

3/6/14
soft mixed (default) hard Yes Yes Yes

Git - Tutorial
No No Yes No Yes Yes

Tip
The g i tr e s e tcommand does not remove untracked files. Use the g i tc l e a n command for this.

28.1.2. Not moving the HEAD pointer with git reset If you specify a path for the g i tr e s e tc o m m a n d , Git does not move the HEAD pointer but only updates the staging area or also the working tree depending on your specified option. See Section 27.3, Remove staged changes for new files and Section 27.4, Remove staged changes for previously committed files for examples.

28.2. Finding commits which you have reset


The commits which were above the commit to which you resetted, can be reached via the g i tr e f l o g command. See Section 31, Recovering lost commits.

28.3. git reset and deleting all unstaged files


The g i tr e s e th a r dcommand makes the working tree exactly match HEAD but it does not delete untracked files in your working tree. If you want to delete them also, you need to use the g i tc l e a nf command in addition.
#r e m o v e ss t a g e da n dw o r k i n gt r e ec h a n g e s #o fc o m m i t t e df i l e s g i tr e s e th a r d #t h ea b o v ed o e sn o tr e m o v eu n t r a c k e df i l e st h e r e f o r e #t h en e x tc o m m a n di sn e e d e d #r e m o v e sn e wf i l e sw h i c ha r es t i l lu n t r a c k e d g i tc l e a nfd

28.4. Using git reset to squash commits


As a soft reset does not remove your change to your files and index, you can use the g i tr e s e ts o f t command to squash several commits into one commit. 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.
#s q u a s h e st h el a s tt w oc o m m i t s g i tr e s e ts o f tH E A D ~ 1& &g i tc o m m i tm" n e wc o m m i tm e s s a g e "

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.

29. Retrieving files from the history


29.1. View file in different revision
The g i ts h o wcommand allows to see and retrieve files from branches, commits and tags. It allows to see the status of these files in the selected branch, commit or tag without checking them out into your
www.vogella.com/tutorials/Git/article.html 36/58

3/6/14

Git - Tutorial

working tree. The following commands demonstrate that. You can also make a copy of the file.
#[ r e f e r e n c e ]c a nb eab r a n c h ,t a g ,H E A Do rc o m m i tI D #[ f i l e n a m e ]i st h ef i l e n a m ei n c l u d i n gp a t h g i ts h o w[ r e f e r e n c e ] : [ f i l e n a m e ] #T om a k eac o p yt oc o p i e d f i l e . t x t g i ts h o w[ r e f e r e n c e ] : [ f i l e n a m e ]>c o p i e d f i l e . t x t

29.2. Restore a deleted file in a Git repo


You can checkout a file from the commit. To find the commit which deleted the file you can use the g i t
l o gor the g i tr e f l i s tcommand as demonstrated by

the following command.

#s e eh i s t o r yo ff i l e g i tl o g-< f i l e _ p a t h > #c h e c k o u tf i l eb a s e do np r e d e c e s s o r st h el a s tc o m m i tw h i c ha f f e c ti t #t h i sw a st h ec o m m i tw h i c hd e l e t et h ef i l e g i tc h e c k o u t[ c o m m i t ]^-< f i l e _ p a t h > #a l t e r n a t i v eu s eg i tr e v l i s t g i tr e v l i s tn1H E A D-< f i l e _ p a t h > #a f t e r w a r d st h es a m ec h e c k o u tb a s e do nt h ep r e d e c e s s o r s g i tc h e c k o u t[ c o m m i t ]^-< f i l e _ p a t h >

29.3. See which commit deleted a file


You can use the -option in g i tl o gto see the commit history for a file, even if you have deleted the file.
#s e et h ec h a n g e so faf i l e ,w o r k se v e n #i ft h ef i l ew a sd e l e t e d g i tl o g-[ f i l ep a t h ] #l i m i tt h eo u t p u to fG i tl o gt ot h e #l a s tc o m m i t ,i . e .t h ec o m m i tw h i c hd e l e t et h ef i l e #1t os e eo n l yt h el a s tc o m m i t #u s e2t os e et h el a s t2c o m m i t se t c g i tl o g1-[ f i l ep a t h ] #i n c l u d es t a tp a r a m e t e rt os e e #s o m es t a t i c s ,e . g .h o wm a n yf i l e sw e r e #d e l e t e d g i tl o g1s t a t-[ f i l ep a t h ]

30. Checkout or revert commits


30.1. Checkout commits versions
You can check out older revisions of your file via the commit ID. The commit ID is shown if you enter the g i tl o gcommand. The following command would show the log.
#c o m m a n dw h i c hg e n e r a t e st h eo u t p u t g i tl o g

The following listing shows an example output of a Git log command.


c o m m i t0 4 6 4 7 4 a 5 2 e 0 b a 1 f 1 4 3 5 a d 2 8 5 e a e 0 d 8 e f 1 9 d 5 2 9 b f A u t h o r :L a r sV o g e l< L a r s . V o g e l @ g m a i l . c o m > D a t e : W e dJ u n51 2 : 1 3 : 0 42 0 1 3+ 0 2 0 0 B u g4 0 9 3 7 3-U p d a t e sv e r s i o nn u m b e ro fe 4t o o l s R e p a i r st h eb u i l d

www.vogella.com/tutorials/Git/article.html

37/58

3/6/14

Git - Tutorial
c o m m i t2 6 4 5 d 7 e e f 0 e 2 4 1 9 5 f c 4 0 7 1 3 7 2 0 0 f e 7 e 1 7 9 5 e c f 4 9 A u t h o r :L a r sV o g e l< L a r s . V o g e l @ g m a i l . c o m > D a t e : W e dJ u n51 2 : 0 0 : 5 32 0 1 3+ 0 2 0 0 B u g4 0 9 3 7 3-U p d a t e sv e r s i o nn u m b e ro fe 4C S Ss p yf e a t u r e s

To checkout a specific commit you can use the following command.


#c h e c k o u tt h eo l d e rr e v i s i o nv i a g i tc h e c k o u t[ c o m m i t _ i d ] #b a s e do nt h ee x a m p l eo u t p u tt h i sc o u l db e g i tc h e c k o u t0 4 6 4 7 4 a 5 2 e 0 b a 1 f 1 4 3 5 a d 2 8 5 e a e 0 d 8 e f 1 9 d 5 2 9 b f

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.

30.2. Reverting a commit


You can revert commits via the g i tr e v e r tcommand. g i tr e v e r twill revert the changes of a commit and record a new commit which documents that the other commit was reverted.
#R e v e r tac o m m i t g i tr e v e r tc o m m i t _ i d

31. Recovering lost commits


31.1. Detached HEAD
If you checkout a commit or a tag, you are in the so-called detached HEAD mode . If you commit changes in this mode, you have no branch which points to this commit. After you checkout a branch you cannot see the commit you did in detached head mode in the g i tl o gcommand. To find such commits you can use the g i tr e f l o gcommand.

31.2. git reflog


Reflog is a mechanism to record the movements of the HEAD pointer and the branches. HEAD is a pointer to the currently selected commit object. The Git reflog command gives a history of the complete changes of the HEAD pointer.
g i tr e f l o g #O u t p u t #. . .s n i p. . . 1 f 1 a 7 3 aH E A D @ { 2 } :c o m m i t :M o r ec h a a n g e s-t y p oi nt h ec o m m i tm e s s a g e 4 5 c a 2 0 4H E A D @ { 3 } :c o m m i t :T h e s ea r en e wc h a n g e s c f 6 1 6 d 4H E A D @ { 4 } :c o m m i t( i n i t i a l ) :I n i t i a lc o m m i t

The g i tr e f l o gcommand also list commits which you have removed.

Tip
There are multiple reflogs: one per branch and one for HEAD. For branches use the g i tr e f l o g[ b r a n c h ]command and for HEAD use the g i tr e f l o gor the g i tr e f l o gH E A Dcommand.

www.vogella.com/tutorials/Git/article.html

38/58

3/6/14

Git - Tutorial

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.
#A s s u m et h e I Df o rt h es e c o n dc o m m i ti s #4 5 c a 2 0 4 5 b e 3 a e d a 0 5 4 c 5 4 1 8 e c 3 c 4 c e 6 3 b 5 f 2 6 9 f 7 #R e s e t st h eh e a df o ry o u rt r e et ot h es e c o n dc o m m i t g i tr e s e th a r d4 5 c a 2 0 4 5 b e 3 a e d a 0 5 4 c 5 4 1 8 e c 3 c 4 c e 6 3 b 5 f 2 6 9 f 7 #S e et h el o g g i tl o g #O u t p u ts h o w st h eh i s t o r yu n t i lt h e4 5 c a 2 0 4 5 b ec o m m i t #S e ea l lt h eh i s t o r yi n c l u d i n gt h ed e l e t i o n g i tr e f l o g #< O u t p u t > c f 6 1 6 d 4H E A D @ { 1 } :r e s e t :m o v i n gt o4 5 c a 2 0 4 5 b e 3 a e d a 0 5 4 c 5 4 1 8 e c 3 c 4 c e 6 3 b 5 f 2 6 9 f 7 #. . . s n i p . . . . 1 f 1 a 7 3 aH E A D @ { 2 } :c o m m i t :M o r ec h a a n g e s-t y p oi nt h ec o m m i tm e s s a g e 4 5 c a 2 0 4H E A D @ { 3 } :c o m m i t :T h e s ea r en e wc h a n g e s c f 6 1 6 d 4H E A D @ { 4 } :c o m m i t( i n i t i a l ) :I n i t i a lc o m m i t g i tr e s e th a r d1 f 1 a 7 3 a

32. Remote and local tracking branches


32.1. Remote tracking branches
Your local Git repository contains references to the state of the branches on the remote repositories to which it is connected. These local references are called remote tracking branches. You can see your remote tracking branches with the following command.
#l i s ta l lr e m o t eb r a n c h e s g i tb r a n c hr

To update remote tracking branches without changing local branches you use the g i tf e t c hcommand which is covered in Section 33, Updating your remote tracking branches with git fetch.

32.2. Delete a remote tracking branch in your local repository


It is also safe to delete a remote branch in your local Git repository. You can use the following command for that.
#d e l e t er e m o t eb r a n c hf r o mo r i g i n g i tb r a n c hdro r i g i n / [ r e m o t e _ b r a n c h ]

The next time you run the g i tf e t c hcommand the remote branch is recreated.

32.3. Delete a branch in a remote repository


To delete the branch in a remote repository use the following command.
#d e l e t eb r a n c hi nar e m o t er e p o s i t o r y g i tp u s h[ r e m o t e ]: b r a n c h ]

Alternatively you can also use the following command.


#d e l e t eb r a n c hi nar e m o t er e p o s i t o r y g i tp u s h[ r e m o t e ]d e l e t e[ b r a n c h ]

For example if you want to delete the branch called testbranch in the remote repository called origin
www.vogella.com/tutorials/Git/article.html 39/58

3/6/14

Git - Tutorial

you can use the following command.


g i tp u s ho r i g i n: t e s t b r a n c h

Note
Note you can also specify the remote repository's URL. So the following command also works.
g i tp u s hs s h : / / [ U R L _ t o _ r e p o ]: t e s t b r a n c h

32.4. Tracking branches


Branches can track another branch. This is called to have an upstream branch and such branch can be referred to as tracking branches. Tracking branches allow you to use the g i tp u l l and g i tp u s hcommand directly without specifying the branch and repository. 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.

32.5. Setting up tracking branches


You create new tracking branches by specifying the remote branch during the creation of a branch. The following example demonstrates that.
#s e t u pat r a c k i n gb r a n c hc a l l e dn e w b r a c h #w h i c ht r a c k so r i g i n / n e w b r a n c h g i tc h e c k o u tbn e w b r a n c ho r i g i n / n e w b r a n c h

Instead of using the g i tc h e c k o u tcommand you can also use the g i tb r a n c hcommand.
#o r i g i n / m a s t e ru s e da se x m a p l eb u tc a nb er e p l a c e d #C r e a t eb r a n c hb a s e do nr e m o t eb r a n c h g i tb r a n c h[ n e w _ b r a n c h ]o r i g i n / m a s t e r #u s et r a c k , #d e f a u l tw h e nt h es t a r tp o i n ti sar e m o t e t r a c k i n gb r a n c h g i tb r a n c ht r a c k[ n e w _ b r a n c h ]o r i g i n / m a s t e r

The n o t r a c kallows you to specify that you do not want to track a branch. You are later going to explicitly add a tracking branch with the g i tb r a n c hucommand.
#i n s t r u c tG i tt oc r e a t eab r a n c hw i t hd o e s #n o tt r a c ka n o t h e rb r a n c h g i tb r a n c hn o t r a c k[ n e w _ b r a n c h _ n o t r a c k ]o r i g i n / m a s t e r #u p d a t et h i sb r a n c ht ot r a c kt h eo r i g i n / m a s t e rb r a n c h g i tb r a n c huo r i g i n / m a s t e r[ n e w _ b r a n c h _ n o t r a c k ]

32.6. See the branch information for a remote repository


To see the tracking branches for a remote repository (short: remote) you can use the following command.
#s h o wa l lr e m o t ea n dt r a c k i n gb r a n c h e sf o ro r i g i n g i tr e m o t es h o wo r i g i n

An example output of this might look like the following.


*r e m o t eo r i g i n

www.vogella.com/tutorials/Git/article.html

40/58

3/6/14

Git - Tutorial
F e t c hU R L :s s h : / / t e s t @ g i t . e c l i p s e . o r g / g i t r o o t / e 4 / o r g . e c l i p s e . e 4 . t o o l s . g i t P u s h U R L :s s h : / / t e s t @ g i t . e c l i p s e . o r g / g i t r o o t / e 4 / o r g . e c l i p s e . e 4 . t o o l s . g i t H E A Db r a n c h :m a s t e r R e m o t eb r a n c h e s : i n t e g r a t i o n t r a c k e d i n t e r m _ r c 2 t r a c k e d m a s t e r t r a c k e d s m c e l a / H a n d l e r A d d o n U p d a t e st r a c k e d L o c a lb r a n c h e sc o n f i g u r e df o r' g i tp u l l ' : i n t e g r a t i o nr e b a s e so n t or e m o t ei n t e g r a t i o n m a s t e r r e b a s e so n t or e m o t em a s t e r t e s t i n g r e b a s e so n t or e m o t em a s t e r L o c a lr e f sc o n f i g u r e df o r' g i tp u s h ' : i n t e g r a t i o np u s h e st oi n t e g r a t i o n( u pt od a t e ) m a s t e r p u s h e st om a s t e r ( u pt od a t e )

33. Updating your remote tracking branches with git fetch


33.1. Fetch
The g i tf e t c hcommand updates your remote tracking branches, i.e. it updates the local copy of branches stored in a remote repository. The following command updates the remote tracking branches from the repository called origin.
g i tf e t c ho r i g i n

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 g i tf e t c hcommand 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. Alternatively you can also use the g i tc h e r r y p i c k" s h a " command to take over only selected commits.

Tip
A detailed description of merge, rebase and cherry-pick can be found in Section 36, Merging branches.

33.2. Fetch from all remote repositories


The g i tf e t c hcommand updates only the remote tracking branches for one remote repository. In case you want to update the remote tracking branches of all your remote repositories you can use the following command.
#s i m p l i f i c a t i o no ft h ef e t c hc o m m a n d #t h i sr u n sg i tf e t c hf o re v e r yr e m o t er e p o s i t o r y g i tr e m o t eu p d a t e #t h es a m eb u tr e m o v ea l ls t a l eb r a n c h e sw h i c h #a r en o ti nt h er e m o t ea n y m o r e g i tr e m o t eu p d a t ep r u n e

33.3. Compare remote tracking branch with local branch


The following code shows a few options how you can compare your branches.
#s h o wt h el o ge n t r i e sb e t w e e nt h el a s tl o c a lc o m m i ta n dt h e #r e m o t eb r a n c h g i tl o gH E A D . . o r i g i n / m a s t e r #s h o wt h ed i f ff o re a c hp a t c h g i tl o gpH E A D . . o r i g i n / m a s t e r

www.vogella.com/tutorials/Git/article.html

41/58

3/6/14
#s h o was i n g l ed i f f g i td i f fH E A D . . . o r i g i n / m a s t e r #i n s t e a do fu s i n gH E A Dy o uc a na l s o #s p e c i f yt h eb r a n c h e sd i r e c t l y g i td i f fm a s t e ro r i g i n / m a s t e r

Git - Tutorial

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 Rparameter.

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.
#a s s u m ey o uw a n tt or e b a s em a s t e rb a s e do nt h el a t e s tf e t c h #t h e r e f o r ec h e c ki to u t g i tc h e c k o u tm a s t e r #u p d a t ey o u rr e m o t et r a c k i n gb r a n c h g i tf e t c h #r e b a s ey o u rm a s t e ro n t oo r i g i n / m a s t e r g i tr e b a s eo r i g i n / m a s t e r

Tip
More information on the rebase command can be found in Section 37.1, Rebasing branches.

33.5. Fetch compared with pull


The g i tp u l lcommand performs a g i tf e t c hand g i tm e r g e(or g i tr e b a s ebased on your Git settings). The g i tf e t c hdoes not perform any operations on your local branches. You can always run the fetch command and review the incoming changes.

34. Merging
Git allows you to combine the changes of two branches. This process is called merging.

35. Command to merge two branches


The g i tm e r g ecommand performs a merge. You can merge changes from one branch to the current active one via the following command.
#s y n t a x :g i tm e r g e< b r a n c h n a m e > #m e r g e si n t oy o u rc u r r e n t l yc h e c k e do u tb r a n c h g i tm e r g et e s t i n g

36. Merging branches


36.1. Fast-forward merge
If the commits which are merged are direct predecessors of the HEAD pointer of the current branch, Git simplifies things by performing a so-called fast forward merge. This fast forward merge simply moves the HEAD pointer of the current branch to the last commit which is being merged. This process is depicted in the following graphics. The first picture assumes that master is checked out and that you want to merge the changes of the branch labeled "branch" into your "master" branch. Each commit points to its predecessor (parent).
www.vogella.com/tutorials/Git/article.html 42/58

3/6/14

Git - Tutorial

After the fast forward merge the HEAD pointer of "master" points to the existing commit.

36.2. Merge commit


If commits are merged which are not direct predecessors of the HEAD pointer of the current branch, Git performs a so-called three-way-merge between the latest commits of the two branches, based on the most recent common predecessor of both.

www.vogella.com/tutorials/Git/article.html

43/58

3/6/14

Git - Tutorial

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
If you prefer to have merge commits, you can avoid fast-forward merges with the g i tm e r g en o f fcommand. This is a question of taste, some teams prefer to always have merge commits, the author of this book prefers fast forward merges.

36.3. Specifying merge strategies and parameters


www.vogella.com/tutorials/Git/article.html 44/58

3/6/14

Git - Tutorial

The sparameter allows you to specify other merge strategies. This is demonstrated with the following command. For example, you can specify the ours strategy in which the result of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. This is demonstrated with the following command.
#m e r g eb r a n c h" o b s o l e t e "i g n o r i n ga l l #c h a n g e si nt h eb r a n c h g i tm e r g eso u r so b s o l e t e

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 Xparameter. For example you can specify here the o u r soption. 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 o u r soption for the recursive merge strategy should not be confused with the ours merge strategy.

A similar option to o u r sis the t h e i r soption. This option prefers the version from the branch which is merged. Both options are demonstrated in the following example code.
#M e r g ec h a n g e sp r e f e r r i n go u rv e r s i o n g i tm e r g esr e c u r s i v eXo u r s[ b r a n c h _ t o _ m e r g e ] #M e r g ec h a n g e sp r e f e r r i n gt h ev e r s i o nf r o m #t h eb r a n c ht om e r g e g i tm e r g esr e c u r s i v eXt h e i r s[ b r a n c h _ t o _ m e r g e ]

Another useful option is the i g n o r e s p a c e c h a n g eparameter 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 m e r g ecommand combines the changes of two branches. If you rebase a branch called A onto another, the g i tcommand 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.
www.vogella.com/tutorials/Git/article.html 45/58

3/6/14

Git - Tutorial

Running the rebase command creates a new commit with the changes of the branch on top of the master branch.

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.
#c r e a t en e wb r a n c h g i tc h e c k o u tbr e b a s e t e s t #T os o m ec h a n g e s

www.vogella.com/tutorials/Git/article.html

46/58

3/6/14

Git - Tutorial
t o u c hr e b a s e 1 . t x t g i ta d d.& &g i tc o m m i tm" w o r ki nb r a n c h " #d oc h a n g e si nm a s t e r g i tc h e c k o u tm a s t e r #m a k es o m ec h a n g e sa n dc o m m i ti n t ot e s t i n g e c h o" T h i sw i l lb er e b a s e dt or e b a s e t e s t ">r e b a s e f i l e . t x t g i ta d dr e b a s e f i l e . t x t g i tc o m m i tm" N e wf i l ec r e a t e d " #r e b a s et h er e b a s e t e s to n t om a s t e r g i tc h e c k o u tr e b a s e t e s t g i tr e b a s em a s t e r #n o wy o uc a nf a s tf o r w a r dy o u rb r a n c ho n t om a s t e r g i tc h e c k o u tm a s t e r g i tm e r g er e b a s e t e s t

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 rebasing, you have to test all of the rewritten commits since they are "rewritten" by the rebase algorithm. Since merge/rebase/cherry-pick are purely text-based and do not understand the semantics of these texts they can end up with logically incorrect results, so such commits always should be reviewed and tested in order to detect potential problems. Hence it might be more efficient to merge a long feature branch into upstream instead of rebasing it since with merge you only have to review and test a single commit: the merge commit itself. Whereas with rebase you have to review and test all rebased commits again.

37.2. Interactive rebase to edit history


The r e b a s ecommand allows you to edit your commit history. For example, you can combine several commits into one commit, reorder or skip commits and edit commit message. This is useful as it allows the user to rewrite some of the commit history (cleaning it up) before pushing your changes to a remote repository. The following will create several commits which should be combined at a later point in time.
#C r e a t ean e wf i l e t o u c hr e b a s e . t x t #A d di tt og i t g i ta d d.& &g i tc o m m i tm" r e b a s e . t x ta d d e dt oi n d e x " #D os o m es i l l yc h a n g e sa n dc o m m i t e c h o" c o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" a d d e dc o n t e n t " e c h o"m o r ec o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" t h i si sj u s tat e s t " e c h o"m o r ec o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" u p s " e c h o"m o r ec o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" y e s " e c h o"m o r ec o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" a d d e dm o r ec o n t e n t " e c h o"m o r ec o n t e n t "> >r e b a s e . t x t g i ta d d.& &g i tc o m m i tm" c r e a t i o no fi m p o r t a n tc o n f i g u r a t i o nf i l e " #C h e c kt h eg i tl o gm e s s a g e g i tl o g

We will combine the last seven commits. You can do this interactively via the following command.
g i tr e b a s eiH E A D ~ 7

www.vogella.com/tutorials/Git/article.html

47/58

3/6/14

Git - Tutorial

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 f i x u pwill 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.
p7 c 6 4 7 2 ea d d e dm o r ec o n t e n t f4 f 7 3 e 6 8a d d e dc o n t e n t fb c 9 e c 3 ft h i si sj u s tat e s t f7 0 1 c b b 5u p s f9 1 0 f 3 8 by e s f3 1 d 4 4 7 da d d e dm o r ec o n t e n t se 0 8 d 5 c 3c r e a t i o no fi m p o r t a n tc o n f i g u r a t i o nf i l e #R e b a s e0 6 e 7 4 6 4 . . e 0 8 d 5 c 3o n t o0 6 e 7 4 6 4 # #C o m m a n d s : # p ,p i c k=u s ec o m m i t # r ,r e w o r d=u s ec o m m i t ,b u te d i tt h ec o m m i tm e s s a g e # e ,e d i t=u s ec o m m i t ,b u ts t o pf o ra m e n d i n g # s ,s q u a s h=u s ec o m m i t ,b u tm e l di n t op r e v i o u sc o m m i t # f ,f i x u p=l i k e" s q u a s h " ,b u td i s c a r dt h i sc o m m i t ' sl o gm e s s a g e # x ,e x e c=r u nc o m m a n d( t h er e s to ft h el i n e )u s i n gs h e l l # #T h e s el i n e sc a nb er e o r d e r e d ;t h e ya r ee x e c u t e df r o mt o pt ob o t t o m . # #I fy o ur e m o v eal i n eh e r eT H A TC O M M I TW I L LB EL O S T . #H o w e v e r ,i fy o ur e m o v ee v e r y t h i n g ,t h er e b a s ew i l lb ea b o r t e d .

37.3. Good practice for rebase


You should always check your local branch history before pushing changes to another Git repository or review system. Git allows you to do local commits. This feature is frequently used to have commits to which you can go back, if something should go wrong during a feature development. Before pushing you should look at your local branch history and validate, whether or not these commits are relevant for others. If they all belong to the implementation of the same feature you, most likely, want to summarize them in one single commit before pushing. The interactive rebase is basically rewriting the history. It is safe to do this as long as the commits have not been pushed to another repository. This means commits should only be rewritten as long as they have not been pushed. If you rewrite and push a commit that is already present in other Git repositories, it will look as if you implemented something that somebody had already implemented.

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.

www.vogella.com/tutorials/Git/article.html

48/58

3/6/14

Git - Tutorial

Warning
In case you want to rewrite history for changes you have shared with others you need to use the fparameter in your g i tp u s hcommand.
#u s i n gf o r c e dp u s h g i tp u s hf

38. Selecting individual commits with git cherrypick


38.1. Applying a single commit
The g i tc h e r r y p i c kcommand allows you to select the patch which was introduced with an individual commit and apply this patch on another branch. The patch is captured as a new commit on the other branch. This way you can select individual changes from one branch and transfer them to another branch.

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 r e b a s ei ) or to port individual bug fixes done on a development branch into maintenance branches.

38.2. Using cherry-pick


In the following example you create a new branch and commit two changes.
#c r e a t en e wb r a n c h g i tc h e c k o u tbp i c k t e s t #c r e a t es o m ed a t aa n dc o m m i t t o u c hp i c k f i l e . t x t g i ta d dp i c k f i l e . t x t g i tc o m m i tm" a d d sn e wf i l e " #c r e a t es e c o n dc o m m i t e c h o" c h a n g e st of i l e ">p i c k f i l e . t x t g i tc o m m i tam" c h a n g e si nf i l e "

You can check the commit history for example with the g i tl o go n e l i n e command.
#s e ec h a n g ec o m m i th i s t o r y g i tl o go n e l i n e #r e s u l t si nt h ef o l l o w i n go u t p u t 2 f c 2 e 5 5c h a n g e si nf i l e e b b 4 6 b 7a d d sn e wf i l e [ M O R EC O M M I T S ] 3 3 0 b 6 a 3i n i t i a lc o m m i t

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.
g i tc h e c k o u tm a s t e r g i tc h e r r y p i c ke b b 4 6 b 7

www.vogella.com/tutorials/Git/article.html

49/58

3/6/14

Git - Tutorial

The c h e r r y p i c kcommand can be used to change the order of commits. g i tc h e r r y p i c kalso accepts commit ranges for example in the following command.
g i tc h e c k o u tm a s t e r #p i c kb o t hc o m m i t s g i tc h e r r y p i c kp i c k t e s t ~ . . p i c k t e s t ~ 1

Tip
See Section 4.2, Commit ranges with the double dot operator for more information about commit ranges.

39. Solving merge conflicts


39.1. What is a merge conflict
A merge conflict occurs if two commits from different branches have modified the same content and Git cannot automatically determine how both changes should be combined when merging these branches. If a merge conflict occurs, Git will mark the conflict in the file and the programmer has to resolve the conflict manually. After resolving it, he can add the file to the staging area and commit the change.

39.2. Example for solving a merge conflict


In the following example you first create a merge conflict and afterwards you resolve the conflict and apply the change to the Git repository. The following code creates a merge conflict. It assumes that repo1 and repo2 have the same origin repository defined.
#S w i t c ht ot h ef i r s td i r e c t o r y c d~ / r e p o 0 1 #M a k ec h a n g e s e c h o" C h a n g ei nt h ef i r s tr e p o s i t o r y ">m e r g e c o n f l i c t . t x t #S t a g ea n dc o m m i t g i ta d d.& &g i tc o m m i tam" W i l lc r e a t em e r g ec o n f l i c t1 " #S w i t c ht ot h es e c o n dd i r e c t o r y c d~ / r e p o 0 2 #M a k ec h a n g e s t o u c hm e r g e c o n f l i c t . t x t e c h o" C h a n g ei nt h es e c o n dr e p o s i t o r y ">m e r g e c o n f l i c t . t x t #S t a g ea n dc o m m i t g i ta d d.& &g i tc o m m i tam" W i l lc r e a t em e r g ec o n f l i c t2 " #P u s ht ot h em a s t e rr e p o s i t o r y g i tp u s h #N o wt r yt op u s hf r o mt h ef i r s td i r e c t o r y #S w i t c ht ot h ef i r s td i r e c t o r y c d~ / r e p o 0 1 #T r yt op u s h>y o uw i l lg e ta ne r r o rm e s s a g e g i tp u s h

#G e tt h ec h a n g e sv i aap u l l #t h i sc r e a t e st h em e r g ec o n f l i c ti ny o u r #l o c a lr e p o s i t o r y g i tp u l lo r i g i nm a s t e r

Git marks the conflict in the affected file. This file looks like the following.
< < < < < < <H E A D C h a n g ei nt h ef i r s tr e p o s i t o r y = = = = = = = C h a n g ei nt h es e c o n dr e p o s i t o r y > > > > > > >b 2 9 1 9 6 6 9 2 f 5 e b f d 1 0 d 8 a 9 c a 1 9 1 1 c 8 b 0 8 1 2 7 c 8 5 f 8

The above is the part from your repository and the below one from the remote repository. You can edit
www.vogella.com/tutorials/Git/article.html 50/58

3/6/14

Git - Tutorial

the file manually and afterwards commit the changes. Alternatively, you could use the g i tm e r g e t o o lcommand. g i tm e r g e t o o lstarts a configurable merge tool that displays the changes in a split screen. g i tm e r g e t o o lis not always available. It is also safe to edit the file with merge conflicts in a normal editor.
#E i t h e re d i tt h ef i l em a n u a l l yo ru s e g i tm e r g e t o o l #Y o uw i l lb ep r o m p t e dt os e l e c tw h i c hm e r g et o o ly o uw a n tt ou s e #F o re x a m p l eo nU b u n t uy o uc a nu s et h et o o l" m e l d " #A f t e r m e r g i n gt h ec h a n g e sm a n u a l l y ,c o m m i tt h e m g i tc o m m i tm" m e r g e dc h a n g e s "

Instead of using the moption in the above example you can also use the g i tc o m m i tcommand 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.

Free Website Builder Free Government Cell Phone Best Cd Rates 10 Best Mutual Funds Best Mutual Funds Free Music

Equifax Free Credit Report Best Wrinkle Creams Free Credit Report Online Top Smartphones Free Music Downloads Best Credit Cards
Chitika | Opt out?

40. Define alias


40.1. Using an alias
An alias in Git allows you to setup your own Git command. For example, you can define an alias which is a short form of your own favorite commands or you can combine several commands with an alias.

40.2. Alias examples


The following defines an alias to see the staged changes with the new g i ts t a g e dcommand.
g i tc o n f i gg l o b a la l i a s . s t a g e d' d i f fc a c h e d '

Or you can define an alias for a detailed g i tl o gcommand. The following command defines the g i tl l alias.
g i tc o n f i gg l o b a la l i a s . l l' l o gg r a p ho n e l i n ed e c o r a t ea l l '

You can also run external commands. In this case you start the alias definition with a !character. For example, the following defines the g i ta ccommand which combines g i ta d d.Aand g i tc o m m i t commands.
#d e f i n ea l i a s g i tc o n f i gg l o b a la l i a s . a c t' ! g i ta d d.A& &g i tc o m m i t ' #t ou s ei t g i ta cm" m e s s a g e "

Warning
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 .

www.vogella.com/tutorials/Git/article.html

51/58

3/6/14

Git - Tutorial

41. Submodules - repositories inside other Git repositories


41.1. Using submodules
Git allows you to include other Git repositories into a Git repository. This is useful in case you want to include a certain library in another repository or in case you want to aggregate certain Git repositories. Git calls these included Git repositories submodules. Git allows you to commit, pull and push to these repositories independently. You add a submodule to a Git repository via the g i ts u b m o d u l ea d dcommand. The g i ts u b m o d u l e
i n i tcommand creates the

local configuration file for the submodules if it does not yet exist.

#A d das u b m o d u l et oy o u rG i tr e p o g i ts u b m o d u l ea d d[ U R Lt oG i tr e p o ] #I n i t i a l i z es u b m o d u l ec o n f i g u r a t i o n g i ts u b m o d u l ei n i t

41.2. Updating submodules


To pull in changes into a Git repository including the changes in submodules you can use the r e c u r s e s u b m o d u l e sparameter in the g i tp u l lc o m m a n d .

#p u l li nt h ec h a n g e sf r o mm a i nr e p oa n ds u b m o d u l e s g i tp u l lr e c u r s e s u b m o d u l e s

Use the g i ts u b m o d u l eu p d a t e command to set the submodules to the commit specified by the main repository.
#s e t t i n gt h es u b m o d u l e st ot h ec o m m i td e f i n e db ym a s t e r g i ts u b m o d u l eu p d a t e

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.

41.3. Tracking commits


By default submodules are tracked by commits, i.e. the main Git repository remembers a certain commit of the submodule. The g i ts u b m o d u l eu p d a t ecommand sets the Git repository of the submodule to that particular commit. The submodule repository tracks its own content which is nested into the main repository. This main repository refers to a commit of the nested submodule repository.

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 g i ts u b m o d u l eu p d a t ecommand 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.
www.vogella.com/tutorials/Git/article.html 52/58

3/6/14

Git - Tutorial
#u p d a t es u b m o d u l ei nt h em a s t e rb r a n c h #s k i pt h i si fy o uu s er e c u r s e s u b m o d u l e s #a n dh a v et h em a s t e rb r a n c hc h e c k e do u t c d[ s u b m o d u l ed i r e c t o r y ] g i tc h e c k o u tm a s t e r g i tp u l l #c o m m i tt h ec h a n g ei nm a i nr e p o #t ou s et h el a t e s tc o m m i ti nm a s t e ro ft h es u b m o d u l e c d. . g i ta d d[ s u b m o d u l ed i r e c t o r y ] g i tc o m m i tm" m o v e ds u b m o d u l et ol a t e s tc o m m i ti nm a s t e r " #s h a r ey o u rc h a n g e s g i tp u s h

Another developer can get the update by pulling in the changes and running the submodules update command.
#a n o t h e rd e v e l o p e rw a n t st og e tt h ec h a n g e s g i tp u l l #t h i su p d a t e st h es u b m o d u l et ot h el a t e s t #c o m m i ti nm a s t e ra ss e ti nt h el a s te x a m p l e g i ts u b m o d u l eu p d a t e

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.

41.4. Tracking branches with submodules


Since tracking of branches is a very common requirement, Git added the option to track a certain branch in its 1.8.2 release. To track branches you specify the branch with the bparameter during the
s u b m o d u l ea d dcommand.

This allows you use to use r e m o t eparameter in the g i ts u b m o d u l eu p d a t ecommand.


#a d ds u b m o d u l et ot r a c km a s t e rb r a n c h g i ts u b m o d u l ea d dbm a s t e r[ U R Lt oG i tr e p o ] ; #u p d a t ey o u rs u b m o d u l e #r e m o t ew i l la l s of e t c ha n de n s u r et h a t #t h el a t e s tc o m m i tf r o mt h eb r a n c hi su s e d g i ts u b m o d u l eu p d a t er e m o t e #t oa v o i df e t c h i n gu s e g i ts u b m o d u l eu p d a t er e m o t en o f e t c h

42. Error search with git bisect


42.1. Using git bisect
The g i tb i s e c tcommand allows you to run a binary search through the commit history to identify the commit which introduced an issue. You specify a range of commits and a script that the b i s e c t command uses to identify whether a commit is good or bad. This script must return 0 if the condition is fulfilled and non-zero if the condition is not fulfilled.

42.2. git bisect example


Create a new Git repository, create the t e x t 1 . t x tfile and commit it to the repository. Do a few more changes, remove the file and again do a few more changes.
www.vogella.com/tutorials/Git/article.html 53/58

3/6/14

Git - Tutorial

We use a simple shell script which checks the existence of a file. Ensure that this file is executable.
# ! / b i n / b a s h F I L E = $ 1 i f[f$ F I L E] ; t h e n e x i t0 ; e l s e e x i t1 ; f i

Afterwards use the g i tb i s e c tcommand to find the bad commit. First you use the g i tb i s e c ts t a r t command to define a commit known to be bad (showing the problem) and a commit known to be good (not showing the problem).
#d e f i n et h a tb i s e c ts h o u l dc h e c k #t h el a s t5c o m m i t s g i tb i s e c ts t a r tH E A DH E A D ~ 5

Afterwards run the bisect command using the shell script.


#a s s u m e st h a tt h ec h e c ks c r i p t #i sad i r e c t o r ya b o v et h ec u r r e n t g i tb i s e c tr u n. . / c h e c k . s ht e s t 1 . t x t

Tip
The above serves as example. The existence of a file can be easier verified with the g i tb i s e c tcommand: g i tb i s e c tr u nt e s tft e s t 1 . t x t

43. Rewriting commit history with git filterbranch


43.1. Using git filter-branch
The g i tf i l t e r b r a n c hcommand allows you to rewrite the Git commit history for selected branches and to apply custom filters on each revision. This creates different hashes for all modified commits. This implies you also get new IDs for all commits based on any rewritten commit. The command allows you to filter for several values, e.g. the author, the message, etc. For details please see the following link.
h t t p : / / w w w . k e r n e l . o r g / p u b / s o f t w a r e / s c m / g i t / d o c s / g i t f i l t e r b r a n c h . h t m l

Warning
Using f i l t e r b r a n c his 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 g i tf i l t e r b r a n c his where you have added a file which contains a password to the Git repository, and you want to remove the password from the history.

www.vogella.com/tutorials/Git/article.html

54/58

3/6/14

Git - Tutorial

43.2. filter-branch example


The following listing shows an example on how to change the committer name and his email address via the g i tf i l t e r b r a n c hcommand.
g i tf i l t e r b r a n c hfe n v f i l t e r\ " G I T _ A U T H O R _ N A M E = ' T e s tV o g e l ' ;G I T _ A U T H O R _ E M A I L = ' t e s t @ g m a i l . c o m ' ;\ G I T _ C O M M I T T E R _ N A M E = ' L a r sV o g e l ' ;\ G I T _ C O M M I T T E R _ E M A I L = ' l a r s . v o g e l @ g m a i l . c o m ' ; "H E A D

44. Create and apply patches


44.1. What is a patch?
A patch is a text file that contains changes to the source code. A patch created with the g i tf o r m a t p a t c hcommand includes meta-information about the

commit (committer, date, commit message, etc)

and also contains the diff of any binary data in the commit, for example, an image. This file can be sent to someone else and this developer can use this file to apply the changes to his local repository. The metadata is preserved. Alternatively you could create a diff file with the g i td i f fcommand, but this diff file does not contain the metadata information.

44.2. Create and apply patches


The following example creates a branch, changes several files and creates a commit recording these changes.
#C r e a t ean e wb r a n c h g i tb r a n c hm y b r a n c h #U s et h i sn e wb r a n c h g i tc h e c k o u tm y b r a n c h #M a k es o m ec h a n g e s t o u c ht e s t 0 5 #C h a n g es o m ec o n t e n ti na ne x i s t i n gf i l e e c h o" N e wc o n t e n tf o rt e s t 0 1 "> t e s t 0 1 #C o m m i tt h i st ot h eb r a n c h g i ta d d. g i tc o m m i tam" F i r s tc o m m i ti nt h eb r a n c h "

The next example creates a patch for these changes.


#c r e a t e sap a t c h>g i tf o r m a t p a t c hm a s t e r g i tf o r m a t p a t c ho r i g i n / m a s t e r #T h i sc r e a t e st h ef i l e : #p a t c h0 0 0 1 F i r s t c o m m i t i n t h e b r a n c h . p a t c h

To apply this patch to your master branch in a different clone of the repository, switch to it and use the g i ta p p l ycommand.
#S w i t c ht ot h em a s t e r g i tc h e c k o u tm a s t e r #A p p l yt h ep a t c h g i ta p p l y0 0 0 1 F i r s t c o m m i t i n t h e b r a n c h . p a t c h

Afterwards you can commit the changes introduced by the patches and delete the patch file.
#P a t c hi sa p p l i e dt om a s t e r #C h a n g ec a nb ec o m m i t t e d g i ta d d. g i tc o m m i tam" A p p l i e dp a t c h " #D e l e t et h ep a t c hf i l e r m0 0 0 1 F i r s t c o m m i t i n t h e b r a n c h . p a t c h

www.vogella.com/tutorials/Git/article.html

55/58

3/6/14

Git - Tutorial

Tip
Use the g i ta mcommand to apply and commit the changes in a single step. To apply and commit all patch files in the directory use, for example, the g i t
a m* . p a t c hcommand.

44.3. Create a patch for a selected commit


You can use specify the commit id and the number of patches which should be created. For example, to create a patch for selected commits based on the HEAD pointer you can use the following commands.
#c r e a t ep a t c hf o rt h el a s tc o m m i tb a s e do nH E A D g i tf o r m a t p a t c h1H E A D #c r e a t ea p a t c hs e r i e sf o rt h el a s tt h r e ec o m m i t s #b a s e do nh e a d g i tf o r m a t p a t c h3H E A D

45. Git commit and other hooks


45.1. Usage of Git hooks
Git provides commit hooks, e.g. programs which can be executed at a pre-defined point during the work with the repository. For example, you can ensure that the commit message has a certain format or trigger an action after a push to the server. These programs are usually scripts and can be written in any language, e.g. as shell scripts or in Perl, Python etc. You can also implement a hook, for example, in C and use the resulting executable. Git calls the scripts based on a naming convention.

45.2. Client and server side commit hooks


Git provides hooks for the client and for the server side. On the server side you can use the p r e r e c e i v eand p o s t r e c e i v escript to check

the input or to trigger actions after the commit.

If you create a new Git repository, Git creates example scripts in the . g i t / h o o k sdirectory. The example scripts end with . s a m p l e . To activate them make them executable and remove the . s a m p l e from the filename. The hooks are documented under the following URL: Git hooks manual page.

46. Line endings on different platforms


Linux and Mac use different line endings than Windows. Windows uses a carriage-return and a linefeed character (CRLF), while Linux and Mac only uses a linefeed character (LF). To avoid commits because of line ending differences in your Git repository you should configure all clients to write the same line ending to the Git repository. On Windows systems you can tell Git to convert line endings during a checkout to CRLF and to convert them back to LF during commit. Use the following setting for this.
g i tc o n f i gg l o b a lc o r e . a u t o c r l ft r u e

On Linux and Mac you can tell Git to convert CRLF during a checkout to LF with the following setting.
g i tc o n f i gg l o b a lc o r e . a u t o c r l fi n p u t

www.vogella.com/tutorials/Git/article.html

56/58

3/6/14

Git - Tutorial

47. Migrating from SVN


To convert Subversion projects to Git you can use a RubyGem called svn2git which relies on g i ts v n internally and handles most of the trouble. To install it (on Ubuntu) simply type:
s u d oa p t g e ti n s t a l lg i t s v nr u b yr u b y g e m s s u d og e mi n s t a l ls v n 2 g i t

Let's say you have a repository called h t t p : / / s v n . e x a m p l e . c o m / r e p owith 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:
s v n 2 g i th t t p : / / s v n . e x a m p l e . c o m / r e p ov e r b o s e s v n 2 g i tr e b a s e

The parameter v e r b o s eadds detailed output to the commandline so you can see what is going on including potential errors. The second s v n 2 g i tr e b a s ecommand 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 s v n 2 g i th e l pfor documentation on additional parameters.

48. Frequently asked questions


48.1. Can Git handle symlinks?
The usage of symlinks requires that the operating system used by the developers supports them. Git as version control system can handle symlinks. If the symlink points to a file, then Git stores the path information it is symlinking to, and the file type. This is similar to a symlink to a directory; Git does not store the contents under the symlinked directory.

49. Git series


This tutorial is part of a series about the Git version control system. See the other tutorials for more information. Introduction into Git Hosting Git repositories at Github, Bitbucket or on your own server Typical workflows with Git EGit - Teamprovider for Eclipse

50. Get the Book


This tutorial is part of a book available as paper print and electronic form for your Kindle.

51. Support free vogella tutorials


Maintaining high quality free online tutorials is a lot of work. Please support free tutorials by donating
www.vogella.com/tutorials/Git/article.html 57/58

3/6/14

Git - Tutorial

or by reporting typos and factual errors.

51.1. Thank you


Please consider a contribution if this article helped you.

51.2. Questions and Discussion


If you find errors in this tutorial, please notify me (see the top of the page). Please note that due to the high volume of feedback I receive, I cannot answer questions to your implementation. Ensure you have read the vogella FAQ as I don't respond to questions already answered there.

52. Links and Literature


Git homepage Video with Linus Torvalds on Git Git on Windows

www.vogella.com/tutorials/Git/article.html

58/58

Anda mungkin juga menyukai