What is Version Control?
Version control records file history so people can inspect, combine, and recover changes.
Introduction
A version control system keeps the changes to a set of files as a history. You use that history to work with others, review changes, go back to an earlier state, and find when a bug crept in.
Git is the default for most software projects. Jujutsu offers a different set of commands and can sit on top of a Git repository for storage.
Understanding the Concept
A repository holds your files plus the history needed to rebuild any past state of them. Git is distributed, so each normal clone carries that history and can make commits without reaching a central server.
Definition
Repository
The stored history and metadata for a versioned set of files, usually paired with a working directory where those files are edited.
A commit records a snapshot of the project, some metadata, and the IDs of its parents. Those parent links form a directed acyclic graph. A commit with one parent continues a line of history, while a merge commit has multiple parents.
Definition
Commit
An immutable history object that records a project snapshot, metadata, and links to its parent commits.
A branch in Git is just a movable name for a commit. Make a commit while that branch is checked out and the name moves forward with you. A branch stores no commits of its own, it only marks which history you can reach.
Definition
Branch
A movable Git reference that names a commit and advances as new commits are created on that line of development.
A remote is a named pointer to another repository, usually with a fetch and a push URL. A hosting service is where most teams meet, but Git needs no central server to make commits or read local history.
Applying It in Practice
A basic Git workflow creates a branch, records a focused change, and publishes the branch:
git clone https://github.com/org/repo.git
cd repo
git switch -c feature/add-login
# Edit files
git add src/auth/login.ts
git commit -m "Add login form"
git push -u origin feature/add-login
The index, or staging area, holds the snapshot Git will turn into your next commit. git add copies the file content you pick into it. That way one working directory can hold several edits while a commit takes only the ones you chose.
Definition
Index
Git's per-worktree staging data, which defines the file snapshot used by the next commit.
Inspect changes before committing:
git status
git diff
git diff --staged
Use git log to read ancestry, git show for one commit, and git blame to trace a line back to its commit. Use git revert to undo a published change with a new one. Discarding uncommitted changes is a different thing, and it cannot be undone. Commands that rewrite history, such as rebase and reset, need more care, because other work may sit on the old commit IDs.
Git and Jujutsu
Jujutsu works differently. In the usual colocated setup, Jujutsu and Git share the same commits and refs, and Jujutsu keeps extra metadata about operations and changes on the side.
Jujutsu has no staging area. Your working copy is itself a commit, which Jujutsu updates as you edit files. Bookmarks act like Git branches, but Jujutsu keeps a change's stable change ID apart from the commit IDs it gets each time you rewrite it.
jj git clone https://github.com/org/repo.git
cd repo
jj new -m "Add login form"
# Edit files
jj diff
jj status
jj bookmark create feature/add-login
jj git push --bookmark feature/add-login
Jujutsu also logs every command that changes the repository. jj undo reverses the last one, and jj op log shows earlier states. Git gives you the same kind of rescue at a lower level, through refs and reflogs.
Pick Jujutsu because its working-copy, conflict, and history-editing model suits your team. Do not pick it expecting Git hosting and tooling to go away, because most collaboration still crosses a Git boundary.
Engineering Considerations
A commit should hold one coherent change and say why in its message. Small commits that still build are easier to review and make git bisect far more useful.
Treat published history as an interface. Rewriting a private branch is routine. Rewriting a branch that others use changes commit IDs beneath their work and requires coordination, which is the problem stacked PRs are built to manage.
Version control is not a backup. A clone can leave out unreachable objects, local-only refs, server settings, issue data, release assets, and large files. Back up the hosting service and any outside artifact stores on their own.
Git keeps file contents in its object database, so large binaries that change often bloat history fast. Git LFS puts a small pointer file in Git and moves the real object through a separate service.
Scaling and Operations
Large repositories may need partial clone, sparse checkout, commit-graph upkeep, or a filesystem monitor. Reach for these only after you measure which step is slow: fetching objects, walking history, or scanning the working tree.
Guard main and release branches with required review and CI. Reject force pushes wherever history has to stay put, and decide up front whether a feature branch can be rewritten once review starts.
Keep generated files, credentials, and build output out of commits unless the project versions them on purpose. Deleting a secret in a later commit does not remove it from old history, so revoke the credential first and clean the history second.
Next Steps
- What are Git Worktrees?: use several working directories with one repository
- Git Worktrees vs Clones: compare shared and independent repositories
- Merge vs Rebase: choose how to integrate diverged histories
- What are Stacked PRs?: organize dependent changes for review