Overview
- 1Git is a free, open-source distributed version control system (DVCS) that lets every developer hold a full copy of a repository's history locally.
- 2Unlike centralized systems, most Git operations (commit, diff, log, branch) happen offline against the local repository, making them extremely fast.
- 3Git tracks content as snapshots of a directory tree rather than file-by-file diffs, and identifies every object (blob, tree, commit) with a SHA hash for integrity.
- 4Hosting platforms like GitHub, GitLab, and Bitbucket layer pull requests, code review, issue tracking, and CI/CD on top of core Git.
- 5Git underpins modern DevOps and GitOps practices, where a repository becomes the single source of truth for application code, configuration, and infrastructure state.
Key Features in 2.47
Distributed model — every clone is a full backup of the repository with complete history, no single point of failure.
Cheap, fast branching and merging that encourages short-lived feature branches and frequent integration.
A staging area (the index) that lets you craft precise, logical commits with `git add -p` instead of committing everything at once.
Content-addressable storage using SHA hashes, so any corruption or tampering in history is immediately detectable.
Powerful history tools like `git log`, `git blame`, `git bisect`, and `git reflog` for auditing and debugging changes over time.
`git worktree` for checking out multiple branches into separate working directories from a single repository.
Partial clone and `git sparse-checkout` for working efficiently with very large monorepos by fetching only the objects and paths you need.
Use Cases
- →Team software development using feature branches, pull requests, and code review before merging into a shared mainline.
- →Open-source collaboration via the fork-and-pull-request model, where contributors propose changes without direct write access.
- →Triggering CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins) on commits, tags, or pull requests to build, test, and deploy automatically.
- →GitOps-style infrastructure and configuration management, where tools like ArgoCD or Flux continuously reconcile a cluster's state against a Git repository.
Core Concepts
- A repository (`git init` or `git clone <url>`) stores the full history in a hidden `.git` directory of objects and refs.
- The working directory, staging area (index), and repository form Git's three-tree model — `git add` moves changes from working directory to index, `git commit` records them permanently.
- Every commit stores a snapshot of the tree, a pointer to its parent(s), author/committer metadata, and a message, all hashed into a unique SHA.
- `HEAD` is a pointer to the current commit, usually via a branch reference like `refs/heads/main`.
- Branches are just lightweight, movable pointers to a commit — `git branch feature-x` creates one instantly without copying files.
- Tags (`git tag v1.0.0`) mark specific commits permanently, commonly used for releases; annotated tags also store metadata and can be signed.
- `.gitignore` tells Git which files or patterns (build artifacts, `node_modules`, `.env`) to never track.
Branching & Merging Workflows
- `git switch -c feature-x` (or the older `git checkout -b feature-x`) creates and switches to a new branch for isolated work.
- `git merge feature-x` integrates changes; Git performs a fast-forward if possible, or creates a merge commit when histories have diverged.
- `git rebase main` replays a branch's commits on top of another branch's tip, producing a linear history instead of a merge commit.
- Interactive rebase (`git rebase -i HEAD~5`) lets you reorder, squash, reword, or drop commits before sharing a branch.
- Merge conflicts appear as conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) in affected files; resolve them, then `git add` the files and continue with `git merge --continue` or `git rebase --continue`.
- Common team models include trunk-based development (short-lived branches merged frequently into `main`) and the older Git Flow model with `develop`, `release`, and `hotfix` branches.
- Never rebase commits that have already been pushed and shared with others, since it rewrites commit hashes and history.
Undoing Changes & History
- `git reset --soft HEAD~1` undoes the last commit but keeps changes staged; `--mixed` (default) unstages them too; `--hard` discards them entirely.
- `git revert <commit>` creates a new commit that undoes a previous one, making it safe to use on shared/public branches.
- `git stash` temporarily shelves uncommitted changes so you can switch context; `git stash pop` reapplies and removes the latest stash.
- `git commit --amend` edits the most recent commit's message or contents before it is pushed.
- `git cherry-pick <commit>` applies the changes from a specific commit onto the current branch.
- `git bisect start` performs a binary search through history to find the commit that introduced a bug, using `git bisect good`/`bad` markers.
- `git reflog` records every place `HEAD` has pointed, letting you recover commits even after a `reset --hard` or a deleted branch.
GitHub, GitOps & Collaboration
- Remotes (`git remote add origin <url>`) reference other copies of a repository; `git fetch` downloads their history without merging, `git pull` fetches and merges (or rebases with `git pull --rebase`).
- Pull requests (GitHub) or merge requests (GitLab) wrap a branch's changes in a reviewable, discussable unit before merging, often gated by required approvals and status checks.
- GitHub Actions and similar CI/CD tools run workflows defined in YAML (e.g. `.github/workflows/ci.yml`) triggered by pushes, pull requests, or tags to test and deploy code automatically.
- Conventional Commits (`feat:`, `fix:`, `chore:`) standardize commit messages so tools can auto-generate changelogs and determine semantic version bumps.
- Branch protection rules can require passing checks, signed commits, or reviews before allowing merges to `main`, preventing broken code from landing directly.
- GitOps extends this model to infrastructure: tools like ArgoCD and Flux watch a Git repository containing Kubernetes manifests and continuously reconcile the live cluster to match it.
- Forking a repository creates your own server-side copy, letting you contribute to projects you don't have write access to via pull requests from your fork.
Frequently Asked Questions
What is the difference between git merge and git rebase?▼
`git merge` combines two branches by creating a new merge commit that ties their histories together, preserving exactly what happened and when. `git rebase` instead replays your branch's commits on top of another branch, producing a clean, linear history with no merge commit. Merge is safer for shared branches since it never rewrites existing commits, while rebase is best used on your own local, unpushed work to keep history tidy before merging.
How do I undo a git commit?▼
If the commit hasn't been pushed, `git reset --soft HEAD~1` undoes it while keeping your changes staged, or `git reset --hard HEAD~1` discards the changes entirely. If the commit has already been pushed and shared with others, use `git revert <commit>` instead, which creates a new commit that reverses the changes without rewriting history. `git reflog` can recover a commit if you reset too aggressively and need it back.
Git vs SVN — what is the difference?▼
Git is a distributed version control system where every developer has a complete local copy of the repository's history, so most operations are offline and fast. SVN (Subversion) is centralized, meaning the full history lives only on a central server and most actions require network access to it. Git's distributed model also makes branching and merging cheap and encourages frequent feature branches, whereas SVN branching is comparatively heavier and less commonly used.
What is git stash used for?▼
`git stash` temporarily saves your uncommitted changes (both staged and unstaged) and reverts your working directory to match the last commit, without creating a commit. This is useful when you need to switch branches quickly, pull in upstream changes, or fix an urgent bug without losing in-progress work. Run `git stash pop` to reapply and remove the most recent stash, or `git stash list` to see all stashed changes.
What is the difference between git fetch and git pull?▼
`git fetch` downloads new commits, branches, and tags from a remote repository but does not change your current working branch or merge anything. `git pull` is essentially `git fetch` followed immediately by a `git merge` (or `git rebase` with the `--rebase` flag) into your current branch. Using `fetch` first lets you inspect incoming changes with `git log origin/main` before deciding how to integrate them.
What is a detached HEAD state and how do I fix it?▼
A detached HEAD happens when you check out a specific commit or tag directly (e.g. `git checkout a1b2c3d`) instead of a branch, so `HEAD` points straight at a commit rather than moving with a branch pointer. Any new commits made in this state are not attached to a branch and can be lost once you check out something else, unless you create a branch to save them. To fix it, run `git switch -c new-branch-name` while still in the detached state to attach your work to a proper branch, or simply `git switch main` to return to your usual branch if you made no changes.