Pro Git, by Scott Chacon

⭐️⭐️⭐️⭐️ key book that helped me "unlock" Git


Book details
Author Scott Chacon
Release Date 2014 (2nd Edition)
Pages 503

Can be read online, or downloaded as an e-Book (PDF, EPUB or MOBI).

My highlights:

Your Identity
The first thing you should do when you install Git is to set your user name and email address. This is important because every Git commit uses this information, and it’s immutably baked into the commits you start creating:
git config --global "John Doe"
git config --global
location 472-476
If you want to use a different text editor, such as Emacs, you can do the following: git config --global core.editor emacs
location 481-483
Checking Your Settings
If you want to check your configuration settings, you can use the git config --list command to list all the settings Git can find at that point
location 500-502
if you need in-person help, you can try the #git, #github, or #gitlab channels on the Libera Chat IRC server, which can be found at
location 521-523
If you want to clone the repository into a directory named something other than libgit2, you can specify the new directory name as an additional argument:
git clone mylibgit
That command does the same thing as the previous one, but the target directory is called mylibgit.
location 587-591
The main tool you use to determine which files are in which state is the git status command. If you run this command directly after a clone, you should see something like this:
git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
location 607-610
git commit -a -m 'Add new benchmarks'
Notice how you don’t have to run git add on the file in this case before you commit. That’s because the -a flag includes all changed files.
location 808-811
To see which remote servers you have configured, you can run the git remote command
location 1117-1118
You can also specify -v, which shows you the URLs that Git has stored for the shortname to be used when reading and writing to that remote
location 1124-1125
Adding Remote Repositories
We’ve mentioned and given some demonstrations of how the git clone command implicitly adds the origin remote for you. Here’s how to add a new remote explicitly.
To add a new remote Git repository as a shortname you can reference easily, run
git remote add shortname url
location 1137-1140
As you just saw, to get data from your remote projects, you can run:
git fetch
location 1154-1156
Creating a New Branch What happens when you create a new branch? Well, doing so creates a new pointer for you to move around. Let’s say you want to create a new branch called testing. You do this with the git branch command:
git branch testing
location 1393-1397
You can easily see this by running a simple git log command that shows you where the branch pointers are pointing. This option is called --decorate.
git log --oneline --decorate
location 1404-1407
Switching Branches To switch to an existing branch, you run the git checkout command. Let’s switch to the new testing branch: git checkout testing
This moves HEAD to point to the testing branch.
location 1411-1415
To show commit history for the desired branch you have to explicitly specify it:
git log testing
To show all of the branches, add --all to your git log command.
location 1429-1431
Divergent history You can also see this easily with the git log command. If you run git log --oneline --decorate --graph --all it will print out the history of your commits
location 1447-1448
It’s typical to create a new branch and want to switch to that new branch at the same time — this can be done in one operation with git checkout -b .
location 1460-1462
Create a new branch and switch to it:
git switch -c new-branch
The -c flag stands for create, you can also use the full flag: --create
location 1464-1466
Switch to an existing branch:
git switch testing-branch
location 1463-1464
Return to your previously checked out branch:
git switch
location 1466-1467
The git branch command does more than just create and delete branches. If you run it with no arguments, you get a simple listing of your current branches:
git branch iss53 * master testing
Notice the * character that prefixes the master branch: it indicates the branch that you currently have checked out (i.e., the branch that HEAD points to).
location 1602-1607
To see the last commit on each branch, you can run
git branch -v
location 1608-1609
The useful --merged and --no-merged options can filter this list to branches that you have or have not yet merged into the branch you’re currently on.
To see which branches are already merged into the branch you’re on, you can run:
git branch --merged: git branch --merged iss53 * master Because you already merged in iss53 earlier, you see it in your list. Branches on this list without the * in front of them are generally fine to delete with git branch -d
location 1611-1618
To see all the branches that contain work you haven’t yet merged in, you can run:
git branch --no-merged
location 1618-1619
If you run git clone -o booyah instead, then you will have booyah/master as your default remote branch.
location 1741-1742
If you want to see what tracking branches you have set up, you can use the -vv option to git branch. This will list out your local branches with more information including what each branch is tracking and if your local branch is ahead, behind or both.
git branch -vv
location 1831-1837
git fetch --all; git branch -vv
location 1847-1847
Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass --abbrev-commit to the git log command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous:
git log --abbrev-commit --pretty=oneline
ca82a6d Change the version number
085bb3b Remove unnecessary test code
a11bef0 Initial commit
location 3924-3929
Interactive Staging
If you run git add with the -i or --interactive option, Git enters an interactive shell mode, displaying something like this:
git add -i
staged unstaged path
1: unchanged +0/-1 TODO
2: unchanged +1/-1 index.html
3: unchanged +5/-1
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp What now>
location 4089-4096
You also don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using git add -p or git add --patch on the command line.
location 4172-4174
Now you want to switch branches, but you don’t want to commit what you’ve been working on yet, so you’ll stash the changes. To push a new stash onto your stack, run git stash or git stash push
location 4197-4198
To see which stashes you’ve stored, you can use git stash list:
git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
location 4204-4207
Git Grep
Git ships with a command called grep that allows you to easily search through any committed tree, the working directory, or even the index for a string or regular expression. For the examples that follow, we’ll search through the source code for Git itself.
By default, git grep will look through the files in your working directory. As a first variation, you can use either of the -n or --line-number options to print out the line numbers where Git has found matches
location 4377-4381
you can ask git grep to summarize the output by showing you only which files contained the search string and how many matches there were in each file with the -c or --count option:
git grep --count gmtime_r
location 4390-4393
If you’re interested in the context of a search string, you can display the enclosing method or function for each matching string with either of the -p or --show-function options
location 4394-4396
If you simply want to modify your last commit message, that’s easy: git commit --amend
location 4461-4463
If, on the other hand, you want to change the actual content of your last commit, the process works basically the same way — first make the changes you think you forgot, stage those changes, and the subsequent git commit --amend **replaces** that last commit with your new, improved commit.
location 4465-4467
The official documentation can be found here:
location 8801-8802