skip to content

Git

26 roadmaps245 questionsupdated

The distributed version control system underneath everything: how commits are stored, how branches move, how work is merged or rebased, and how mistakes are undone. Interviews go deeper here than in most tool areas, because knowing the object model is what separates memorised commands from real understanding.

on this pageshow

guide

overview

~1 min

Git is a distributed version control system built on a small idea: every commit is a complete, content-addressed snapshot, and branches, tags and `HEAD` are names that point at those snapshots. Interviewers dig further into Git than into most tools because the commands are easy to memorise and the model underneath them is not. A candidate who can say which pointer moved, which object was created and what is still reachable can reason through an unfamiliar command; one who memorised recipes stalls at the first surprise. The hub follows the life of a change. [The object model and DAG](/topics/dev-git-object-model) is the foundation everything else refers to. [Staging and commits](/topics/dev-git-staging-commits) covers how a change becomes a commit, and [branching and merging](/topics/dev-git-branching-merging) and [rebase and history rewriting](/topics/dev-git-rebase-history) cover the two ways work is combined. [Remotes and collaboration](/topics/dev-git-remotes-collaboration) is where local history meets everyone else's, and [stash, reflog and recovery](/topics/dev-git-stash-reflog-recovery) and [inspecting history](/topics/dev-git-inspecting-history) are the toolkits for undoing and investigating. Around the core sit [hooks](/topics/dev-git-hooks), [submodules, subtrees and worktrees](/topics/dev-git-submodules-worktrees), [branching workflows](/topics/dev-git-workflows) and [configuration, ignore rules and attributes](/topics/dev-git-config-attributes). Junior rounds check the daily vocabulary: what staging is for, what fetch does that pull does not, how to read a conflict. Senior rounds turn into scenarios — a bad force-push, a lost commit, a release that shipped without its hotfix — and into team-level trade-offs between workflows, merge policies and where a check belongs. Learn the object model and the three trees first. Merge, rebase, remotes and recovery all become pointer arithmetic once those are clear.

primer

### Commits are snapshots, not diffs A commit names one tree — the full state of every tracked file — plus its parents and some metadata. Diffs are computed on demand by comparing two snapshots. Keeping that straight explains why checkout is fast, why a rename is detected rather than recorded, and why "undoing a commit" can mean several different operations. ### Everything is addressed by content Blobs, trees, commits and annotated tags are stored under the hash of their contents. Change one byte anywhere and every hash above it changes, which is what makes history tamper-evident and why any edit to an old commit produces a new commit rather than a modified one. **Rewriting history** always means making new objects and moving names. ### Names are cheap pointers A branch is a ref that stores a single commit id; `HEAD` usually names a branch, and sometimes a commit directly. Creating, deleting and moving branches costs almost nothing, so most Git commands reduce to "which pointer moves, and to where". Reachability from those names decides what `git log` shows and what garbage collection may eventually delete. ### Three trees stand between you and a commit The working tree is what you edit, the **index** is the commit you are proposing, and `HEAD` is the commit you last made or checked out. `add`, `commit`, `reset`, `restore` and both forms of `diff` are each defined by which of those three they read and which they write. Interviewers treat this as the entry test for the undo questions. ### Integration is a choice about history Merging keeps what happened and records the join; rebasing replays your work so history reads as if it happened in order. Both start from the merge base. The choice is about who else already has your commits, what reviewers will read, and how much bisect and blame matter later. ### Local first, then shared An ordinary clone is a full repository. Remote-tracking refs are your last snapshot of someone else's branches, refreshed only by fetch. Anything you have not pushed is private and can be rewritten freely; anything others have fetched is a contract, and rewriting it has a cost you must name. ### Almost nothing is lost immediately Commits that no branch points at stay in the object store until garbage collection, and the reflog remembers where each ref pointed before. Uncommitted work is the real exception: a hard reset or a forced checkout can overwrite unstaged edits with no record to recover them from.

Blob
The object storing one file's contents, with no name or permissions. Identical content anywhere in history is stored once.
Tree
The object representing one directory: a list of names, modes and the hashes of the blobs and subtrees beneath it.
Commit object
A snapshot pointer: one root tree, zero or more parent commits, author and committer identity, timestamps and a message.
Ref
A human-readable name, such as a branch, tag or remote-tracking branch, that resolves to an object id.
HEAD
The ref that marks what is currently checked out. Normally it names a branch; when it holds a commit id directly, HEAD is detached.
Index
Also called the staging area: the file describing the tree the next commit will record, built up with add and reset to match a commit by reset.
Commit DAG
The directed acyclic graph formed by commits pointing at their parents. Ancestry, ranges and merge bases are all questions about this graph.
Merge base
The best common ancestor of two commits, used as the reference point for a three-way merge and for triple-dot ranges.
Fast-forward
Advancing a branch to a descendant commit by moving its pointer, with no merge commit, possible only when no divergence exists.
Rebase
Replaying a series of commits onto a new base, producing new commits with new ids and moving the branch to the last one.
Remote-tracking ref
A local, read-only record such as origin/main of where a remote branch pointed at the last fetch.
Refspec
A source-to-destination mapping that tells fetch and push which refs to transfer and which local or remote names to update.
Reflog
A local, per-ref journal of the values a ref has held, used to find commits that no branch still reaches.
Packfile
A compressed file holding many objects, often as deltas against similar objects, used for storage and network transfer.
Submodule
A nested repository recorded in the parent as a pinned commit id at a path, with its URL kept in .gitmodules.
Worktree
An additional checkout with its own working directory, index and HEAD, sharing the object store and refs of one repository.

Almost every section of the hub is a view of the same three layers: objects in the store, refs that name them, and the three trees you work in. A commit writes new objects and moves the branch `HEAD` names. A merge or rebase reads the DAG to find the merge base, writes new commits, and moves a branch. Fetch brings objects across and refreshes remote-tracking refs; push asks the other side to move its refs, and refuses by default when that would drop commits. Reset moves a branch and optionally rewrites the index and the files on disk; the reflog records the move, which is why most recovery questions end in the reflog. The surrounding sections attach to the same points: - **Hooks** run at the moments a ref is about to change or has changed — before a commit is written, before a push is sent, when a server receives one. - **Submodules** are a special tree entry that stores a commit id of another repository; **worktrees** are extra sets of the three trees over one object store. - **Workflows** are conventions about which refs exist, who moves them and whether shared ones may be rewritten. - **Configuration and attributes** decide how the working tree is converted to blobs and back, and how diff and merge treat particular paths. Plumbing commands let you look at the layers directly. Reading them once removes most of the mystery from the porcelain: ```bash git cat-file -p HEAD # tree, parents, author, committer, message git cat-file -p 'HEAD^{tree}' # names and modes pointing at blobs and subtrees git rev-parse main origin/main # two refs, two commit ids, nothing more git merge-base main origin/main # the commit both histories share git reflog -5 main # where main pointed before its last moves ``` A strong answer to almost any scenario question walks the same route: which objects exist, which refs point where before and after, and what is still reachable afterwards.

  1. Object Model and DAG →

    Objects, refs and the DAG are the vocabulary every other section uses; answers elsewhere assume you can reason about hashes and reachability.

  2. Staging and Commits →

    The working tree, index and HEAD, and how a change becomes a commit; the undo commands only make sense after this.

  3. Branching and Merging →

    Branches as pointers, fast-forwards and three-way merges, and reading conflicts: the everyday half of working with others.

  4. Remotes and Collaboration →

    Fetch, pull, push and remote-tracking refs, where local history meets a shared one and non-fast-forward rejections appear.

  5. Rebase and History Rewriting →

    Rewriting history deliberately, and the rules for when it is safe, once merging and remotes are clear.

  6. Stash, Reflog, and Recovery →

    The recovery toolkit that turns most 'I lost my work' scenarios into finding a commit and pointing a name at it.

  • Describing a commit as a diff or a list of changes: it records a full snapshot, and diffs are computed between snapshots when asked.

  • Treating git pull as a download: it also merges or rebases into your current branch, which is why fetch alone is the safe way to look.

  • Rebasing or force-pushing a branch others have already fetched, then being surprised when their next pull duplicates or resurrects commits.

  • Reaching for reset --hard to undo a pushed commit on a shared branch, where a revert keeps history forward-only and avoids a forced push.

  • Claiming reset --hard destroys commits: they stay reachable through the reflog for a while; it is uncommitted working-tree changes that are gone.

  • Adding a committed file to .gitignore and expecting Git to stop tracking it; ignore rules only affect paths that are not yet tracked.

  • Reading origin/main as the live state of the server: it is a local snapshot from the last fetch, so ahead and behind counts can be stale.

  • Using .. and ... interchangeably; they select different commits in git log and compare different trees in git diff — see Log and Revision Filtering.

  • Putting slow, whole-project checks in a pre-commit hook: hooks are local and skippable, so anything that must hold belongs in CI or a server-side hook.

This guide assumes a current Git 2.x release. A handful of changes along the 2.x line still come up, because interviewers learned Git at different points and teams run different versions: - **2.0** made `push.default=simple` the default, so a bare push sends only the current branch to its upstream, and made `git add` on a path stage removals as well. - **2.23** added `git switch` and `git restore`, splitting the branch-switching and file-restoring jobs that `git checkout` had combined. Older answers use checkout for both; either is correct if you name what it does. - **2.28** added `init.defaultBranch`, which is why new repositories may start on `main` or `master` depending on configuration and hosting defaults. - **2.29** introduced SHA-256 repositories as an experimental object format; SHA-1 remains the default and interoperability between the two is still limited. - **2.34** made `ort` the default merge strategy, replacing `recursive` for ordinary two-branch merges. When an answer depends on one of these — the command you would type, the push behaviour, the default branch name — say which era you are describing.

Git replaced centralised systems such as Subversion and CVS for most software work. The trade-off interviewers expect you to name: a centralised system keeps one authoritative history on a server and supports path-level locking, while Git gives every clone full history, cheap local branches and offline work, at the cost of weaker handling of large binary files and no built-in locking. Mercurial is the closest distributed peer and is far less common today; Perforce remains common where huge binary assets dominate, as in game development. Around Git sit the hosting platforms — GitHub, GitLab, Bitbucket and self-hosted servers — which add pull or merge requests, review, branch protection and CI. None of those are Git features, and a good answer keeps the line clear: a protected branch is a server policy, a pull request is a hosting-platform object, while a ref and a hook belong to Git. Git LFS stores large files outside the repository behind small pointer files, and hook managers such as husky, lint-staged and the pre-commit framework distribute client-side checks across a team. At large scale, partial clone, sparse checkout and monorepo tooling address repositories that outgrow a plain full clone.

explore

report an issue with this guide →

questions

245 · 11 sections

In Git, what does a commit record about its predecessors, and why is history a DAG?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Each Git commit stores an ordered list of parent commit IDs: zero for a root commit, one for an ordinary commit, two or more for a merge. Following those pointers backwards yields a directed acyclic graph, not a straight line.

open as a page

In Git, what is HEAD, and how does it differ from a branch name?

level: juniorimportance: must knowfreq 70%
basics
~20 s

HEAD is a pointer to whatever you currently have checked out. Normally it is a symbolic ref holding the name of a branch, such as refs/heads/main, while the branch itself is a ref holding one commit hash.

open as a page

In Git, what is the difference between HEAD~2 and HEAD^2?

level: middleimportance: must knowfreq 72%
basics
~20 s

In Git, HEAD~2 walks two steps back along the first-parent chain, i.e. the grandparent. HEAD^2 takes one step to the second parent, which exists only on a merge commit; on a non-merge it is an error.

open as a page

In git log, what does main..feature select, and how does main...feature differ?

level: middleimportance: must knowfreq 68%
basics
~20 s

In git log, main..feature lists commits reachable from feature but not from main. main...feature lists the symmetric difference: commits reachable from either side but not both. In git diff, three dots means something else — merge base against the right side.

open as a page

In Git, what does a commit object actually store?

level: middleimportance: must knowfreq 82%
basics
~10 s

A commit stores the hash of one tree (a full snapshot of the tracked files), the hashes of its parent commits, author and committer identity with timestamps, and the message. It stores no diff.

open as a page

What does git commit --amend --no-edit do, and why does the commit SHA change?

level: juniorimportance: must knowfreq 80%
basics
~20 s

git commit --amend replaces the tip commit with a brand-new commit built from the current index, and --no-edit reuses the old message. A commit's name is a hash of its whole content, including the committer timestamp, so the replacement gets a new SHA.

open as a page

How should a Git commit message be structured, and what is the 50/72 convention?

level: juniorimportance: must knowfreq 66%
basics
~20 s

A Git commit message is a short subject line, a blank line, then an optional body. The convention keeps the subject under about 50 characters and wraps body lines at 72. The blank line is the part Git itself depends on.

open as a page

In Git, how do git add -A, git add -u, and git add . differ?

level: juniorimportance: must knowfreq 68%
basics
~20 s

In modern Git, add -A stages new, modified and deleted paths across the whole working tree; add -u stages modifications and deletions for already-tracked paths only, never new files; add . does what -A does but limited to the current directory and below.

open as a page

In Git, what are the working tree, the index, and HEAD?

level: juniorimportance: must knowfreq 82%
basics
~20 s

Git juggles three trees: the working tree (your files on disk), the index or staging area (the proposed next commit), and HEAD (the commit you are on). git add copies working tree into index; git commit turns the index into a commit.

open as a page

What does git add -p do, and why would you stage only part of a file?

level: middleimportance: must knowfreq 62%
basics
~20 s

git add -p walks the diff between your working tree and the index hunk by hunk and asks whether to stage each one. Only the accepted hunks enter the index, so one messy file can become several focused commits.

open as a page

In Git, what does creating a branch with git branch feature actually do?

level: juniorimportance: must knowfreq 82%
basics
~20 s

It writes one new ref holding the hash of the commit you branched from. No files are copied and no history is duplicated, which is why branching is instant in a repository of any size.

open as a page

In Git, what do the <<<<<<<, =======, and >>>>>>> markers in a conflicted file mean?

level: juniorimportance: must knowfreq 85%
basics
~20 s

Git writes both versions of a region it could not merge into the file. Text between <<<<<<< and ======= is the side you are on; text between ======= and >>>>>>> is the incoming side. You edit the file to the final content, delete the markers, and stage it.

open as a page

In Git, what is a fast-forward merge and when can Git perform one?

level: juniorimportance: must knowfreq 80%
basics
~20 s

A fast-forward merge happens when the current branch's commit is already an ancestor of the commit being merged. Git records no merge commit; it simply moves the branch pointer forward and updates the index and working tree.

open as a page

In Git, what is a three-way merge and which three commits does it use?

level: juniorimportance: must knowfreq 68%
basics
~20 s

A three-way merge combines two branch tips using their best common ancestor, the merge base, as a reference point. Comparing each tip against that base tells Git which side changed what, so it can combine changes instead of guessing.

open as a page

In Git, what is a detached HEAD and how do you rescue commits made in one?

level: middleimportance: must knowfreq 68%
basics
~20 s

HEAD is detached when it names a commit directly instead of a branch, so commits you make advance nothing. Rescue them by creating a branch at that commit — git switch -c <name> before leaving, or git branch <name> <hash> from the reflog afterwards.

open as a page

In Git, what does git cherry-pick do to the commit you name?

level: juniorimportance: must knowfreq 70%
basics
~20 s

It applies that commit's change on top of your current branch and creates a new commit for it. The original commit stays where it is; the copy has a different SHA because its parent, committer and timestamp differ.

open as a page

In Git, why is force-pushing to a shared branch dangerous?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A forced push overwrites the remote branch pointer even when the new tip is not a descendant of the old one, so commits other people pushed can stop being reachable and everyone who already fetched the branch now has a history that diverges from it.

open as a page

In Git, what happens when you run git rebase -i HEAD~3?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Git opens an editor holding a todo list of the three commits after HEAD~3, oldest first, each on a pick line. You edit the verbs and the order, save, and Git replays the commits as scripted, creating new commit IDs.

open as a page

In Git, what is the difference between merging main into your branch and rebasing onto it?

level: juniorimportance: must knowfreq 85%
basics
~20 s

Merging adds a new commit that joins both histories and leaves your existing commits untouched. Rebasing re-creates your commits on top of main's tip as new commits with new hashes, producing a straight line with no merge commit.

open as a page

In Git, why does deleting a file and committing not remove it from history?

level: juniorimportance: must knowfreq 55%
basics
~20 s

A Git commit only adds a new snapshot. Every earlier commit still references the blob holding that file, so the content stays reachable and clonable until history itself is rewritten and the old objects are pruned.

open as a page

In Git, what does cloning with --depth 1 actually download, and what is missing?

level: juniorimportance: must knowfreq 72%
basics
~20 s

git clone --depth 1 downloads only the tip commit of a single branch plus the trees and file contents needed to check it out. Older history and other branches are absent, so log and blame reach back one commit.

open as a page

What is the difference between git fetch and git pull?

level: juniorimportance: must knowfreq 88%
basics
~20 s

git fetch downloads new objects and updates remote-tracking refs such as origin/main, leaving your branch and working tree untouched. git pull runs that same fetch and then immediately integrates the result into your current branch by merging or rebasing.

open as a page

In a forked repository, what do the Git remotes named origin and upstream conventionally point to?

level: juniorimportance: must knowfreq 68%
basics
~10 s

By convention origin is your own fork, the copy you can push to, and upstream is the original project you forked from and normally only fetch from. Git gives neither name any special meaning.

open as a page

In Git, how do you delete a remote branch, and what does git push origin :feature mean?

level: juniorimportance: must knowfreq 65%
basics
~20 s

Use git push origin --delete feature. The older equivalent, git push origin :feature, is a refspec with an empty source: pushing nothing onto the destination ref deletes it. Both remove only the remote branch, never your local one.

open as a page

In Git, what does git remote add origin <url> actually change in your repository?

level: juniorimportance: must knowfreq 55%
basics
~20 s

It only edits .git/config, adding a remote section with a url and a default fetch refspec. No network call happens and no objects arrive until you run git fetch, and the name origin is purely local.

open as a page

After git reset --hard discarded your last three commits, how do you get them back?

level: juniorimportance: must knowfreq 74%
basics
~20 s

Nothing was deleted: git reset --hard only moved the branch pointer. Find the old tip's hash with git reflog, verify it with git show, then re-anchor it using git branch rescue <hash> or git reset --hard <hash>.

open as a page

In Git, how does git reflog differ from git log?

level: juniorimportance: must knowfreq 70%
basics
~20 s

git log walks commit ancestry from a ref, showing shared project history. git reflog lists a local journal of where HEAD or a branch has pointed over time, newest first, including commits no longer reachable from any branch.

open as a page

In Git, how do you unstage a file without losing the edits in your working tree?

level: juniorimportance: must knowfreq 76%
basics
~10 s

Run git restore --staged <file>. It rewrites that path in the index from HEAD, leaving the file on disk exactly as you edited it. The older equivalent is git reset -- <file>.

open as a page

In Git, what is the difference between git stash pop and git stash apply?

level: juniorimportance: must knowfreq 74%
basics
~20 s

Both restore a saved stash into your working tree; pop also deletes the stash entry afterwards, while apply leaves it in the list. If a pop hits a conflict, the entry is kept, so nothing is lost.

open as a page

In Git, how does HEAD@{2} differ from HEAD~2?

level: middleimportance: must knowfreq 58%
basics
~10 s

HEAD~2 is graph navigation: two commits back along parent links from the current commit. HEAD@{2} is reflog navigation: the commit HEAD pointed at two ref movements ago, regardless of ancestry.

open as a page

What does git blame report for each line, and what can it not tell you?

level: juniorimportance: must knowfreq 60%
basics
~20 s

git blame annotates every line of a file with the commit that last modified it, plus that commit's author and date. It shows only the most recent touch, never the line's full history, and it says nothing about deleted lines.

open as a page

What does git diff show by default, and how does git diff --staged differ?

level: juniorimportance: must knowfreq 85%
basics
~20 s

Plain git diff compares the working tree against the index, showing changes you have not staged yet. git diff --staged (identical to --cached) compares the index against HEAD, showing exactly what the next commit would contain.

open as a page

What do the git log flags --oneline, --graph, and --decorate each add to the output?

level: juniorimportance: must knowfreq 70%
basics
~20 s

In git log, --oneline prints one abbreviated-hash-plus-subject line per commit, --graph draws the commit DAG as ASCII art down the left margin, and --decorate appends the ref names — branches, tags, HEAD — that point at each commit.

open as a page

What does git show display for a commit, and how does it differ from git diff?

level: juniorimportance: should knowfreq 45%
basics
~20 s

git show prints one object: for a commit it prints the metadata and log message plus the patch against its first parent. git diff prints only a patch between two snapshots and never shows commit metadata.

open as a page

How do you make git blame skip a mass-reformatting commit?

level: middleimportance: should knowfreq 40%
basics
~20 s

List the reformatting commit's full id in a file and point Git at it: git blame --ignore-rev <sha>, or --ignore-revs-file <file>, or set blame.ignoreRevsFile so it applies automatically. Blamed lines are then attributed to the previous commit that touched them.

open as a page

In Git, what happens when a client-side hook such as pre-commit exits with a non-zero status?

level: juniorimportance: must knowfreq 62%
basics
~10 s

A non-zero exit from a pre-operation hook such as pre-commit, commit-msg or pre-push aborts the operation — no commit is created, no push is sent. Post-hooks like post-commit run afterwards and cannot abort anything.

open as a page

How do Git's pre-commit, prepare-commit-msg and commit-msg hooks differ during one git commit?

level: middleimportance: must knowfreq 55%
basics
~20 s

They fire in that order during one git commit: pre-commit inspects the staged content before any message exists, prepare-commit-msg seeds or rewrites the message file before the editor opens, and commit-msg validates the final message. All three can abort by exiting non-zero.

open as a page

Why don't Git hooks in .git/hooks travel with a clone, and how do teams share them?

level: middleimportance: must knowfreq 62%
basics
~20 s

Hooks live in .git/hooks, part of the repository metadata that is never committed, so a clone never copies them. Teams instead commit hook scripts to a tracked directory and point Git at it with the core.hooksPath config setting.

open as a page

In Git, how do the pre-receive and update hooks differ on the repository receiving a push?

level: middleimportance: must knowfreq 48%
basics
~20 s

pre-receive runs once per push and reads every proposed ref update on stdin, so a non-zero exit rejects the whole push. update runs once per ref with the ref name and old and new object names as arguments, and rejecting there blocks only that one ref.

open as a page

What does lint-staged run your checks against, and why use it in a Git pre-commit hook?

level: juniorimportance: should knowfreq 50%
basics
~20 s

lint-staged runs the commands you configure only against the files currently staged in Git's index, not the whole project. That keeps a pre-commit hook proportional to the change, so it finishes fast and only reports problems in code you touched.

open as a page

After cloning a repo with Git submodules, why are the submodule directories empty?

level: juniorimportance: must knowfreq 65%
basics
~20 s

A plain clone fetches only the superproject, which records submodules as commit references rather than files, so it creates the directories but leaves them empty. Clone with --recurse-submodules, or run git submodule update --init --recursive afterwards.

open as a page

What does git worktree add create, and how does it differ from a second git clone?

level: juniorimportance: must knowfreq 45%
basics
~20 s

It creates an additional working directory with its own checked-out branch, backed by the same repository. Unlike a second clone it shares one object database and one set of branches, so it costs no extra fetch and no duplicated history.

open as a page

What are the trade-offs of git subtree versus git submodule for someone who only clones your repo?

level: middleimportance: must knowfreq 48%
basics
~20 s

Subtree stores the dependency's actual files in your repository, so a plain clone builds immediately; submodules store only a pinned pointer, so consumers need an extra recursive step. Subtree costs repository size and a mixed history.

open as a page

Which repository state do Git worktrees share, and which is private to each worktree?

level: middleimportance: must knowfreq 40%
basics
~10 s

Objects, refs, remotes and repository config are shared by all worktrees. Each worktree keeps its own working directory, index, HEAD, HEAD reflog and in-progress operation state, stored in .git/worktrees/<name> inside the original repository.

open as a page

In Git, which branches does the Git Flow model define and what is each one for?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Git Flow defines two permanent branches, main and develop, plus three temporary types: feature branches cut from develop, release branches cut from develop, and hotfix branches cut from main. Releases and hotfixes merge back into both permanent branches.

open as a page

Why doesn't a new Git tag like v1.4.0 reach the remote after git push, and how do you send it?

level: juniorimportance: must knowfreq 62%
basics
~20 s

A plain git push sends branch refs only; tags live in refs/tags and are excluded by the default refspec. Push one explicitly with git push origin v1.4.0, or push a branch plus its reachable annotated tags with git push --follow-tags.

open as a page

What is trunk-based development, and how long do its branches live in Git?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Trunk-based development means everyone integrates into one shared branch — the trunk, usually main — continuously. Branches off it are short-lived, typically merged back within a day or two, so the repository never accumulates long-running parallel lines of development.

open as a page

In Git, what does git format-patch produce, and how does a maintainer apply it?

level: middleimportance: must knowfreq 45%
basics
~20 s

git format-patch writes one mbox-formatted file per commit, containing the message plus the diff and author metadata. A maintainer replays them with git am, which recreates the commits with their original author, date and message rather than just applying a diff.

open as a page

How do you split a large Git change into a series of commits a maintainer can review?

level: middleimportance: must knowfreq 55%
basics
~20 s

Make each commit one self-contained step that builds and passes tests on its own: preparation and refactoring first, behaviour change second, then tests and docs. Order them so a reviewer reading top to bottom sees the change being argued, not assembled.

open as a page

In Git, how do the --system, --global and --local config scopes differ, and which one wins?

level: juniorimportance: must knowfreq 70%
basics
~10 s

They name three config files: machine-wide, per-user, and per-repository. Git reads them in that order and the narrower scope wins, so a repository's .git/config overrides your home-directory settings, which override the system file.

open as a page

In Git, why does adding an already-tracked file to .gitignore have no effect?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Git ignore rules apply only to untracked paths. Once a file has an entry in the index, Git keeps reporting and committing its changes whatever .gitignore says. Untrack it with git rm --cached, then commit that removal.

open as a page

In Git, why does a file show every line as changed after a Windows teammate edits it?

level: juniorimportance: must knowfreq 50%
basics
~10 s

The file's line endings switched between LF and CRLF. Git compares whole lines, so an invisible carriage return at the end of every line makes every line differ and the whole file looks rewritten.

open as a page

In Git, what does a .gitattributes file control, and how are its rules resolved?

level: middleimportance: must knowfreq 50%
basics
~10 s

A .gitattributes file assigns per-path attributes that change how Git diffs, merges, filters and archives matching files. Patterns use .gitignore syntax; within one file the last matching line wins, and .git/info/attributes outranks committed files.

open as a page

In a Git .gitignore file, what do a leading slash, a trailing slash, and ** match?

level: middleimportance: must knowfreq 66%
basics
~20 s

A leading slash anchors a Git ignore pattern to the directory holding the .gitignore instead of matching at any depth. A trailing slash restricts the match to directories. Double asterisk matches across directory separators, which a single asterisk never does.

open as a page