Development environment
Git
Git is a distributed version control system: every commit is a content addressed snapshot, while branches, merges and remotes stay cheap local operations.
Git is a distributed version control system: every clone is a complete repository with the full history, so history and diffs work without a network.
A repository is a content addressed key value store: the key is a digest computed over the content plus a header. A blob is the content of a file, a tree lists a directory, a commit points at a tree root, at its parents, at the author identity and at the message. Identical content yields the same identifier.
A commit is a snapshot
- Git stores a series of snapshots, not a list of changes: every commit points at the whole state of the project.
- Because a commit contains the identifiers of its parents, history is a chain pointing backwards, and a commit’s content plus its ancestry determine its identifier.
- A commit records two distinct roles, the author and the committer, and both are part of the commit object. Authorship is therefore a fact stored in the repository.
- Every project of ours is a Git repository, and our deploys are gated on the commit author being the expected one. We treat authorship as verifiable evidence rather than a formality, while Vercel and similar platforms build their own deploys on the same history.
Branches, merges and conflicts
- A branch is a file holding the identifier of the commit it points at, not a copy of the tree, so creating and deleting one is instant.
- HEAD tells you which branch is current. Switching reverts the working tree to the target branch’s last commit, and when that cannot be done cleanly Git refuses to switch.
- A merge joins two lines of history into a commit with two parents, so the joining is part of the history and needs no separate bookkeeping.
- When changes touch the same region the merge stops and the file receives conflict markers; after resolving them
git merge --continueconcludes it, whilegit merge --aborttries to reconstruct the pre-merge state. - That reconstruction is not guaranteed with non-trivial uncommitted changes at the start, so merge with a clean working tree.
Remotes
- A remote names a repository elsewhere and its location. Cloning creates origin, fetching updates remote-tracking branches, and pushing sends local commits.
- The documented protocols are local, HTTP, SSH and the git scheme. The last uses no encryption and no authentication, so the documentation advises against it: an attacker in the middle can modify the clone.
- Our own Linux server keeps the bare clone and is reached over SSH, and most of the day to day work happens in VS Code.
The index, or staging area
- There are three states, modified, staged and committed, and three places: the working tree, the staging area or index, and the Git directory.
git adddoes not commit; it marks the current version of a file for the next snapshot, so a commit is exactly what you assembled on purpose.git diffcompares the working tree with the index,git diff --stagedthe index with the last commit.
What to watch
- Rewriting history: because a commit contains its parents’ identifiers, changing an old commit changes every identifier after it and forces everyone to re-synchronise.
- Large files: Git stores every version whole and compresses binaries poorly, so repositories grow quickly and every clone downloads the whole history; such files belong behind an extension.
- Authorship: the author name and email address are commit data, so a wrong value stays in the history.
- Git erases little, but uncommitted work can be lost.
Further reading
At CyberElectro Git is the baseline: every project is a repository, and a deploy is gated on the commit author being the expected one.