Git Tutorial – Git Fu With The Command Line

In this Git tutorial learn how to add autocompletion to the command line, and how to coerce the prompt into providing you with Git-related context and help By Jeff Wolski.

Leave a rating/review
Save for later
Share

There are many different GUIs for Git these days: GitHub for Mac, Tower, SourceTree, Xcode and more. While these options are fine for most situations, many experienced developers would tell you that the Command Line Interface (CLI) is the best option and should be the primary tool you use. git-logo

While “best” is an imprecise, subjective term, the Git CLI is certainly the most powerful and versatile way to use Git, as the GUI options usually just run the CLI commands under the hood. Anything a Git GUI can do, the command line can do — probably better.

This Git tutorial introduces you to a few ways to use the command line more effectively with Git.

In particular, you’ll learn how to make the command line a friendlier place by adding autocompletion, and how to make the command line prompt provide you with help and Git guidance.

Note: It’s often been the case that graphical Git clients have simply executed Git commands under-the-hood. However, an open source, portable, pure C implementation of the Git core methods is now available in libgit2, and is being used by industry heavyweights, such as Microsoft, to power their Git tools

Note: It’s often been the case that graphical Git clients have simply executed Git commands under-the-hood. However, an open source, portable, pure C implementation of the Git core methods is now available in libgit2, and is being used by industry heavyweights, such as Microsoft, to power their Git tools

Getting Started

If you’re new to Git or just need to brush up, here are two links to help you get up to speed.

Also, before continuing, make sure that you’ve installed Xcode’s Command Line Tools (CLT). To find out what you have, open a terminal window and at the prompt enter

xcode-select -p

If you see no error message, you’re OK.

If the tools are not there, type the line below into Terminal, and then follow the instructions in the resulting dialog.

xcode-select --install

Why You Care About Fancy Git Commands

…but might not realize it yet.

To start, take a quick look at some of the most common issues people have with Git repositories, or repos for short. Almost all Git questions on Stack Overflow involve the CLI.

From the volume of CLI related questions, it’s safe to draw the conclusion the majority of developers predominantly use the CLI to handle their Git repositories.

One reason for it’s popularity is because it provides the extra power necessary when your needs have outgrown even the most complete GUI, and your repo requires some low level, fine-grained TLC.

more-power

Anything a GUI can do, the CLI can do (and often better).

Even if your Git GUI of choice is capable of handling your exact situation, you’re likely to have a session of tinkering with menu options and checkboxes to figure out how to address your specific issues. All the while, the GUI will simply be executing CLI commands in the background, so you might as well do it for yourself. If for nothing more than to gain a solid understanding of what’s happening under-the-hood.

One more reason to love Git’s CLI is that it’s been around longer, and has a much larger community, than any Git GUI. Subsequently, there are more people out there who can answer your questions about the Git CLI.

Another shortcoming of Git GUIs shows up when you start using a standard branching model, because these tools often don’t have built-in support for the popular models. However, Atlassian’s SourceTree supports the popular Git-flow model, and it happens to have a pretty useful overview of the different classes of branching models, also known as work-flows.

But what if I want a cool graph of my commits? Can the non-graphical CLI provide that?”

Yes, yes it can. Follow along and you’ll learn how to make it happen.

Cool History Graphs

It turns out the Git CLI can produce useful, almost pretty, commit-history graphs for you. It even lets you filter for the commits you actually want to see.

First, you need a repo with something worth looking at, and for this tutorial you’ll find it inside the git-extras repository.

You’re just going to use this repo as an example to illustrate some CLI usage, but the commands here are quite useful and you may want to install them to enhance Git’s CLI further.

Look at that, one more reason to love the Git CLI — the ability to extend Git via the command line is yet another reason why the Git CLI holds an edge over any Git GUI.

Now use one of Git’s most basic commands, git clone to make a copy of this repo on your local machine. First open a terminal window and navigate to the folder where you want to store the repo, and then type the commands below:

git clone git@github.com:visionmedia/git-extras.git
cd git-extras

If you get any errors from the clone command above, you can replace that line by:

git clone https://github.com/visionmedia/git-extras.git

Note: If you do see an error here, it’s likely because you’ve not setup your SSH keys with GitHub. You can find out more about how to do that and why it’s important here

Note: If you do see an error here, it’s likely because you’ve not setup your SSH keys with GitHub. You can find out more about how to do that and why it’s important here

Make sure you’re in the git-extras directory by entering pwd on the command line. Now, take a look at a graph of commits by entering the following command:

git log --graph --pretty=oneline --abbrev-commit 

And you should see something like this.

*  3b3efd7 Merge pull request #219 from jhoffmann/patch-1
|\ 
| * 3c6a084 Update Readme.md
* |  47bb6e0 Merge pull request #222 from jsipprell/pull/filenames-containing-spaces
|\ \ 
| * | 1479b96 git effort: handle filenames containing whitespace cleanly
| |/ 
* |  039bb5c Merge pull request #223 from mwoc/master
|\ \ 
| * | 0687de7 Use two-space indents for log entry output, so it again is debian changelog compatible (as before commit 1235e4a5)
| |/ 
* |  a87403b Merge pull request #229 from yggdr/master
|\ \ 
| * | e4290df invoke bash via /usr/bin/env for portability
* | |  45b3515 Merge pull request #231 from petersohn/master
|\ \ \ 
| |/ / 
|/| |  
| * | 698d027 Make git-obliterate work if there are whitespaces in filename
|/ / 
* | d437418 Release 1.9.1
* |  ef00c0c Merge pull request #225 from pmalek/master
|\ \ 
| |/ 
             -- And it continues!
:

Hit the spacebar a few times; you’ll see pages and pages of commits and a graphical representation of the branches and merges over time. When you’ve soaked in the graph, hit q to quit.

That’s probably a lot more commits than you want to dig through. But you can limit the scope in various ways — for instance, by date.

Enter the command below:

git log --graph --pretty=short --abbrev-commit --since=April

This shows just the commits since April, and it also grabs some useful info about each commit by asking for a short format instead of oneline.

Now you see a much shorter graph like this one.

* commit 3b3efd7
| Merge: 47bb6e0 3c6a084
| Author: hemanth.hm 
| 
|   Merge pull request #219 from jhoffmann/patch-1
|  
*  commit 47bb6e0
|\ Merge: 039bb5c 1479b96
| | Author: hemanth.hm 
| | 
| |   Merge pull request #222 from jsipprell/pull/filenames-containing-spaces
| |  
| * commit 1479b96
|  Author: Jesse Sipprell 
|  
|    git effort: handle filenames containing whitespace cleanly
|  
*  commit 039bb5c
|\ Merge: a87403b 0687de7
| | Author: hemanth.hm 
| | 
| |   Merge pull request #223 from mwoc/master
| |  
| * commit 0687de7
|  Author: Maarten Winter 
|  
|    Use two-space indents for log entry output, so it again is debian changelog compatible (as before commit 1235e4a5)
|  
*  commit a87403b
|\ Merge: 45b3515 e4290df
| | Author: hemanth.hm 
| | 
| |   Merge pull request #229 from yggdr/master
| |  
| * commit e4290df
| | Author: Konstantin Schukraft 
| | 
| |   invoke bash via /usr/bin/env for portability
| |   
* |  commit 45b3515
|\ \ Merge: d437418 698d027
| |/ Author: hemanth.hm 
|/|  
| |    Merge pull request #231 from petersohn/master
| |  
| * commit 698d027
|/ Author: eszabpt 
|  
|    Make git-obliterate work if there are whitespaces in filename
| 
* commit d437418
| Author: TJ Holowaychuk 
| 
|   Release 1.9.1
| 
* commit ef00c0c
| Merge: e91da7c 4145f22
| Author: TJ Holowaychuk 
| 
|   Merge pull request #225 from pmalek/master
| 
* commit 4145f22
| Author: Patryk Małek 
| 
|   Fixed git-changelog errors when multiple files match change|history
| 
* commit de6463f
 Author: Patryk Małek 
 
   Fixed git-changelog errors on first usage
(END) 

Don’t forget to hit q to exit.

Next, filter your graph to show only commits by a specific user. Graph all the commits by Patryk Małek since April, and list a bunch more info on each commit by entering the following command:

git log --graph --pretty=fuller --abbrev-commit --since=April --author="Patryk Małek"

Now you have a shorter, much more useful list of commits with quite a lot of detail.

* commit 4145f22
| Author:   Patryk Małek 
| AuthorDate: Mon Jun 16 16:32:47 2014 +0200
| Commit:   Patryk Małek 
| CommitDate: Mon Jun 16 16:32:47 2014 +0200
| 
|   Fixed git-changelog errors when multiple files match change|history
| 
* commit de6463f
 Author:   Patryk Małek 
 AuthorDate: Mon Jun 16 16:27:57 2014 +0200
 Commit:   Patryk Małek 
 CommitDate: Mon Jun 16 16:27:57 2014 +0200
 
   Fixed git-changelog errors on first usage

Maybe you’d like a list all of the accepted pull-requests since June? Just enter the following:

git log --grep="pull request" --since=21june

Since GitHub automatically adds a useful message each time an owner of a repo accepts a pull request, you see something like this:

commit 3b3efd74831639a7eeac37add0a1332a0ca9e847
Merge: 47bb6e0 3c6a084
Author: hemanth.hm 
Date:  Sun Jul 6 12:37:41 2014 +0530

  Merge pull request #219 from jhoffmann/patch-1
  
  Update Readme.md

commit 47bb6e0f7423304caf214998e44e717400b30bad
Merge: 039bb5c 1479b96
Author: hemanth.hm 
Date:  Sun Jul 6 12:36:08 2014 +0530

  Merge pull request #222 from jsipprell/pull/filenames-containing-spaces
  
  git-effort handles filenames with whitespace.

commit 039bb5c318f329d62cff86d3a11b4c516586b963
Merge: a87403b 0687de7
Author: hemanth.hm 
Date:  Sun Jul 6 12:34:21 2014 +0530g

  Merge pull request #223 from mwoc/master
  
  Restoring debian changelog compatibility.

commit a87403b57f3c72034be2abc066d40425e8a9a7ba
Merge: 45b3515 e4290df
Author: hemanth.hm 
Date:  Sun Jul 6 11:55:00 2014 +0530

  Merge pull request #229 from yggdr/master
  
  /usr/bin/env for portability.

commit 45b3515ff811e603c2c9278553af26c7c996c117
Merge: d437418 698d027
Author: hemanth.hm 
Date:  Sun Jul 6 11:52:58 2014 +0530

  Merge pull request #231 from petersohn/master
  
  git-obliterate now supports whitespaces in filename.

commit ef00c0c2c6d146081347dd75d27ee6a9facb4ee9
Merge: e91da7c 4145f22
Author: TJ Holowaychuk 
Date:  Sat Jun 21 21:53:16 2014 -0700

  Merge pull request #225 from pmalek/master
  
  Fixed git-changelog errors on first usage
(END) 

Note: Pull requests are not really a feature of Git, but are part of a work-flow made available by Git repository hosting services such as GitHub and Bitbucket.

Note: Pull requests are not really a feature of Git, but are part of a work-flow made available by Git repository hosting services such as GitHub and Bitbucket.

Jeff Wolski

Contributors

Jeff Wolski

Author

Over 300 content creators. Join our team.