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:

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?

  1. Modified (changed in your working directory)
  2. Staged (in the index, ready for commit)
  3. 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: ~/.gitconfig or ~/.config/git/config
  • --local= | .git/config per 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 for a specific key?

git config <key> ; where key can be something such as user.name or user.email, core.editor, etc.

What command can you use to check the git configuration settings?

git config --list

What are the two types of files from gits' perspective? What kind of files belong in each type?

  1. tracked: things previously staged; newly staged files.

    • can be modified, unmodified or staged
  2. 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?

Text

How to get a short git status? what do the LHS columns mean here?

$ {{c1::git status -s}}
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
Back Extra

git status --short or -s.

  • m : modified
  • mm : modified, staged, modified
  • a : 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?

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 range
  • a/**/z : nested directories; matches a/b/c/z, a/z, a/b/z, etc.

What do the following instructions do in a .gitignore file?

  • *.a
  • !lib.a
  • /TODO
  • build/
  • doc/*.txt
  • doc/**/*.pdf
Back
  • ignore all *.a files
  • but track lib.a
  • only ignore TODO file in current directory. not subdir/TODO. recall that prefix / avoids recursivity
  • ignore all files in any directory named build
  • ignore doc/notes.txt, but not doc/server/notes.txt
  • ignore all .pdf files in doc/ 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 does git log --stat do?

--stat prints a list of modified files below each commit entry, showing how many files were modified and how many lines were added/removed in each file. It provides a summary with insertion/deletion counts and shows relative file activity with ASCII graphs.

What does git log --pretty do and what are its main format options?

--pretty controls the output format of commit entries. Main options include:

  • oneline - compact single-line format with hash and subject
  • short - hash, author, and subject
  • full - includes committer information
  • fuller - shows both author and committer with dates
  • format - custom format using placeholders like %H (hash), %an (author name), %s (subject)

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 -m to edit in your editor)
  • To add a forgotten file: git add <file> then git 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?

Back

It discards working-tree changes to <file> by replacing it with the version from the index (staging area).

How it behaves:

  • If file is staged: restores the staged version
  • If file is not staged: restores from HEAD (because index matches HEAD)

Perils:

  • Permanently loses uncommitted local edits in your working directory
  • No safety net—changes are gone forever
  • Does not create a commit or backup

Safer modern equivalents:

  • git restore <file> (restore working tree from index)
  • git restore --source=HEAD <file> (explicitly restore from last commit)
  • git restore --staged <file> (unstage without discarding working changes)

Note: git checkout -- is deprecated in favour of git restore

What's the difference between git restore <file> and git restore --staged <file>?

Back

git restore <file>

  • Discards working directory changes
  • Restores file from the index (staging area)
  • Leaves staging area unchanged
  • Use when: you want to undo edits but keep staged changes

git restore --staged <file>

  • Unstages the file (removes from index)
  • Leaves working directory unchanged
  • Your edits remain in the working tree
  • Use when: you staged something by mistake but want to keep your changes

Common workflow:

# Made changes and staged them
git add file.txt

Oops, didn't mean to stage yet

git restore –staged file.txt # unstage, keep changes

Actually, don't want these changes at all

git restore file.txt # discard working changes

Key insight: One affects staging area, one affects working directory

If you've staged changes to a file, what does git checkout -- <file> restore: the staged version or the HEAD version?

Back

The staged version (from the index).

Example scenario:

# Original file has "A"
echo "B" > file.txt
git add file.txt          # Index now has "B"

echo "C" > file.txt # Working tree now has "C"

git checkout – file.txt # Restores "B" (staged version) # NOT "A" (HEAD version)

Key point: git checkout -- <file> always restores from the index, not directly from HEAD.

To restore from HEAD instead:

  • git checkout HEAD -- <file>
  • git restore --source=HEAD <file>

This is why it's important to know what's in your staging area!

Which 2 commands does git restore (with different flags) replace?

Back

git restore <file> replaces:

  • git checkout -- <file> (discard working directory changes)

git restore --staged <file> replaces:

  • git reset HEAD <file> (unstage file)

Why the change: Git introduced git restore and git switch to split the overloaded functionality of git checkout into clearer, more focused commands.

Mnemonic:

  • No flag = restore working tree
  • --staged flag = restore (remove from) staging area

What's the modern replacement for git reset HEAD <file> (unstaging)?

Back

git restore --staged <file>

Why the change:

  • More explicit and clear intent
  • git reset is overloaded (moves HEAD, unstages, discards changes depending on flags)
  • git restore --staged only does one thing: unstage

Shorthand equivalents: git reset <file> (HEAD is default) = git reset HEAD <file>

But both are now discouraged in favour of git restore --staged.

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.

\begin{tikzpicture}[ box/.style={rounded corners=5pt, draw, minimum width=3cm, minimum height=2cm, font=\small, line width=1.5pt, align=center, inner sep=4pt}, ] \definecolor{headcol}{HTML}{3498DB} \definecolor{indexcol}{HTML}{E67E22} \definecolor{wdcol}{HTML}{27AE60} \definecolor{resetcol}{HTML}{E74C3C}

% ========================================================== % Card background % ========================================================== \fill[rounded corners=10pt, fill=white, draw=gray!40, line width=2pt] (-1.5, -3.8) rectangle (14, 5.8);

% ========================================================== % BEFORE state % ========================================================== \node[font=\bfseries\footnotesize, text=gray!70] at (1, 4) {BEFORE};

\node[box, fill=headcol!12, draw=headcol] (head) at (2.2, 2.3) { \textbf{HEAD}\\[3pt] \texttt{version A} }; \node[box, fill=indexcol!18, draw=indexcol, line width=2.5pt] (idx) at (6.25, 2.3) { \textbf{Index}\\[3pt] \texttt{version B}\\[2pt] {\tiny\textcolor{indexcol!80}{\textbf{(staged change)}}} }; \node[box, fill=wdcol!12, draw=wdcol] (wd) at (10.3, 2.3) { \textbf{Working Dir}\\[3pt] \texttt{version B} };

\draw[->, thick, gray!60] (head.east) – (idx.west); \draw[->, thick, gray!60] (idx.east) – (wd.west);

% ========================================================== % Command arrow + label % ========================================================== \draw[->, very thick, resetcol, line width=3pt] (6.25, 1.05) – (6.25, -0.15); \node[font=\bfseries\small, text=resetcol, fill=white, rounded corners=2pt, draw=resetcol!30, inner sep=2pt] at (6.25, 0.45) {\texttt{git reset HEAD <file>}};

% ========================================================== % AFTER state % ========================================================== \node[font=\bfseries\footnotesize, text=gray!70] at (1, -0) {AFTER};

\node[box, fill=headcol!12, draw=headcol] (head2) at (2.2, -1.7) { \textbf{HEAD}\\[3pt] \texttt{version A} }; \node[box, fill=indexcol!8, draw=indexcol!60] (idx2) at (6.25, -1.7) { \textbf{Index}\\[3pt] \texttt{version A}\\[2pt] {\tiny\textcolor{resetcol}{\textbf{$\leftarrow$ reset to HEAD}}} }; \node[box, fill=wdcol!12, draw=wdcol] (wd2) at (10.3, -1.7) { \textbf{Working Dir}\\[3pt] \texttt{version B}\\[2pt] {\tiny\textcolor{wdcol!80}{\textbf{(unchanged)}}} };

\draw[->, thick, gray!60] (head2.east) – (idx2.west); \draw[->, thick, gray!60] (idx2.east) – (wd2.west);

\end{tikzpicture}

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 can you delete tags?

first locally: git tag -d <tagname>

then on the upstream: git push <remote> --delete <tagname>

How do you push tags?

git push <remote> <tagname>

or for lots: git push <remote> --tags

How can you create an annotated tag with message?

git tag -a <tagname> -m ""

How can you tag an old commit?

git tag -a <tagname> <commit_hash>

How do you see tag data?

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?

/flashcards/soft-eng/img/rebase1.png

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.

/flashcards/soft-eng/img/rebase2.png /flashcards/soft-eng/img/rebase3.png

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

/flashcards/soft-eng/img/rebase2.png

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 do you download changes from a remote repository without merging them?

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 readme

How 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. /flashcards/soft-eng/img/three-way-merge.png

/flashcards/soft-eng/img/merge-commit.png

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

/flashcards/soft-eng/img/rebase2.png /flashcards/soft-eng/img/rebase3.png

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.

/flashcards/soft-eng/img/change-head.png

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.

How can you create a new branch? Is there only one command?

git branch <new_branch>

which does not move HEAD. dissimilarly, the following do:

  • git checkout -b <new_branch>
  • git switch -c <new_branch>

What are 2 commands for switching to an existing branch? Which is preferred?

git checkout <branch_name>

or more modern:

git switch <branch_name>

/flashcards/soft-eng/img/new-branch.png

What command can we use to see where the branch pointers are pointing? i.e. HEAD

git log --oneline --decorate

Modern note: --decorate is now on by default in most Git versions

/flashcards/soft-eng/img/head-branch.png

How does Git know what branch you're on?

Keeps a special pointer called HEAD that is a pointer to the local branch

/flashcards/soft-eng/img/head-branch.png

How many pointers are in a commit object?

  • 0 for the initial commit (no parents)
  • 1 for regular commits
  • multiple (2?) for merge commits

/flashcards/soft-eng/img/commit-parents.png

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.

/flashcards/soft-eng/img/commit-tree.png

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; -m takes 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

  • origin is the remote.
  • featureB:featureBee uses the <src>:<dst> syntax:

    • featureB is the local branch.
    • featureBee is the remote branch name on origin.

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 commit to create the single squashed commit
  • it does not mark featureB as “merged” in Git history (a later normal merge may try to reapply commits).

\begin{tikzpicture}[ commit/.style={circle, draw=black, fill=blue!20, minimum size=10mm, font=\small\ttfamily}, branch/.style={rectangle, rounded corners, draw=green!60!black, fill=green!10, minimum width=15mm, minimum height=6mm, font=\small\ttfamily}, staged/.style={rectangle, draw=orange!80!black, fill=orange!15, minimum width=30mm, minimum height=15mm, font=\small}, arrow/.style={-Stealth, thick}, label/.style={font=\small}, ]

% Title \node[font=\Large\bfseries, text=blue!50!black] at (6, 11) {\texttt{git merge –squash featureB}};

% ======== BEFORE (top) ======== \node[font=\large\bfseries, anchor=west] at (0, 10) {1. Before:};

% Main branch commits \node[commit] (C1) at (1, 8) {C1}; \node[commit] (C2) at (2.5, 8) {C2};

% FeatureB commits \node[commit] (F1) at (2.5, 6.5) {F1}; \node[commit] (F2) at (4, 6.5) {F2}; \node[commit] (F3) at (5.5, 6.5) {F3};

% Arrows \draw[arrow] (C1) – (C2); \draw[arrow] (C2) – (F1); \draw[arrow] (F1) – (F2); \draw[arrow] (F2) – (F3);

% Branch labels \node[branch, above=2mm of C2] {main}; \node[branch, fill=purple!10, draw=purple!60!black, below=2mm of F3] {featureB};

% HEAD pointer (on main branch) \node[label, text=red, font=\small\bfseries, below=1mm of C2] {HEAD → main};

% ======== AFTER SQUASH (middle) ======== \node[font=\large\bfseries, anchor=west] at (0, 5) {2. After \texttt{git merge –squash}:};

% Working tree/index \node[staged, minimum width=40mm, minimum height=18mm] (staged) at (3.5, 2.5) {}; \node[font=\small\bfseries, text=orange!80!black, anchor=south] at (staged.north) {Working Tree/Index}; \node[font=\footnotesize, align=center] at (staged.center) {All changes from\\F1 + F2 + F3\\(STAGED)};

\node[font=\footnotesize, text=gray, below=1mm of staged] {Need to run \texttt{git commit}}; \node[font=\footnotesize, text=red, below=6mm of staged] {(still on main branch)};

% Arrow from before to after squash \draw[-Stealth, ultra thick, blue!60!black, dashed] (F3) to[out=-45, in=90] node[right, font=\small] {squash} (staged.north);

% ======== AFTER COMMIT (bottom) ======== \node[font=\large\bfseries, anchor=west] at (8, 10) {3. After \texttt{git commit}:};

% Main branch commits \node[commit] (C1b) at (9, 8) {C1}; \node[commit] (C2b) at (10.5, 8) {C2}; \node[commit, fill=green!30] (C3) at (12, 8) {C3};

% FeatureB commits (still exist but not merged) \node[commit, opacity=0.3] (F1b) at (10.5, 6.5) {F1}; \node[commit, opacity=0.3] (F2b) at (12, 6.5) {F2}; \node[commit, opacity=0.3] (F3b) at (13.5, 6.5) {F3};

% Arrows \draw[arrow] (C1b) – (C2b); \draw[arrow] (C2b) – (C3); \draw[arrow, opacity=0.3] (C2b) – (F1b); \draw[arrow, opacity=0.3] (F1b) – (F2b); \draw[arrow, opacity=0.3] (F2b) – (F3b);

% Branch labels \node[branch, above=2mm of C3] {main}; \node[branch, fill=purple!10, draw=purple!60!black, opacity=0.3, below=2mm of F3b] {featureB};

% HEAD pointer (moved to C3 on main) \node[label, text=red, font=\small\bfseries, below=0mm of C3] {HEAD → main};

% Annotations \node[font=\footnotesize, align=center, text=green!50!black, above=7mm of C3] {Single squashed commit}; \node[font=\footnotesize, align=center, text=gray, below=8mm of F2b] {featureB NOT merged\∈ Git history};

% ======== Key notes at bottom ======== \node[font=\normalsize, align=left, text=blue!60!black] at (6.5, 0) {% \textbf{Key Points:} All F1+F2+F3 changes → one commit (C3) • No merge commit • featureB history not recorded};

\end{tikzpicture}

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...B means: diff between merge-base(A, B) and B (changes on B since the common ancestor).
  • So git diff master... (or git diff master...HEAD) shows commits that are on your current branch but not on master, ignoring changes that only master has.

(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"?

/flashcards/soft-eng/img/pull-request-not-merge-cleanly.png

Back

two main options:

  1. rebase your branch on top of whatever the target branch is
  2. 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?

Text

How can you reference issues/pull requests from comments? What are the three syntaxes?

  • {{c1::same scope (i.e. same fork):}} {{c4::#<num>}}
  • {{c2::another fork:}} {{c3::username#<num>}}
  • {{c6::different repo:}} {{c5::username/repo#<num>}}
Back Extra

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 tests
Back

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

How can you pull and merge changes from someone's fork without adding it as a remote?

Back

git pull <URL> <branch>

Example: git pull https://github.com/username/repo patch-1

When to use this:

  • One-off contributions you want to test/merge
  • Don't want to permanently add their fork as a remote
  • Quick way to fetch and merge someone else's branch

Compare to normal workflow:

# Normal way (if you'll collaborate repeatedly):
git remote add contributor <URL>
git pull contributor patch-1

One-off way:

git pull <URL> patch-1

Technically speaking, what does this do?

$ curl https://github.com/tonychacon/fade/pull/1.patch | git am
Back

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?

/flashcards/soft-eng/img/audit-log.png

What kind of entities have this functionality in Github?

Back

Audit log.

Github organisations.

What are the 2 main systems for scripting Github?

  1. Hooks and Services
  2. API

/flashcards/soft-eng/img/service-hooks.png

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.

What is the minimum number of characters required to (uniquely) refer to a SHA-1 Hash?

What is the other requirement?

Back

4 chars minimum; uniqueness

What is the difference between git log --oneline and git log --abbrev-commit --pretty=oneline?

They are the same.

Note though, that git log --pretty=oneline does not abbreviate the commits.

What does git rev-parse topic1 do?

Where rev-parse is a plumbing command, and topic1 is a branch (pointer)

Back

Shows the SHA-1 hash of the commit that the branch is pointing to.

Does a freshly cloned repo have a reflog? What does reflog stand for?

Nope – it only records the current users actions.

"Reference log" – a log of where the HEAD and branch references have been (for the last few months)

How to see reflog information in a git log call? What is the flag?

-g

What does the HEAD^n syntax do?

HEAD^n might bug on non-merge commits, because normal commits only have 1 parent. ^ is ancestor syntax

What does the HEAD@{n} syntax do?

HEAD@{n} shows the $n\textup{th}$ previous place HEAD has been (contingent on reflog!)

What does git show HEAD~3 do?

traverses the parent of HEAD, 3 times. i.e. grand-grand parent of HEAD (equivalent to HEAD~~~)

What does the double-dot syntax do? What is it useful for?

useful for isolating commit ranges

resolves a range of commits that are reachable from one commit but not from another.

What does git log master..experiment do?

lists all commits reachable from experiment but not reachable from master

What does git log origin/master..HEAD do? What is it useful for?

useful to see what you are about to push to a remote.

(origin/master is the remote; recall the double-dot syntax)

What does git infer when you leave off a branch name in the double-dot syntax?

git log origin/master..

Back

infers HEAD

works on either side.

What happens when you use the ^ syntax before a reference? What are the 3 synonyms for this?

synonyms to --not, hence

  1. git log refA..refB
  2. git log ^refA refB
  3. git log refB --not refA

What does the triple-dot syntax do?

specifies all the commits that are reachable by either of the two references, but not by both.

What does the --left-right flag do on git log? What syntax is it most useful with?

gives angle brackets pointing at the reference the commit belongs to:

$ git log --left-right master...experiment
< F
< E
> D
> C

most useful with triple-dot syntax

How can you add files in git interactively?

git add -i

What does stashing do in Git?

takes the dirty state of the working directory (modified tracked files and staged changes), and saves them on a stack of unfinished changes that you can re-apply later.

How do you see all the stashes?

git stash list

How do you create a stash?

git stash

or

git stash push

How do you apply a stash?

git stash apply

Does git stash apply delete the stash from the stack? If not, how can we do so?

It does not. It only applies the stash.

git stash drop <stash_name>

or

git stash pop

What does the git clean command do? What is the dry-run flag?

removes files that are not tracked.

--dry-run ( or -n, which you can later swap for -f )

Does git clean remove =.gitignore=​'d files?

Nope, but you can make it do so with -x

What is the searching command that git ships with? Why is it superior to sed, awk, etc?

git grep – allows searching across branches! (and perhaps even through history)

What are some useful flags for git grep?

--count

--line-numbers (-n)

-p (--show-function)

What are the two ways in which we could want to change a Git commit? How can you solve each?

  1. change commit message

    • git commit --amend
  2. change commit contents

    • make modifications
    • stage changes
    • git commit --amend

What flag can you give to git commit --amend to skip the message altering?

Note: this is for when you make tiny changes that do not warrant a new commit message

Back

--no-edit

How do you modify a commit further back in the history?

git rebase -i HEAD~3

note: HEAD~3 will be the commit that is the parent of commit head - 2

perils: rewrites last 3 commits

How can you take a series of commits and squash them down into a single commit?

with the interactive rebasing tool.

git rebase -i <ref>

where <ref> could be a branch, commit hash or even a tag.

What are some of the things you can do with interactive rebasing?

  • changing multiple commit messages
  • reordering commits
  • squashing commits
  • splitting commits
  • deleting commits

What command should we use for rewriting git history on a larger number of commits in some scriptable way?

filter-branch

How to remove a file named passwords.txt from the entire history?

git filter-branch --tree-filter 'rm -f passwords.txt' HEAD

Git as a system manages and manipulates three trees in its normal operation:

Text

Git as a system manages and manipulates three trees in its normal operation:

TreeRole
{{c1::HEAD}}{{c4::last commit snapshot, next parent}}
{{c2::index}}{{c5::proposed next commit snapshot}}
{{c3::working directory}}{{c6::sandbox}}
Back Extra

The first thing that reset will do is move what {{c1::HEAD}} points to. This isn't the same as {{c2::changing HEAD itself}}, which is what {{c3::checkout}} does.

Text

The first thing that reset will do is move what {{c1::HEAD}} points to. This isn't the same as {{c2::changing HEAD itself}}, which is what {{c3::checkout}} does.

git reset moves the {{c4::branch}} that HEAD is pointing to

Back Extra

What is HEAD~?

the parent of HEAD

What are the 3 levels of git reset?

  1. git reset --soft HEAD~
  2. git reset [--mixed] HEAD~
  3. git reset --hard HEAD~

What effect does git reset HEAD~ have on your git state?

undid the last commit (changes branch HEAD points to)

and unstaged everything (updates index with snapshot of HEAD~1)

What do the 3 levels of git resetting (--soft, --mixed, --hard) do?

  1. moves branch that HEAD points to /flashcards/soft-eng/img/progit-fig144.png /flashcards/soft-eng/img/progit-fig145.png
  2. updates index with contents of new snapshot that HEAD points to. /flashcards/soft-eng/img/progit-fig146.png
  3. makes working directory look like index /flashcards/soft-eng/img/progit-fig147.png

What does git reset file.txt do? What does this mean practically?

/flashcards/soft-eng/img/progit-fig148.png

  1. moving branch that HEAD points to is skipped (files are not commits!)
  2. make index look like HEAD. practically this unstages the file.

How can you squash commits with git reset?

git reset --soft HEAD~2

/flashcards/soft-eng/img/progit-fig151.png

git commit

/flashcards/soft-eng/img/progit-fig152.png /flashcards/soft-eng/img/progit-fig153.png

Whilst reset will move the {{c1::branch}} that HEAD points to, checkout will {{c2::move HEAD itself to point to another branch}}

Text

Whilst reset will move the {{c1::branch}} that HEAD points to, checkout will {{c2::move HEAD itself to point to another branch}}

/flashcards/soft-eng/img/progit-fig154.png

Back Extra

Table

Text
HEADIndexWorkdirWD Safe?
Commit Level
reset --soft [commit]{{c1::REF}}{{c2::NO}}{{c3::NO}}{{c4::YES}}
reset [commit]{{c5::REF}}{{c6::YES}}{{c7::NO}}{{c8::YES}}
reset --hard [commit]{{c9::REF}}{{c10::YES}}{{c11::YES}}{{c12::NO}}
checkout <commit>{{c13::HEAD}}{{c14::YES}}{{c15::YES}}{{c16::YES}}
File Level
reset [commit] <paths>{{c17::NO}}{{c18::YES}}{{c19::NO}}{{c20::YES}}
checkout [commit] <paths>{{c21::NO}}{{c22::YES}}{{c23::YES}}{{c24::NO}}

How do you back out of a merge when you weren't expecting conflicts?

git merge --abort

What does git reset --hard HEAD do?

reverts the repository back to the last committed state

/flashcards/soft-eng/img/progit-fig147.png

What options can be used to merge when the only differences between the code is whitespace?

git merge -Xignore-space-change <branch>

or instead use the flag -Xignore-all-space

What is the difference between -Xignore-all-space and -Xignore-space-change?

"all-space" ignores whitespace completely when comparing lines, "space-change" treats sequences of one or more whitespace characters as equivalent

When you get into a merge-conflict state, how can you export the files from the common state, their state and your state?

$ git show :1:hello.rb > hello.common.rb
$ git show :2:hello.rb > hello.ours.rb
$ git show :3:hello.rb > hello.theirs.rb

What does git ls-files -u do when in a merge conflict state?

$ git ls-files -u
100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1 hello.rb
100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2 hello.rb
100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3 hello.rb

shows the conflicting files with

  1. common ancestor
  2. yours
  3. theirs

What does git diff --ours do? What about the --theirs flag? What's the last flag in this vein?

git diff --base

--ours shows what the merge introduced.

--theirs shows us how the merge differed on their side

--base shows how the file was changed on both sides.

What does git checkout --conflict <file> do?

What are the options available to conflict?

Back

It controls/reformats how merge conflict markers are displayed in a file.

diff3 or merge (default)

diff3 will show base markers on <file>. this command resets the markers on a git conflicted file.

How can we get a full list of the unique commits that were included in either branch involved in the merge?

triple-dot syntax:

git log --oneline --left-right HEAD...MERGE_HEAD

How to only see those commits that affect files that are merge-conflicted?

git log --merge

usefully, you probably do want to add --oneline and --left-right

Whan you run git diff while in a conflicted merge state, you only get …

what is currently in a conflicted state.

Note: this can be helpful to see what needs to be resolved.

What are the three steps that reset --hard goes through?

  1. move the branch that HEAD points to
  2. make index look like HEAD
  3. make the working directory look like the index.

What does git revert do?

makes a new commit which undoes all the changes from an existing one.

What do the -Xours and -Xtheirs flags do?

allow us to choose which files to use in merge conflicts.

these are our strategy options; in contrast to choosing the strategies themselves via -s (recursive, ours, etc)

What is the flag to provide a merge strategy for git merge?

-s; can take recursive (default) or ours as options.

note: there are more like octopus and resolve – but less common day-to-day

common confusion: -Xours and -Xtheirs are strategy options once you have picked the strategy itself.

What does rerere stand for?

"re-use recorded resolution"

What does the -L flag do in git blame?

Back

The -L flag restricts git blame output to specific line ranges within a file.

Syntax: -L <start>,<end> or -L <start>,+<count>

Example
  • git blame -L 10,20 file.txt - shows lines 10 through 20
  • git blame -L 15,+5 file.txt - shows 5 lines starting from line 15
  • git blame -L /function/,+10 file.txt - shows 10 lines starting from the first line containing "function"

Multiple -L flags can be used to specify multiple ranges.

What does the -C option do in git blame?

tries to track down where (else) (in the codebase) the lines in the current file originated from

What does git bisect do?

helps us find the commit that is broken with a binary search

How does git bisect work?

start with git bisect start, then follow it up with git bisect bad.

this will tell it we are in a broken state.

then git bisect good <commit> where <commit> is the commit that is working.

repeat this good, bad cycle until git finds the offending commit.

run git bisect reset when done. this resets HEAD.

How to initialise submodules after a git clone?

Can we do it from the git clone command directly?

Back

git submodule init followed by git submodule update

or indeed: git clone <repo> --recurse-submodules

How can you combine the git submodule init and git submodule update commands?

git submodule update --init,

but for good measure you should really also add the --recursive flag, in case those submodules have submodules too:

i.e. git submodule update --init --recursive

How to see what has changed in a submodule from the present repo?

git diff --submodule

What does git submodule update --remote do?

goes into all the submodules and basically runs git fetch followed by git merge

How can we modify git push to only succeed if all submodule changes have already been pushed?

git push --recurse-submodules=check

Note: --recurse-submodules=on-demand will try to do the git push for you in all submodules.

What does git submodule foreach do?

How can we use it to create a unified diff?

Back

git diff; git submdoule foreach 'git diff'

What do you need to additionally do when checking out a branch with submodules / going to a branch without submodules?

add the recurse-submodules flag to git checkout

This (after git version > 2.13) takes care of placing the submodules in the right state for the branch we're on.

How can you convert a subdirectory into a submodule?

What is wrong with simply doing rm -f <subfolder>; git submodule add ...subfolder.git?

Back

we need to unstage the directory from git's index first!

git rm -r <subfolder> will work

What does git rebase --onto c1 c2 c3 do?=

Rebases branch c3 onto c1, starting from commits after c2.

In other words: take all commits reachable from c3 but not from c2, and replay them onto c1.

This is useful for moving a branch to a new base while excluding certain commits.

If c3 is omitted, it defaults to the current branch (HEAD).

\begin{tikzpicture}[ commit/.style={circle, draw, fill=blue!20, minimum size=8mm}, branch/.style={rectangle, draw, fill=green!20, rounded corners}, arrow/.style={->, thick, red} ]

% =================== % BEFORE REBASE % ===================

\node[commit] (A) at (0,2) {A}; \node[commit] (B) at (1.5,2) {B}; \node[commit] (c2) at (3,2) {c2}; \node[commit] (D) at (4.5,2) {D}; \node[commit] (c3) at (6,2) {c3};

\node[commit] (c1) at (3,0) {c1};

% Connections \draw (A) – (B) – (c2) – (D) – (c3); \draw (B) – (c1);

% Labels \node[above=3mm of A] {\small Before}; \node[branch, above=2mm of c3] {branch c3}; \node[branch, below=2mm of c1] {c1 (new base)};

% Arrow \node at (7.2,1) {\Large $\Rightarrow$};

% =================== % AFTER REBASE % ===================

\node[commit] (A2) at (9,2) {A}; \node[commit] (B2) at (10.5,2) {B}; \node[commit] (c22) at (12,2) {c2};

\node[commit] (c12) at (12,0) {c1}; \node[commit] (D2) at (13.5,0) {$D'$}; \node[commit] (c32) at (15,0) {$c3'$};

% Connections \draw (A2) – (B2) – (c22); \draw (B2) – (c12) – (D2) – (c32);

% Labels \node[above=3mm of A2] {\small After}; \node[branch, below=2mm of c32] {branch c3};

% Mapping arrows \draw[arrow, dashed] (D) to[bend left=25] (D2); \draw[arrow, dashed] (c3) to[bend left=25] (c32);

\node[below=7mm of c12] {\small Commits reachable from c3 but not c2 are replayed onto c1};

\end{tikzpicture}

What does git bundle create repo.bundle HEAD master do?

creates a local file that contains the entire repo. you must add all the refs desired. it can later be unpacked with git clone repo.bundle repo as usual!

Consider modifying your Git working directory and now you want to reset the work in a particular directory (within the wd) to match HEAD.

You have not staged anything yet.

What is the correct command?

Back

git restore static/

or also,

git checkout -- static/

How to do a git push such that all the submodules are also in sync?

git push --recurse-submodules=on-demand

git checkout -- <file>

Text

git checkout -- <file>

discards {{c1::working directory}} changes, not {{c2::staged}} ones.

Back Extra

What to do if you made commits in a detached HEAD state and you want to keep them?

git branch temp-fix

This works because now there is a branch pointer pointing at the dangling commit.

You can then later merge or rebase this branch.

What is the detached HEAD state?

When HEAD is pointing to a commit, not a branch. In this situation, the HEAD pointer will not auto-advance.

You're only able to explore history.

How do you fix being in a detached HEAD state if you made no commits?

Simply attach to a branch:

git checkout main

(or master)

but more modern is:

git switch main

Give 3 examples of commands that explicitly detach HEAD temporarily.

  1. git rebase
  2. git bisect
  3. git checkout --detach

How can you use git reset to squash commits manually? As opposed to git rebase -i?

git reset --soft <commit_before_them>

git commit -m " "

Using git reset how can you split a commit up into multiple commits?

  1. git reset --soft HEAD~
  2. git restore --staged
  3. git add <c1_files>
  4. git commit
  5. git add <c2_files>
  6. git commit

git reset --soft is for changing {{c1::history}} not {{c2::files}}

What is the effect of git reset --soft HEAD~1

everything that was committed is now staged.

An alternative to git commit --amend is?

  1. git reset --soft HEAD~
  2. git commit -m "new msg"

Imagine the contents of file.txt are C, B, A respectively with C in the working directory, B in index and A in .git.

Front

How can you restore file.txt to B?

What about to A?

\begin{tikzpicture}[ node distance=4cm, every node/.style={ draw, rounded corners, minimum width=3.8cm, minimum height=1.4cm, align=center } ]

\node (wd) {Working Directory\\\texttt{file.txt = C}}; \node (idx) [right=of wd] {Index\\\texttt{file.txt = B}}; \node (repo) [right=of idx] {.git (HEAD)\\\texttt{file.txt = A}};

\draw[->] (wd) – (idx); \draw[->] (idx) – (repo);

\end{tikzpicture}

Back

restore to B: git restore file.txt

\begin{tikzpicture}[ node distance=4cm, every node/.style={ draw, rounded corners, minimum width=4.2cm, minimum height=1.4cm, align=center } ]

\node (wd1) {Working Directory\\\texttt{file.txt = C}}; \node (idx) [right=of wd1] {Index\\\texttt{file.txt = B}}; \node (repo) [right=of idx] {.git (HEAD)\\\texttt{file.txt = A}};

\node (wd2) [below=2.2cm of wd1] {Working Directory\\\texttt{file.txt = B}};

\draw[->] (idx.south) |- node[left]{\texttt{git restore file.txt}} (wd2.east);

\end{tikzpicture}

restore to A: git restore --source=HEAD file.txt

\begin{tikzpicture}[ node distance=4cm, every node/.style={ draw, rounded corners, minimum width=4.2cm, minimum height=1.4cm, align=center } ]

\node (wd1) {Working Directory\\\texttt{file.txt = C}}; \node (idx) [right=of wd1] {Index\\\texttt{file.txt = B}}; \node (repo) [right=of idx] {.git (HEAD)\\\texttt{file.txt = A}};

\node (wd2) [below=2.2cm of wd1] {Working Directory\\\texttt{file.txt = A}};

\draw[->] (repo.south) |- node[right]{\texttt{git restore –source=HEAD file.txt}} (wd2.east);

\end{tikzpicture}

What is git reset <file> shorthand for? i.e. what is implied?

git reset HEAD <file>

the ref is implied

Delete all staged and unstaged changes to one file

Text

Delete all staged and unstaged changes to one file

{{c1:: git restore --staged --worktree <file>}}

OR

{{c2:: git checkout HEAD <file>}}

Is git reset --hard <file> valid syntax?

No. the --hard / --mixed / --soft flags are incompatible with a pathspec.

What is the difference between fixup and squash in an interactive rebase?

both fold the marked commit into the one above it, but they differ in what happens to the commit message:

squash
merges the commit and opens the editor so you can combine or edit both commit messages together
fixup
merges the commit, but silently discards its message, keeping only the message from the target commit

How to find every commit that added or removed some text?

git log -G banana

Show every commit that modified a file, including before it was renamed:

git log --follow <file>

Show every commit that modified a file:

git log <file>

How to look at a branch's history?

git log main

where main is an example of a branch.

Delete unstaged changes to one file:

Text

Delete unstaged changes to one file:

{{c1:: git restore <file>}}

OR

{{c2:: git checkout <file>}}

Back Extra

Show a summary of a diff:

git diff <commit> --stat

OR

git show <commit> --stat

How to diff one file since a commit?

git diff <commit> <file>

How to show diff between a commit and its parent ?

git show <commit>

How to diff unstaged changes?

git diff

How to diff all staged and unstaged changes?

git diff HEAD

git reset <file> modifies the {{c1::index}} whilst git restore <file> modifies the {{c2::working directory}}

Text

git reset <file> modifies the {{c1::index}} whilst git restore <file> modifies the {{c2::working directory}}

What is the git restore equivalent of git reset <file>?

git restore --staged <file>

git diff shows {{c1::unstaged}} changes between your {{c2::index}} and {{c3::working directory}}

How to push all local branches to a specified remote?

git push <remote> --all

git merge <branch> merges {{c1:: <branch> }} into {{c2:: the current branch}}

git revert <commit> creates a new commit that undoes all of the changes made in {{c1:: <commit> }} and then {{c2::applies it to the current branch}}

What are some useful flags for git reflog ?

--relative-date
shows date info
--all
shows all refs

  1. note that the formatting of these cards is not guaranteed; they are the source files for my anki-editor workflow. ↩︎