Lessons · Git · Quick reference
Git quick reference
62 topics, one line each, in the order Hone teaches them.
Hone is a place to practise programming. This sheet is the whole Git track at a glance: every idea it covers, in the order they are taught, one line each. It is a map rather than a lesson. Read opens the full explanation of an idea; Practise gives you a question on it. Both are free, and reading needs no account at all.
Git without fear · The three areas
starting a repositorygit init turns the current folder into a repository by creating a hidden .git folder. The folder is tracked from then on; its files are not until you add them. Read: Starting a repository · Practise starting a repository
what git can see right nowgit status shows which files are untracked, modified or staged. Run it before every command you are not sure about. Read: What Git thinks right now · Practise what git can see right now
choosing what goes in the commitgit add copies a file's current state into the staging area. add chooses; commit records. Two steps, on purpose. Read: Choosing what the next commit contains · Practise choosing what goes in the commit
recording a snapshotgit commit records the staged changes as one snapshot with a message. Nothing unstaged goes in, and the commit stays on your machine until you push. Read: Recording a snapshot · Practise recording a snapshot
the folder, the staging area, the last commitYou edit in the working tree, choose with add into the index (the staging area), and record with commit into the repository. Every Git command moves changes between these three. Read: Working tree, index, repository · Practise the folder, the staging area, the last commit
reading the historygit log lists commits newest first: hash, author, date, message. --oneline compresses each to one line; --graph --all draws every branch. Read: Reading the history · Practise reading the history
Git without fear · The daily rhythm
what changed, line by linegit diff shows working-tree edits that are not staged. git diff --staged shows what is staged, which is exactly what the next commit will contain. Read: Seeing the change before you record it · Practise what changed, line by line
writing a commit messageA good commit message says what changed and why, in the imperative: 'Fix login timeout on slow networks'. Six months later it is the only explanation anyone will have. Read: A message someone can use · Practise writing a commit message
files git should not watchA .gitignore file lists patterns for files that should not be tracked: build output, logs, secrets, editor junk. Ignored files never show as untracked. Read: Files Git should never track · Practise files git should not watch
HEAD: where you are standingHEAD names the commit you have checked out, normally through a branch. HEAD~1 is one commit back, HEAD~2 two back. Read: Where HEAD points · Practise HEAD: where you are standing
putting a file backgit restore file discards unstaged edits to that file. git restore --staged file unstages it and keeps your edits. The first has no undo. Read: Taking a change back · Practise putting a file back
deleting a file git tracksgit rm deletes the file and stages the deletion in one step. git rm --cached stops tracking a file but leaves it on disk. Read: Removing a file properly · Practise deleting a file git tracks
renaming a tracked filegit mv renames the file and stages the rename; status shows R and the file's history stays connected. Read: Renaming so history follows · Practise renaming a tracked file
redoing the last commitgit commit --amend replaces the last commit with a new one, to fix its message or add a forgotten file. It has a new hash: amend rewrites, it does not edit. Read: Fixing the last commit · Practise redoing the last commit
Git without fear · Branches and merges
a branch is a name for a commitA branch is a movable name for a commit. Creating one costs nothing and changes nothing; committing on it moves it forward. Read: A branch is a pointer · Practise a branch is a name for a commit
moving between branchesgit switch name moves you onto that branch and changes the working tree to match. git switch -c name creates the branch first. Read: Moving between branches · Practise moving between branches
fast-forward: no merge neededgit merge other brings other's commits onto your branch. If your branch has not moved, Git fast-forwards: the pointer moves up and no new commit is made. Read: Bringing a branch in · Practise fast-forward: no merge needed
when both sides movedIf both branches have new commits, git merge creates a merge commit with two parents: the join point of the two lines of work. Read: When both sides moved · Practise when both sides moved
when git will not guessA conflict happens when both branches changed the same part of the same file. Git marks both versions with <<<<<<<, ======= and >>>>>>> and waits for you to choose. Read: Resolving a conflict · Practise when git will not guess
stash: putting work asidegit stash puts your uncommitted changes on a local stack and leaves a clean working tree. git stash pop brings the top one back and drops it from the stack. Read: Shelving work for a moment · Practise stash: putting work aside
Git without fear · Working with others
copying a whole repositorygit clone URL copies a repository, full history included, into a new folder, and names the source remote origin. Read: Getting a copy of a project · Practise copying a whole repository
the other end, by nameA remote is a name for another copy of the repository, with a URL. origin is the conventional name for where you cloned from; you can add others. Read: Named places to sync with · Practise the other end, by name
fetch, then mergegit fetch downloads new commits into origin/* and changes none of your branches. git pull is fetch followed by a merge (or rebase) into your branch. Read: fetch looks, pull changes · Practise fetch, then merge
sending your commitsgit push sends your commits to a branch on the remote. The first time, -u sets the upstream so plain git push and git pull know where to go. Read: Sending commits up · Practise sending your commits
asking somebody to merge itA pull request (merge request on GitLab) is a proposal to merge one branch into another, reviewed on the hosting platform before it lands. Git itself has branches; the platform adds the conversation. Read: Proposing a change · Practise asking somebody to merge it
naming a commit for goodA tag is a fixed label on one commit. Unlike a branch it never moves, which is what makes it right for releases: v1.0 always means that commit. Read: Marking a release · Practise naming a commit for good
Git without fear · Undo, safely
which undo, and whenThe right undo depends on one question: has anyone else got this commit? Unpushed: reset --soft keeps the work and removes the commit. Pushed: revert adds a commit that undoes it. Read: Which undo · Practise which undo, and when
undoing by adding a commitgit revert HEAD makes a new commit whose diff is the exact opposite of the last one. History only grows; nothing anyone already has is rewritten. Read: Undo by adding · Practise undoing by adding a commit
moving the branch backgit reset HEAD~1 moves the branch back one commit. --soft keeps the changes staged, the default keeps them in the working tree, --hard discards them too. Read: Moving the branch back · Practise moving the branch back
replaying commits somewhere elseFrom a feature branch, git rebase main lifts your commits off where they were and lays them down again on top of main's newest commit. The changes are the same; the commits themselves are new, with new hashes. Read: Replaying your commits on a new base · Practise replaying commits somewhere else
taking one commit from another branchgit cherry-pick hash applies that single commit's change onto your current branch as a new commit. For 'I want that one fix over here'. Read: Taking one commit · Practise taking one commit from another branch
committing with no branch attachedA detached HEAD means HEAD points straight at a commit, not at a branch. Looking around is fine; new commits made there have no branch name and can be lost. Read: Looking around without a branch · Practise committing with no branch attached
who last changed this linegit blame file shows, for each line, the commit and author that last changed it. The hash leads to the message, which is where the why lives. Read: Who changed this line, and why · Practise who last changed this line
When git goes wrong · Before you type anything
what to do before you touch anythingThree read-only commands answer where you are, what the history looks like, and what is uncommitted. None of them changes anything, so none of them can make it worse. Read: Look before you touch · Practise what to do before you touch anything
everywhere HEAD has beengit log walks backwards from where you are. git reflog lists where you have BEEN, so a commit you have moved away from is in one and invisible in the other. Read: Everywhere HEAD has been · Practise everywhere HEAD has been
three commands that tell you where you areWhat is uncommitted, what does the history look like from here, and which branch am I on. Everything else follows from those three answers. Read: Three questions, three commands · Practise three commands that tell you where you are
unreachable is not deletedA commit nothing points at is still an object in the repository. It stops appearing in ordinary commands and it does not stop existing. Read: Unreachable is not deleted · Practise unreachable is not deleted
is it the tree or the historyTwo different problems with two different sets of commands. git status answers which one you have, in one line or none. Read: Wrong files, or wrong history · Practise is it the tree or the history
When git goes wrong · Work you have not committed
putting one back, not the lotgit restore takes one named file back. Every other file in the tree is left exactly as it is. Read: One file back to how it was · Practise putting one back, not the lot
taking it out of the next commitgit restore --staged moves a file out of the staging area and leaves the file on disk untouched. Without the flag, the same command overwrites the file instead. Read: Taking it out of the next commit · Practise taking it out of the next commit
clearing out what was never trackedgit clean deletes untracked files -- the ones git has never been told about. Tracked files are left alone entirely. Read: Removing files git never knew about · Practise clearing out what was never tracked
getting a stash backA stash is a commit. The stash list is a set of pointers to those commits, so dropping one removes the pointer and leaves the commit where it was. Read: Getting a stash back · Practise getting a stash back
returning to the branch you were ongit switch - goes to the previous branch, the way cd - goes to the previous directory. And switch exists because checkout did two unrelated jobs. Read: Back to the branch you were on · Practise returning to the branch you were on
When git goes wrong · Work you have committed
undoing a commit, keeping the workgit reset --soft HEAD~1 moves the branch back one commit and leaves everything staged, exactly as it was the moment before you typed commit. Read: Undoing a commit and keeping the work · Practise undoing a commit, keeping the work
soft, mixed and hardThree depths in order. Soft moves the branch. Mixed moves the branch and the index. Hard moves those and your files. Read: Soft, mixed and hard · Practise soft, mixed and hard
rewriting history or recording an undoreset moves the branch backwards and pretends the commit never happened. revert adds a NEW commit that undoes an old one, and leaves the history intact. Read: Rewriting history, or recording an undo · Practise rewriting history or recording an undo
amend replaces, it does not editCommits cannot be changed, so --amend builds a new one and moves the branch to it. The hash is different, and the original is still in the repository. Read: Amend replaces, it does not edit · Practise amend replaces, it does not edit
the commit went on the wrong branchNothing has to move. Point a new branch at the commit, then move the branch you were on back one, and the commit is where it should have been. Read: The commit went on the wrong branch · Practise the commit went on the wrong branch
When git goes wrong · The history moved under you
what force does to everybody elseA normal push only fast-forwards. --force says the branch is whatever you have, and anything on the remote that is not in your history stops being on the branch. Read: What force does to everybody else · Practise what force does to everybody else
merge or replay when you pullPlain pull merges their work into yours and leaves a merge commit. pull --rebase replays your commits on top of theirs and leaves a straight line. Read: Merge or replay, when you pull · Practise merge or replay when you pull
both sides have movedDiverged means you have commits the remote does not AND it has commits you do not. A plain push is refused, because moving the remote to your commit would drop theirs. Read: Both sides have moved · Practise both sides have moved
getting a lost commit backThe reflog names where the branch was before the move that lost it. Point something at that, and the commit is back in the history. Read: Getting a lost commit back · Practise getting a lost commit back
the branch it tracked is gone'gone' means the remote branch your local branch tracks no longer exists. Your branch and its commits are untouched; what is missing is the thing it was compared against. Read: The branch it tracked is gone · Practise the branch it tracked is gone
When git goes wrong · A merge that stopped half way
reading a conflictBetween <<<<<<< and ======= is where you are. Between ======= and >>>>>>> is what is arriving. The label after >>>>>>> names it. Read: Reading a conflict · Practise reading a conflict
the free way out of a merge or rebaseWhile a merge or a rebase is stopped, git is holding the state you started from. --abort puts it back exactly. Read: The free way out · Practise the free way out of a merge or rebase
the stop-resolve-continue loopA rebase replays your commits one at a time, so it can stop once per commit. Staging the resolved file is what tells git you are done with this one. Read: Stop, resolve, continue · Practise the stop-resolve-continue loop
knowing you have finished resolvingTwo checks: git reports no unmerged paths, and no conflict marker is left in any file. Staging a file with markers still in it is entirely possible. Read: Knowing you have finished · Practise knowing you have finished resolving
When git goes wrong · So the next one is smaller
small commits are cheap to undoEvery tool on this road works one commit at a time. If a commit is an afternoon's work, so is the smallest undo you can perform. Read: Small commits are cheap to undo · Practise small commits are cheap to undo
a branch before anything riskyA branch is a small file holding one commit hash. Creating one copies nothing and protects everything it points at from becoming unreachable. Read: A branch before anything risky · Practise a branch before anything risky
a commit is a save, a push is a backupGit being distributed means every clone is complete, not that clones keep each other up to date. A commit lives on your machine until you push it. Read: A commit is a save, a push is a backup · Practise a commit is a save, a push is a backup
marking the known-good pointA tag is a permanent name for a commit. A branch follows you forwards as you commit; a tag stays where it was put. Read: Marking the known-good point · Practise marking the known-good point
the short list git cannot get backEverything git protects is something it was given. An untracked file removed by clean, and an uncommitted edit overwritten by restore or a hard reset, were never objects and have no copies. Read: The short list git cannot get back · Practise the short list git cannot get back