Git tutorial

An essential guide to a powerful integration

Git

Project and code management together.

Try it free

Basic operations

I want to create a repository.

$ git init

Run the command “init” in the directory in which you want to create a repository.

Work with Git: create a repository

Register files/directories to Index

$ git add <filepattern>

In the file pattern, you can specify individual or multiple files and directory names to be added to the index. You can either specify the file name directly or use wild card symbols such as *.txt . Putting . in the filepattern will register all changed files on the index including files within sub-directories.

If you add a -p option, you will be prompted to accept/reject specific sections of a changed file. If you add a -i option, you can register changed files interactively.

Work with Git: commit a file

Commit indexed files

$ git commit

The -a option is like a shortcut that detects changed files (except for newly added files), adds them to the index, and commits them.

The -m option allows you to commit and specify a commit message at the same time. If you do not specify -m, a text editor will open prompting you to enter a commit message.

Work with Git: commit a file

See a list of changed files

$ git status

Adding the -s option will only display the names of files that have been changed.

Adding the -s option followed by -b option will include the branch name in the output.

View differences in changed files

$ git diff

The “diff” command will by default show the differences between the working tree and the index.

If you add the –cached option, the differences between the index and HEAD will be shown.

If you assign HEAD or a commit ID, the differences between the working tree and the assigned HEAD/commit will be shown.

View commit log

$ git log

“log” will by default show a list of commits of the branch.

Specifying a file name will show a log of commits only for that given file.

View a commit detail

$ git show <commit>

Specify the commit ID that can be found through the log command or HEAD to the parameter of the show command.

Move/change the name of a file/directory

$ git mv <oldfilename> <newfilename>

Delete a file

$ git rm <file>

Remove untracked files from working tree

$ git clean

Adding the -n option will only show the files that will be removed. Adding the -f option will actually remove the files.

By default, files listed under the .gitignore configuration file will not be removed. If you specify the -x option however, the files listed under .gitignore will be removed from the working tree.

Restore a changed file in the working tree

$ git checkout -- <file>

Remove a file from the index

$ git reset HEAD -- <file>

Register changes from only files that have been added to the index

$ git add -u

Remote operations

Clone a copy of an existing remote repository

$ git clone <url>

The clone command will create a copy of the repository on your local machine. It will also configure the local repository to automatically track the remote repository.

That configuration allows you to execute Git push or Git fetch/pull without specifying the remote repository name.

Work with Git: clone a remote repository

Add a remote repository

$ git remote add <name>

View list of remote repositories

$ git remote

If you add a -v option, you can see the details of the remote repository.

Create a branch in my local repository based off a branch in the remote repository

$ git checkout <branch>

In the latest version of Git, you can simply create a branch from the remote repository on your local repository by assigning an existing branch name in the remote repository when calling Git checkout.

If you are on an older version of Git, you can do so with the command below.

$ git branch <branchname> origin/<branch>

Create a branch in the remote repository / push changes to a branch in the remote repository

$ git push <repository> <refspec>

Passing the -u option to the push command will allow Git to add a tracking reference to the remote repository when the local branch is successfully pushed. You will not have to specify the repository parameter the next time you do a push/fetch/pull.

You can use either an alias set by the “git remote add” command or the URL for .

Branch name can be used for and the tracking reference will be used when omitted.

Learn Git Basics: syncing repositories
Work with Git: push to remote

Inspect changed content on branches in the remote repository

$ git fetch <repository> <refspec>

The fetch command allows you to retrieve the latest data from your remote repository. This command however does not automatically merge or modify the change into any of your existing work.

The repository and refspec parameter are optional. Ommitting a repository name will yield the same operation as a push command. Ommitting the refspec parameter will ensure fetch is applied to all branches in that remote repository.

Grab latest change of a branch from the remote repository and merge it into current work

$ git pull <repository> <refspec>

The pull command will retrieve the latest changed content from the remote repository and merge it directly into your local repository. You can take it as a “pull = fetch + merge”.

The repository and refspec parameter are optional. Ommitting a repository name will yield the same operation as a push command. Ommitting the refspec parameter will ensure that pull only applies to the current branch.

Learn Git Basics: syncing repositories
Work with Git: pull from a repository

Delete a branch in the remote repository

$ git push --delete <repository> <branchname>

Assign the –delete option in your push command with .

If you are on Git version 1.7 and older, the –delete option cannot be used. Instead, you have to assign it as below:

$ git push <repository> :<branchname>

Create a tag in the remote repository

$ git push <repository> <tagname>

If you add the –tags option, all tags that exist in the local repository will be pushed and created in the remote repository.

Delete a tag in the remote repository

$ git push --delete <repository> <tagname>

Assign the –delete option in your “push” command with

If you are on Git version 1.7 and older, the –delete option cannot be used. Instead, you have to assign it as below:

$ git push <repository> :<tagname>

Change the address of an existing pre-configured remote repository in my local repository

$ git remote set-url <name> <newurl>

Specify the new address of the remote repository in .

Change the name of an existing pre-configured remote repository in my local repository

$ git remote rename <old> <new>

Change the name of the remote repository from to .

Branch operations

See list of branches

$ git branch

Adding the -r option will list the remote tracking branches as well. Adding the -a option will show both remote and local branches.

Create a new branch

$ git branch <branchname>

Work with Git: create a branch

Rename a branch

$ git branch -m <oldbranch> <newbranch>

Delete a branch

$ git branch -d <branchname>

If the branch has not been fully merged with an upstream branch, or in HEAD if there is no upstream, Git will not allow you to delete the branch. You can specify -D however to force delete it irrespective of its merge status.

Work with Git: delete a branch

Switch branches

$ git checkout <branch>

This will allow you to check out and switch to your desired branch.

Adding the -b option will cause a new branch to be created and then checked out.

Learn Git Collaboration: switch branches
Work with Git: switch branches

Merge branches

$ git merge <branch>

Adding the –no-ff option will cause a Git merge to always create a merge commit instead of fast forwarding. This is useful because it allows you to retain the historical information of a branch before it was merged.

Learn Git Collaboration: integrating branches
Work with Git: merge branches

SSH connection settings

Set up an SSH connection (Windows)

Go to Start menu > All Programs > Open TortoiseGit and start Putty Key Generator.

Open TortoiseGit items and run Puttygen

Click on “Generate” and move the mouse cursor within the red frame until the progress bar completes. This will randomly generate a key.

Until the progress bar reaches the right corner, you move the mouse with the red-framed area.

When the key generation is complete, you will see the following display. Click “Save private key” and save the .ppk file.

Save the ppk file by clicking the "Save private key" button.

You can view the public key again in future by loading the .ppk file into Putty Key Generator..

In order to configure SSH connection when we push with TortoiseGit, right-click on TortoiseGit, then choose “Manage”.

If you click TortoiseGit, the following screen will be displayed. Then, click Manage button.

With “origin” selected in the remote column, assign the SSH path to the URL field, and assign the ppk file path that we have just saved to the Putty Key field. Click “Add New/Save”. Now, the origin remote that is associated with the SSH URL path will be added to the list of remote in this repository. Click “OK” to complete.

Assign the ppk file that you just saved to the Putty authentication, and then click Add New/Save button.

Set up an SSH connection (Mac)

Open terminal under application/utility and execute the following command.

$ ssh-keygen

You will see the following output. You may optionally enter the passphrase for this generated rsa key pair.

Continue by hitting enter if you do not wish to set a passphrase.

Generating public/private rsa key pair.
  Enter file in which to save the key (/Users/eguchi/.ssh/id_rsa): <Press Enter key>
  Created directory '/Users/eguchi/.ssh'.
  Enter passphrase (empty for no passphrase): <Input passphrase>
  Enter same passphrase again: <Please enter the same pass phrase again>
  Your identification has been saved in /Users/eguchi/.ssh/id_rsa.
  Your public key has been saved in /Users/eguchi/.ssh/id_rsa.pub.
  The key fingerprint is:
  57:15:3c:ca:f2:dc:27:6d:c2:9a:88:d0:70:cf:8d:31 eguchi@eguchi-no-MacBook-Air.local
  The key's randomart image is:
  +--[ RSA 2048]----+
  |             .o. |
  |             .o  |
  |           ... . |
  |      . . E.o    |
  |       +So.O o . |
  |      . ..+ + = +|
  |       . . . o = |
  |        . . o    |
  |                 |
  +-----------------+

You can view the public SSH key with the following command.

$ cat ~/.ssh/id_rsa.pub

Output example

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkkJvxyDVh9a+zH1f7ZQq/JEI79dVjDSG
  4RzttQwfK+sgWEr0aAgfnxdxQeDKxIxqI1SwyTY8oCcWzvpORuPqwbc7UWWPcCvbQ3jlEdN
  5jvwKM82hincEWwI3wzcnVg2Mn8dH86b5m6REDzwRgozQ3lqrgwGVlTvkHDFs6H0b/1PSrM
  XGppOP/QXGEVhZ6Hy4m3b1wMjjrbYwmWIeYklgoGHyrldhAaDYc33y7aUcRyFyq5DubtsLn
  2oj4K+1q36iviCHxCOri0FDmn2dzylRCI4S+A2/P7Y7rVfdT+8OWYKCBUs8lfjujghEtejq
  Qmj9ikyGTEAW1zQCN7hVwYdjL hoge@hoge.local

Copy and paste this key in the remote repository setting.

Set up an SSH connection (Console)

Execute the following command.

$ ssh-keygen

You will see the following output. You may optionally enter the passphrase for this generated rsa key pair.

Continue by hitting enter if you do not wish to set a passphrase.

Generating public/private rsa key pair.
  Enter file in which to save the key (/Users/eguchi/.ssh/id_rsa): <Press Enter key>
  Created directory '/Users/eguchi/.ssh'.
  Enter passphrase (empty for no passphrase): <Input passphrase>
  Enter same passphrase again: <Please enter the same pass phrase again>
  Your identification has been saved in /Users/eguchi/.ssh/id_rsa.
  Your public key has been saved in /Users/eguchi/.ssh/id_rsa.pub.
  The key fingerprint is:
  57:15:3c:ca:f2:dc:27:6d:c2:9a:88:d0:70:cf:8d:31 eguchi@eguchi-no-MacBook-Air.local
  The key's randomart image is:
  +--[ RSA 2048]----+
  |             .o. |
  |             .o  |
  |           ... . |
  |      . . E.o    |
  |       +So.O o . |
  |      . ..+ + = +|
  |       . . . o = |
  |        . . o    |
  |                 |
  +-----------------+

You can view the public SSH key with the following command.

$ cat ~/.ssh/id_rsa.pub

Output example

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkkJvxyDVh9a+zH1f7ZQq/JEI79dVjDSG
  4RzttQwfK+sgWEr0aAgfnxdxQeDKxIxqI1SwyTY8oCcWzvpORuPqwbc7UWWPcCvbQ3jlEdN
  5jvwKM82hincEWwI3wzcnVg2Mn8dH86b5m6REDzwRgozQ3lqrgwGVlTvkHDFs6H0b/1PSrM
  XGppOP/QXGEVhZ6Hy4m3b1wMjjrbYwmWIeYklgoGHyrldhAaDYc33y7aUcRyFyq5DubtsLn
  2oj4K+1q36iviCHxCOri0FDmn2dzylRCI4S+A2/P7Y7rVfdT+8OWYKCBUs8lfjujghEtejq
  Qmj9ikyGTEAW1zQCN7hVwYdjL hoge@hoge.local

Copy and paste this key in the remote repository setting.

Register my SSH public key to Backlog

Login to Backlog with your account username that has access to the Git repository. Once logged in, click on “Personal Settings”.

Click "personal setting"

Click “Register SSH public key”.

Click "Register SSH public key"

Paste the SSH public key into the text area and click “Register”.

Paste the content of SSH public key and click "Register" button

Commit log operations

Amend previous commit

$ git commit --amend

Assign the –amend option to overwirte the latest commit of the branch you’re wokring on.

Learn Git Basics: rewriting history
Work with Git: commit –amend

Amend only comments of previous commit

$ git commit --amend

When there are no files in an index, you can recommit the previous commit by assigning the –amend option and you’ll be prompted to edit/amend the existing commit comment.

Learn Git Basics: rewriting history
Work with Git: commit –amend

Amend past commit

$ git rebase -i <commit>

Assign a commit hash and a list of all commits up to the assigned commit will be listed. Find the commit you wish to amend, and change that line from “pick” to “edit”, then save and quit.

Next, assign the –amend option to commit. A screen for adding comments will be displayed. Amend the comment.

$ git commit --amend

Finally, assign the –continue option to run rebase.

$ git rebase --continue

Learn Git Basics: rewriting history
Work with Git: change commit using rebase

Amend only comments of a past commit

$ git rebase -i <commit>

Assign a commit hash in and a list of all commits up to the assigned commit will be listed. Find the commit you wish to amend, and change that line from “pick” to “edit”, then save and quit.

Next, assign the –amend option to commit. A screen for adding comments will be displayed. Amend the comment.

$ git commit --amend

Finally, assign the –continue option to run rebase.

$ git rebase --continue

Learn Git Basics: rewriting history
Work with Git: change commit using rebase

Exit a rebase

$ git rebase --abort

By adding the –abort option, you can exit the rebase operation.

View HEAD changes across history

$ git reflog

The reflog command allows you to see a list of commits that HEAD used to indicate in the past.

08084a5 HEAD@{0}: commit: append description of the pull command
  99daed2 HEAD@{1}: commit: append description of the commit command
  48eec1d HEAD@{2}: checkout: moving from master to issue1
  326fc9f HEAD@{3}: commit: append description of the add command
  48eec1d HEAD@{4}: commit (initial): first commit

Both deleted and successful commits gathered by rebase will be displayed.

View changes in branch tip

$ git reflog <ref>

By assigning a branch name to , a list of commits that the tip of the branch used to indicate will be listed like below

445e0ae issue1@{0}: commit (merge): Merge branch 'master' into issue1
  1c904bd issue1@{1}: commit (amend): modify description of the pull command
  08084a5 issue1@{2}: commit: append description of the pull command
  99daed2 issue1@{3}: commit: append description of the commit command
  48eec1d issue1@{4}: branch: Created from 48eec1ddf73a7fb508ef664efd6b3d873631742f

We can see the rebase history of both deleted and existing commits.

Remove previous commit

$ git reset --hard HEAD~

Learn Git Basics: undoing changes
Work with Git: git reset

Reset a rebase

$ git reset --hard <commit>

Use the reflog command to look up commits before they were rebased. Identify the commit hash or the value of [HEAD@{number}] of the commit that occured before the rebase. In this example, 71bdfbd and HEAD@{4} are the references to the commit.

a51f8d2 HEAD@{0}: rebase -i (finish): returning to refs/heads/dev
  a51f8d2 HEAD@{1}: rebase -i (squash): update 1
  3a273e1 HEAD@{2}: rebase -i (squash): updating HEAD
  f55ef69 HEAD@{3}: checkout: moving from dev to f55ef69
  71bdfbd HEAD@{4}: commit: update 2
  f55ef69 HEAD@{5}: commit (amend): update 1

Assign the hash value (71bdfbd and HEAD@{4}) to <commit> when running the reset command.

The head position of the branch will now move to the commit before the rebase was executed. The state of the branch now will be identical to that before rebase was executed.

Cancel the previous reset

$ git reset --hard ORIG_HEAD

ORIG_HEAD refers to the commit before reset took place. You can revert the previous reset by assigning reset to ORIG_HEAD.

Learn Git Basics: undoing changes
Work with Git: git reset

Copy a commit from another branch

$ git cherry-pick "<commit>"

The commit with the ID of will be copied to the current branch.

Learn Git Basics: rewriting history
Work with Git: cherry pick

Search for a commit that includes a specific comment

$ git log --grep "<pattern>"

Displays commits with text specified in .

Git stash

Stash my current change temporarily

$ git stash save

You may choose to omit “save”. If you do specify “save”, you can enter a message to label the stash content (eg. git stash save “making a big change”).

View my stash list

$ git stash list

Recover a change from stash

$ git stash pop

By just calling “git stash pop”, the latest stash will be restored on your current work.

Assigning a parameter of the stash ID (eg. stash@{1}) will restore this specific stash to your current work.

Delete a stash

$ git stash drop

By just calling “git stash drop”, the latest stash will be deleted.

Assigning a parameter of the stash ID (eg. stash@{1}) will delete this specific stash.

Delete all stashes

$ git stash clear

Tag operations

See list of tags

$ git tag

Adding the -n option will show the annotations on each tag.

Create a new tag

$ git tag <tagname>

Create a tag with comment

$ git tag -a <tagname>

Delete a tag

$ git tag -d <tagname>

Git config

Set up user name/email address

$ git config --global user.name <username>
  $ git config --global user.email <mailaddress>

Without the –global option, this setting will only apply to a specific repository.

Color the displayed output

$ git config --global color.ui auto

Set alias for Git command

$ git config --global alias.<aliasname> <commandname>

Remove files from version control tracking

$ echo <filename> >> .gitignore

Add the paths of files under .gitignore. Git will no longer manage those files. You will have to commit the .gitignore file for this to work.

Track empty directories under version control

$ cd <dirname>
  $ touch .gitkeep

Git does not track empty directories. If you would like to add that to the version control, you will need to place a file in that directory. A common practice that people normally do is to add a .gitkeep file to the empty directory.

Display settings

$ git config --global --list

Setup a HTTP connection to a proxy server

Add the following setting to the http items of .gitconfig files.

[http]
  proxy = <address of the proxy server>:<port of the proxy server>

You can also configure it using the following config command:

$ git config --global http.proxy <address of the proxy server>:<port of the proxy server>

Establish a HTTP connection to a user authenticated proxy server

Add the following setting to the http items of .gitconfig files.

[http]
  proxy = http://<username>:<password>@<address of the proxy server>:<port of the proxy server>

You can also configure it using the following config command

$ git config --global http.proxy http://<username>:<password>@<address of the
  proxy server>:<port of the proxy server>

Troubleshooting

Error “Permission denied (publickey)” when connecting to a remote repository using SSH

First of all, you will want to ensure the following:

  • Is the URL correct?
  • Is the secret key correctly configured in the local machine?
  • Is the public key correctly configured in the remote?

You can verify the public/secret key configuration corresponding to the Backlog remote repository by running the following command:

$ ssh <space>@<space>.git.backlogtool.com

Replace <space> with a Backlog space that you own (eg. for the space ‘demo.backlogtool.com’, it will be ‘demo@demo.git.backlogtool.com’)

If the setting is correct, you will see the following output. If you see an error message, repeat the steps above and ensure you are doing it right.

Hi yourname! You've successfully authenticated, but Backlog does not provide
  shell access.
  Connection to git.backlogtool.com closed.

Unable to clone a remote repository via its HTTPS URL

On older versions of Git, you may occassionally face problems when executing a push or pull. It is recommended that you use Git version 1.7.10 or later. If you are using a Git client such as Source Tree or TortoiseGit, use the Git version that comes along with the corresponding client.

I am asked for my password every time I push to/pull from the remote repository

On Git version 1.7.10 or later, you can avoid entering password multiple times by configuring as follows.

Windows

You can use git-credential-winstore, which will only ask for your password the first time you push/pull.

Mac

You can use SourceTree (which we covered in the earlier chapter) to link with the Mac Keychain. This will allow Git to figure out which credentials to use every time you pull or push.

Console

On a Mac, you can use the Git’s credentials API to link a username/password with Git operations. If you use Homebrew, the Git credential API is intalled automatically. Otherwise, you will have to install it manually.

You can check if the credential API is installed with the command below.

$ git credential-osxkeychain
  Usage: git credential-osxkeychain <get|store|erase>

If the credential API is not installed, you will see the output below.

$ git credential-osxkeychain
  git: 'credential-osxkeychain' is not a git command. See 'git --help'.

In that case, you can download it and move the files to /usr/local/bin

$ curl -s -O http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain
  $ chmod u+x git-credential-osxkeychain
  $ mv git-credential-osxkeychain /usr/local/bin

Upon completing installation, run the following command below to activate the credential API.

git config --global credential.helper osxkeychain

Changes pushed to the remote repository are not being reflected there

You may come across the following message below when executing a push. That would normally happen when you are pushing from a new local repository.

$ git push
  No refs in common and none specified; doing nothing.
  Perhaps you should specify a branch such as 'master'.
  Everything up-to-date

By omitting the branch name when executing a push, Git will by default assume that you are trying to push the current change to a remote branch with the same name as the local branch. This happens if the master branch has not been created in the remote repository yet (we are pushing from the local master branch). In this case, we will have to explicitly assign the branch name when executing a push.

$ git push -u origin master

By doing that, the master branch will be created in the remote repository automatically. The next time you run push, you can omit the branch name.

Git vs SVN commands

Comparison table of Git-Subversion commands

Command Operation Subversion
git clone Copy a repository svn checkout
git commit Record changes to file history svn commit
git show View commit details svn cat
git status Confirm status svn status
git diff Check differences svn diff
git log Check log svn log
git add Addition svn add
git mv Move svn mv
git rm Delete svn rm
git checkout Cancel change svn revert1
git reset Cancel change svn revert1
git branch Make a branch svn copy2
git checkout Switch branch svn switch
git merge Merge svn merge
git tag Create a tag svn copy2
git pull Update svn update
git fetch Update svn update
git push It is reflected on the remote svn commit3
gitignore Ignore file list .svnignore
  1. Revert in SVN is the cancel of change, but Revert in Git is the commit for negation. The meanings of Revert are different.
  2. Branch and tag are the same in the structure in SVN, but they are clearly different in Git
  3. SVN does not have the concept of local repository/remote repository, accordingly commit is directly reflected in the remote. However, Git has different reflecting methods for reflecting to the local repository and for reflecting to the remote repository.

Related

Subscribe to our newsletter

Learn with Nulab to bring your best ideas to life