Pro Git
A revisitation of a good book.
I made a couple naïve attempts at trying to master git circa 2024.
After obtaining the UGrad, I have had a couple months of unemployment to improve my Software Engineering skills.
As such I read more than a small selection of this book and produced the following flashcards1:
"Deep Work: Professional activity performed in a state of distraction-free concentration that pushes your cognitive capabilities to their limit." —Cal Newport
Notes
Flashcards
Is it true that git add is a multi-purpose command? if so, what are some things it can do?
True. it can track new files, stage files, and mark merge-conflicted files as resolved.
it may also be able to do more things.
What is the checksumming algorithm used by Git? What is the length of the values? What are the value strings composed of?
SHA1 hash. 40 length. Hex; i.e. 0-9 + a-f
What are the three main states files can reside in?
- Modified (changed in your working directory)
- Staged (in the index, ready for commit)
- Committed (saved in the repository / HEAD history)
What does the staging area look like?
it is a file called index.
What are the three scopes of git config and where are each of the configuration files stored?
--system| all users:/etc/gitconfig--global| current user; all repos:~/.gitconfigor~/.config/git/config--local=|.git/configper repo control
Does /etc/gitconfig trump .git/config?
No. local trumps global which trumps system. This is also the case for configuration files more generally.
What command can you use to check the git configuration settings? What about a specific key?
git config --list
git config <key> ; where key can be something such as user.name or user.email, core.editor, etc.
What are the two types of files from gits' perspective? What kind of files belong in each type?
-
tracked: things previously staged; newly staged files.
- can be modified, unmodified or staged
- untracked: everything else. the stuff git doesn't know about.
How to git add recursively?
trick question; git add automatically adds directories recursively.
What does git add do?
it begins tracking the file and stages it for committing. it is multi-purpose and can do even more. think of it as "add precisely this content to the next commit"
How to get a short git status? what do the LHS columns mean here?
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txtBack
git status --short or -s.
m: modifiedmm: modified, staged, modifieda: added to staging??: untracked
What files do *.[oa] and *.~ ignore in the .gitignore?
files ending with .o OR .a and files ending with .~.
How do you write comments in .gitignore file? how do you specify a directory to ignore?
#
end the directory name with /
note, unless you add the prefix slash, it will ignore that named directory at all levels! the prefix slash means 'not recursively'
What are glob patterns?
Front
What do these ones do?
*[abc]?[0-9]a/**/z
Back
they are simplified regular expressions.
*: matches zero or more characters.[abc]: matches any character inside the brackets?: a single character[0-9]: matches any character between the rangea/**/z: nested directories; matchesa/b/c/z,a/z,a/b/z, etc.
What do the following instructions do in a .gitignore file?
*.a!lib.a/TODObuild/doc/*.txtdoc/**/*.pdf
Back
- ignore all
*.afiles - but track
lib.a - only ignore
TODOfile in current directory. notsubdir/TODO. recall that prefix/avoids recursivity - ignore all files in any directory named
build - ignore
doc/notes.txt, but notdoc/server/notes.txt - ignore all
.pdffiles indoc/and subdirs
Can a repo only have 1 .gitignore file?
no, it can have one in each subdirectory if required.
What does git diff do?
it compares what is in your working directory with what is in your staging area.
How can you use git diff to compare your staged changes to the last commit?
git diff --staged
What is the difference between git diff --staged and git diff --cached? What do they do?
they're synonyms!
shows the diff between last commit and what is staged
What does -v do in git commit?
adds a git diff to the commit popup so you can see exactly what you are committing.
How can you skip the staging area? What is there to be careful of?
git commit -a -m "<message>"
this will only commit the files that were already being tracked. no new files.
How do you remove a file from git? precisely what does the command for this do?
you must remove the file from the tracked files (staging area) and then commit.
git rm does this and also deletes the file from the working directory (so it's not "unstaged" later)
When should you do the -f option for git rm?
if you modified the file or added it to the staging area.
it's a safety feature to prevent removal of files that aren't in a snapshot.
How to remove a file from staging area, but keep it in working directory?
git rm --cached <file>
What order does git log show commits in?
reverse chronological order – most recent commits first.
What does git log -p -2 do?
shows only last 2 commits with diff (or patch) details
What do git log --stat and git log --pretty do? what values can pretty take?
--stat prints a list of modified files below each entry. how many such files, and how many lines were changed.
--pretty has options: oneline, short, full, fuller, format: _, etc.
What does git log -n do where n is integral? How can you get commits made in the last 2 weeks?
shows last 2 commits.
git log --since=2.weeks
also, --until is useful too.
dates can be "2008-01-15" or even relative: "2 years 1 day 3 minutes ago"
What git log flag is commonly referred to as the pick axe? What does this pickaxe do?
git log -S<needle> (the “pickaxe”) shows commits where the number of occurrences of <needle> changes (added/removed).
(Note: git log -s just suppresses diff output.)
How can you filter in git log based on path? where in the command should this filter go?
at the very end, separated by -- to segregate from the other options: git log -- path/to/file
What flag allows you to declutter the log history from merge commits when using git log?
--no-merges
How can you fix a commit message / add an extra file to your commit (that hasn't been pushed yet)?
Use git commit --amend.
- To fix the message only:
git commit --amend -m "new message"(or run without-mto edit in your editor) - To add a forgotten file:
git add <file>thengit commit --amend --no-edit
Amending rewrites the last commit: it creates a new commit with a new hash (the old commit becomes unreachable unless referenced). Avoid amending if the commit has already been pushed/shared (or you’ll need a force push).
What does git checkout -- <file> do? Are there perils?
It discards working-tree changes to <file> by replacing it with the version from the index (staging area). If the file is not staged, that effectively means “restore from =HEAD=”.
Perils:
- It can permanently lose local edits in your working directory (not just “unstage”).
- It does not create a commit or safety net.
Safer / modern equivalents:
git restore <file>(restore working tree from index)git restore --source=HEAD <file>(force restore from last commit)
Which 2 commands does git restore replace?
git reset HEAD <file> and git checkout -- <file>
Which 2 commands does git reset replace?
(For the “unstage” use-case) git reset replaces:
git reset HEAD <file>
Because git reset <file> defaults to HEAD, so:
git reset <file>
is the shorter equivalent.
Note: git checkout -- <file> is a different operation (discard working-tree changes) and is now commonly written as:
git restore <file>
What is the command to add a new remote with shortname and URL?
git remote add <shortname> <url>
What does git fetch <remote> do?
it just downloads the data from whichever remote is the argument, and places it in the .git folder. no merging occurs.
What does git reset HEAD <file> do?
It resets the file in the index to match HEAD (unstages it) while leaving the working directory version unchanged.
How to see the URLs of all the remotes? What about a single remote?
git remote -v
OR for more info on a single remote: git remote show origin
How can you list tags? How can you (optionally filter them)?
git tag
with optional -l that respects globs -l ""
What are the 2 types of tags? What do they do?
lightweight: pointer to a specific commit
annotated: full objects. checksummed; contain metadata: tagger name, email, date, message.
How do you push tags? how can you delete them?
git push <remote> <tagname>
or for lots: git push <remote> --tags
delete: git tag -d <tagname> (which does so locally) followed by git push <remote> --delete <tagname>
How can you create an annotated tag with message? how can you tag an old commit? how do you see tag data?
git tag -a <tagname> -m ""
git tag -a <tagname> <commit_hash>
git show <tagname>
When is rebasing a bad idea?
when other people have based work on your commits.
do not rebase those.
How can you rebase server branch onto master without checking out server first?
git rebase master server
"replay the commits onto master from server branch"
What does git rebase master do? Assuming you're on the experiment branch?

Back
goes to common ancestor; gets diff of every commit – saves them into a temp file; resets experiment branch to same commit as master. applies each patch.
you will then need to fast-forward by checking out master and merging experiment into it.

What are the commands for a basic rebase? How are they different to a merge?
rebase:
git checkout experiment
git rebase master
"go to experiment branch, apply patches to master"
merge:
git checkout master
git merge experiment
"merge changes into current branch"
What does rebasing do?
takes all the changes committed on one branch and replays them on another branch

What is a small gotcha vis-a-vis the git branch -vv command and the information it returns?
it's telling you information about what we have cached from the last fetch. we are better off running git fetch --all; git branch -vv
What does the -vv flag do to git branch?
shows what tracking branches have been set-up.
lists out local branches with more information; what each branch is tracking and if the local branch is ahead, behind or both.
What is @{u} short for? What is an alternative short-form for this? What does git merge @{u} do?
short for the upstream url. hence @{upstream} is another short-form.
git merge @{u} merges the current branches' upstream into the current branch.
If you already have a local branch and want to set it to a remote branch you just pulled down, or want to change the upstream branch you're tracking, the command is {{c1:: git branch -u origin/<branch>}}
What is git checkout serverfix an alias for, where you don't have the remote serverfix branch?
git checkout --track origin/serverfix which itself is shorthand for git checkout -b serverfix origin/serverfix
When you git fetch from a remote (git fetch origin), does that give you editable copies of the new branches?
no, only unmodifiable pointers.
you need to run git merge origin/<branch> which pulls in the changes into your current branch. to make a new branch, use git checkout -b serverfix origin/serverfix
How to push a branch up to a particular remote?
git push -u <remote> <branch>
This pushes the local branch to the given remote and sets its upstream,
so that later you can just run git push on that branch.
Creating a branch does not automatically push it; you must push it at least once as above.
How to pull changes down from a certain remote?
git fetch <remote>
How can we get a full list of remote references?
git ls-remote <remote>
OR
git remote show <remote>
How do you rename a branch? Are there perils?
git branch -m <old> <new> (rename branch locally)
git push -u origin <new> (push new branch name + set upstream)
git push origin --delete <old> (delete old branch from the remote)
Perils: if others are using the old branch name (locally or tracking
origin/<old>), renaming/deleting it will break their setup until they
rename or re-point their branches.
What does git branch --no-merged master do?
shows you which branches have not been merged into master. You can give the final argument to see info on a branch you don't have checked out.
What do the --merged and --no-merged options do on git branch?
shows you which branches are already merged into the branch you're on.
--no-merged shows the branches that have work that you have not merged in.
What happens when you run git branch with no arguments? What about if you add -v?
naked is a simple listing.
git branch
iss53
,* master
testing
note that * tells you what is currently checked out! (i.e. where the HEAD points)
-v also shows the last commit on each branch:
$ git branch -v
iss53 93b412c Fix javascript issue
,* master 7a98805 Merge branch 'iss53'
testing 782fd34 Add scott to the author list in the readmeHow can you solve merge-conflicts?
edit the files and choose the correct code.
git add and git commit (staging the file marks it as resolved). you could also use git mergetool
What happens when you do a git merge and the commit of the branch you're on is not a direct ancestor of the branch you're merging in?
simple three-way merge. uses the two snapshots pointed to by the branch tips and the common ancestor of the two.


How to merge hotfix branch into main?
git checkout main
git merge hotfix
note if you can fast-forward then you should delete the hotfix branch after merging: git branch -d hotfix
What is "fast-forward"?
When the merge has no divergent work to merge together it just moves the branch pointer forward

How can you create a new branch and switch to it in the same command?
git checkout -b <new_branch_name>
alternatively you can now use git switch with --create / -c for a new branch.
note git switch - changes to the last branch.

Is it expensive to create and delete branches? Explain.
No, the pointers are just simple text files with the 40 character SHA1-hash checksums of the commit it points to.
41 bytes cost (+ newline)
Which branches does git log show branches for? How can you modify this behaviour?
git log <branch_name> shows logs for an arbitrary branch git log --all shows for all branches but by default, it's whatever HEAD is pointing to.
What is the command to switch an existing branch? How can you create a new branch?
git checkout <branch_name>
git branch <branch_name>

What command can we use to see where the branch pointers are pointing? i.e. HEAD
git log --oneline --decorate

How does Git know what branch you're on?
Keeps a special pointer called HEAD that is a pointer to the local branch

How many pointers are in a commit object?
- 0 for the initial commit (no parents)
- 1 for regular commits
- multiple (2?) for merge commits

What happens when you make a commit? What does Git store?
stores a commit object with a pointer to the snapshot. also contains metadata + pointer/s to directly previous commits.

A branch in Git is simply a lightweight, movable {{c1::pointer}} to a commit.
When does a file get a checksum? What does this imply has happened?
when the file is staged.
implies a version of the file has been stored. (called blobs)
Why should you write git commit messages in the imperative form? What does imperative form mean?
Write "Fix bug", not "Fixes bug" or "Fixed bug".
The convention matches with commit messages generated by commands like git merge and git revert.
How can you condense git commit -a -m ""? Is this true for all flags?
Yes: you can combine short flags, so:
git commit -am "msg"
is the same as:
git commit -a -m "msg"
But no, this is not true for all flags. Only single-letter short options can be grouped like this, and only when they don’t require their own attached value.
Examples:
- OK:
-am(equivalent to-a -m;-mtakes its message as the next argument) - NOT like this: you generally can’t combine long options (e.g.
--amend) or assume every short flag combination is valid.
What does the three-dots syntax do? git log --no-merges issue54...origin/master
The three-dots range A...B is the symmetric difference between the two branches.
git log --no-merges issue54...origin/master
shows commits that are reachable from either issue54 or origin/master,
but not from both — i.e. commits that are unique to one side or the other.
(You can add --left-right to see which side each commit comes from.)
What is the -u flag short for? git push -u origin featureB:featureBee
-u is short for --set-upstream.
In:
git push -u origin featureB:featureBee
originis the remote.-
featureB:featureBeeuses the<src>:<dst>syntax:featureBis the local branch.featureBeeis the remote branch name onorigin.
The -u / --set-upstream flag makes the local branch featureB
track origin/featureBee, so later you can just run git push or
git pull with no extra arguments.
What does git merge --squash featureB do?
It takes all the changes introduced by branch featureB (since the merge-base with your current branch) and applies them to your working tree/index as one combined change, without creating a merge commit and without recording the branch history.
After running it:
- the changes are staged (like a big “combined” diff)
- you still need to run
git committo create the single squashed commit - it does not mark
featureBas “merged” in Git history (a later normal merge may try to reapply commits).
What does git am do?
"_a_pplies a series of patches from a _m_ailbox"
reads on mbox file, but can also accept a .patch file.
What does git log --pretty =fuller -1 do?
shows last commit with fuller formatting.
What does the --not option do here:
git log <branch> --not master
Back
excludes commits on the master branch.
synonymous to git log master...branch
What option can pass to git log to get the diff introduced by each commit?
-p
How to do a diff between the last commit of the branch you're on and its common ancestor with another branch?
On your feature branch, to see what this branch has introduced since it forked from master:
git diff master...
This uses the three-dots syntax:
- In general,
git diff A...Bmeans: diff betweenmerge-base(A, B)andB(changes on B since the common ancestor). - So
git diff master...(orgit diff master...HEAD) shows commits that are on your current branch but not onmaster, ignoring changes that onlymasterhas.
(You can also write git diff master...branch if you want to compare explicitly to branch.)
How to explicitly find the common ancestor of two branches contrib and master?
git merge-base contrib master
What is cherry-picking? What does the usage look like?
it is like a rebase, but for a single commit.
git cherry-pick <commit_hash>
(cherry picks that commit into current branch)
What does git describe <branch> do?
Gives a human-readable string to describe a commit.
What does git shortlog --no-merges master --not v1.0.1 do?
gives a short log of all the changes since the last release of v1.0.1
How to clone a repository? How to specify a path to clone into?
git clone <remote> <optional_path>
What is a bare repository? How can you create one?
a Git repository with no working directory.
git clone --bare <source>
git init --bare <directory>.git
the .git part is convention for bare repositories.
What does ssh-keygen do? What does adding the -o flag do?
Generates a public and (corresponding) private key.
-o saves the private key in a format more resistant to brute-force attacks. (use this option if setting a password)
What are some pros and cons of setting up Git on your own webserver?
pros:
- lots of control
- run everything from within your own firewall
- some organisations might not allow code on another server
cons:
- time to set-up
- maintainence efforts
What are the 4 distinct protocols Git can use to transfer data?
local, http, secure shell (ssh), git.
How do you check the open issues in a repository with gh?
gh issue list --state open
How do you see the descriptions of a particular Github issue using gh?
gh issue view <num>
Is Github a part of Git?
No, it is a Git host. A place where some functionalities become simpler.
How does Github map commits to your user?
by email address
Do forks exist as part of Git or Github? How about pull-requests?
Forks and pull requests are not core Git features; they are hosting-platform features (e.g., GitHub/GitLab/Bitbucket).
In Git itself, you only have repositories and remotes; a “fork” is just another repo you can add as a remote, and a “pull request” is a workflow built on Git commits/branches plus platform review + merge tooling.
Is it true that often pull requests are created at the beginning of a project? If so, why?
True. Because you can keep pushing to the topic branch even after the pull request is opened.
How can you update a pull request with new code?
Commit to the topic branch and push. The pull request gets updated automatically.
How can you solve "Pull request does not merge cleanly"?

Back
two main options:
- rebase your branch on top of whatever the target branch is
- you can merge the target branch into your branch (preferred)
In Github, all issues and pull requests are assigned {{c1::numbers}} and they are {{c1::unique}} within the project
How can you reference issues/pull requests from comments? What are the three syntaxes?
- same scope (i.e. same fork):
#<num> - another fork:
username #<num> - different repo:
username/repo#<num>
What happens at the bottom of an issue or pull request if someone links to it with the #<num> syntax?
Github create a 'trackback' event
In addition to linking to issue numbers in Github, you can also reference a specific {{c1::commit}} by the {{c1::full 40 character SHA-1 hash}}.
What is a really cool aspect of the checkbox syntax in Github flavoured markdown?
- [X] write the code
- [ ] write all the testsBack
simply clicking the checkbox updates the comment – there is no need to manually edit the file!
How can task lists be used in Issues and Pull requests on pages that list these out?
A little icon with their progress appears beside the headings.
How to write emojis in Github?
I :eyes: that :bug: and I :cold_sweat:.
:trophy: for :microscope: it.
:+1: and :sparkles: on this :ship:, it's :fire::poop:!
:clap::tada::panda_face:Pull requests can either come from a {{c1::branch}} in a {{c1::fork}} of your repository or they can come from {{c1::another branch in the same repository}}.
What is the command to merge in a remote branch without having to add a remote?
git pull <URL> patch-1
here patch-1 is the branch.
Technically speaking, what does this do?
$ curl https://github.com/tonychacon/fade/pull/1.patch | git amBack
merges in the pull request.
Is ls-remote a plumbing command or porcelain command? What happens if you run it on a repository?
plumbing.
gives a list of all the branches and tags and other references in the repo.
What does the CONTRIBUTING file do on Github?
It shows contributors the rendered version of the file when they start opening a pull request.
What is this an example of?

What kind of entities have this functionality in Github?
Back
Audit log.
Github organisations.
What are the 2 main systems for scripting Github?
- Hooks and Services
- API

What are the rate limits to Github when authenticated vs. when not?
5,000 vs. 60.
Is Curl + HTTP requests the best way to interface with the Github API?
There is never a "best way", but other languages like Go, .NET, Objective-C and Ruby do have more idomatic frameworks for the API.
What to do when you do a git init followed by a git add -A of many large files?
git rm -r --cached (unstages everything)
git gc --prune=now (deletes blobs)
What does git blame do?
for each line in a file, it shows the last commit that modified it: who made the change, when, and which commit it was.
e.g. git blame path/to/file.py
What does the syntax git show commit:file do?
It shows the contents of file as it was in commit (or any commit-ish),
without changing your working tree or HEAD.
e.g. git show HEAD~2:src/main.py prints how src/main.py looked two commits ago.
Footnotes
note that the formatting of these cards is not guaranteed; they are the source files for my anki-editor workflow.