Git Guide for Developers
Every professional software project today—whether open source or enterprise, tiny script or massive monorepo—relies on version control. Among version control systems, Git has emerged as the clear, universal standard. It’s fast, distributed, and flexible enough to support everything from solo hobby projects to the Linux kernel’s millions of lines of code.
This guide takes you from installing Git on your machine to confidently collaborating with teams using branching, merging, and remote workflows. You’ll learn not just the commands, but the reasoning behind them. Whether you’re a beginner or an experienced developer looking to fill in gaps, this guide is built to be practical and immediately applicable to your daily work.
What Is Git?
Git is a distributed version control system (DVCS). Unlike centralised systems (like Subversion) that depend on a single server, Git gives every developer a complete copy of the repository—including its full history—on their local machine. This design brings speed, resilience, and flexibility.
When you work in Git, you interact with three main areas:
- The working directory – your actual files.
- The staging area – a snapshot of changes you intend to commit.
- The repository – the history of commits stored in the
.gitfolder.
Git tracks changes as a series of snapshots, not file differences. Each commit points to its parent(s), forming a directed acyclic graph. This makes branching and merging cheap and safe, and it’s the foundation of almost every modern collaboration workflow.
Installing Git
Git runs on all major operating systems. It is often pre-installed on macOS and Linux, but you may want to install the latest version.
Windows
- Download the official installer from git-scm.com.
- During installation, you can choose the default editor (VS Code is a common choice) and whether to use Git from the Windows Command Prompt.
- After installation, open Git Bash or Command Prompt.
macOS
-
The easiest way is to install the Xcode Command Line Tools:
xcode-select --install -
You can also install a more recent version via Homebrew:
brew install git
Linux
Use your distribution’s package manager. For Debian/Ubuntu:
sudo apt update && sudo apt install git
For Fedora:
sudo dnf install git
Verifying Installation
git --version
This should print the installed Git version.
Basic Configuration
Set your identity (required before your first commit):
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
Set the default branch name (often main):
git config --global init.defaultBranch main
On macOS or Windows, you may also want to set a credential helper to cache your credentials:
git config --global credential.helper cache
These settings are stored in your global .gitconfig file.
Understanding Git Repositories
A Git repository is a self-contained collection of files and their version history. You can start a new one or clone an existing one.
When you work locally, Git tracks changes in three logical stages:
- Working directory – the files you see and edit.
- Staging area (index) – a holding area where you mark which changes will go into the next commit.
- Commit history – the immutable chain of saved snapshots.
This two-step process (stage, then commit) gives you precise control over what goes into each commit. You can stage only part of a file’s changes if needed.
Remote repositories (e.g., on GitHub, GitLab) are copies that you push to and pull from. They serve as collaboration hubs, but they are not special in Git’s internal model; every local clone is a full backup.
Essential Git Commands
A solid grasp of the following commands will cover the vast majority of your daily Git usage.
Starting a Repository
git init– creates a new repository in the current directory.git clone <url>– copies an existing remote repository, including all history and branches, to your local machine.
Tracking and Committing Changes
git status– shows the state of the working directory and staging area.git add <file>– stages changes for the next commit. Usegit add -pto stage parts of a file interactively.git commit -m "message"– records the staged snapshot in history.git log– views commit history. Add--oneline,--graph, or--statfor concise or visual output.
Inspecting Differences
git diff– shows unstaged changes. Usegit diff --stagedto see staged changes against the last commit.git diff <branch1>..<branch2>– compares two branches.
Undoing and Cleaning Up
git restore <file>– discards changes in the working directory (Git 2.23+).git rm <file>– removes a file and stages the removal.git mv <old> <new>– renames a file and stages the rename.
These commands are the building blocks of any Git workflow. Commit early and often; you can always reorganise your commits later with interactive rebasing.
Working with Branches
Branches are cheap, lightweight pointers to a specific commit. They isolate work and enable parallel development without affecting the main codebase.
Creating and Switching
git branch feature/login # create a branch
git switch feature/login # switch to it (Git 2.23+)
git checkout -b feature/login # older combined command
Branch Naming Conventions
Teams often adopt prefixes: feature/, bugfix/, hotfix/, release/. A clear naming scheme makes branch purpose instantly recognisable.
The Main Branch
Historically called master, the default branch is now commonly named main. This branch should always be in a deployable (or at least buildable) state.
Feature Branches
Isolate a single piece of work—a new feature, a refactor, or a documentation update. Merge back into main (or a develop branch) once reviewed and tested.
Release and Hotfix Branches
In more formal workflows, release branches stabilise a version before deployment, and hotfix branches address urgent production issues directly from main.
Branching is one of Git’s most powerful features. Combined with thoughtful naming and a clear workflow, it scales from solo projects to huge distributed teams.
Merging and Rebasing
When you finish work on a branch, you need to integrate it. Git offers two primary mechanisms: merge and rebase.
git merge
Creates a new commit that ties together two histories. A fast‑forward merge occurs when the target branch hasn’t moved; otherwise, Git creates a merge commit.
Merging preserves the complete history, including the exact context of when a branch was created and integrated.
git rebase
Rewrites the branch’s history by applying its commits on top of another branch. This results in a linear, cleaner history. However, because rebasing changes commit IDs, you should never rebase commits that have been pushed to a shared branch.
Merge Conflicts
When both branches change the same part of a file, Git cannot automatically reconcile the differences. It pauses, marks the conflicted areas with <<<<<<<, =======, and >>>>>>>, and waits for you to resolve them manually. After resolving, stage the file and complete the merge or rebase.
When to Use Which
- Merge when you want to preserve exact historical context, especially for shared branches.
- Rebase when you want a clean, linear history on feature branches before merging.
Many teams rebase feature branches onto the latest main before merging, which avoids unnecessary merge commits while still finalising integration with a merge commit.
Remote Repositories
Collaboration happens through remote repositories. A remote is a reference to another repository, typically hosted on a platform.
Managing Remotes
git remote add origin <url>– links your local repository to a remote.git remote -v– lists configured remotes.
Synchronising
git fetch– downloads objects and refs from the remote without modifying your working directory. Useful for inspecting changes before integrating.git pull– a combination offetchfollowed bymerge(orrebaseif configured).git push– sends your local commits to the remote branch.
A typical collaboration cycle:
git pull --rebase # incorporate remote changes cleanly
# ... make changes ...
git add .
git commit -m "Add search endpoint"
git push
Always pull before pushing to avoid non‑fast‑forward rejections. Resolve any conflicts locally.
Common Git Workflows
Different teams adopt different branching strategies. Here are four of the most common.
Feature Branch Workflow
All development happens on short‑lived feature branches. Once a feature is ready, it’s merged back into main. This is simple, effective, and the foundation of most other workflows.
Git Flow
A more structured model with long‑lived branches: main (production), develop (integration), feature branches, release branches, and hotfix branches. It provides strict isolation but can be overkill for small teams or continuous deployment.
Trunk‑Based Development
Developers commit directly to main (or a short‑lived branch merged within a day). Continuous integration and feature flags keep the trunk stable. This model is favoured by teams practising CI/CD and deploying multiple times a day.
Forking Workflow
Common in open source. Each contributor forks the main repository, works in their own copy, and submits pull requests. Maintainers review and merge from the fork.
| Workflow | Branch lifetime | Best for |
|---|---|---|
| Feature Branch | Days to weeks | Most teams |
| Git Flow | Weeks (release) | Large, scheduled releases |
| Trunk‑Based | Hours to a day | CI/CD, fast‑moving teams |
| Forking | Variable | Open source, external contributors |
Choose a workflow that matches your release cadence and team size. Start simple and add structure only when you need it.
Undoing Changes
Mistakes happen. Git provides a spectrum of undo mechanisms, from safe to destructive.
git restore <file>– discards uncommitted changes (working directory). Safe; only loses unsaved work.git restore --staged <file>– unstages a file without losing the changes.git revert <commit>– creates a new commit that undoes a previous commit. Safe for shared history.git reset <commit>– moves the branch pointer.--soft: keeps changes staged.--mixed(default): keeps changes unstaged.--hard: discards changes completely. Destructive; avoid on shared branches.
git checkout <commit> -- <file>– restores a single file from an earlier commit.
When in doubt, use git revert on commits that have already been pushed. For local only, git reset can be safe if you know what you’re discarding.
Git Best Practices
- Commit often. Small, focused commits are easier to understand, review, and revert.
- Write meaningful commit messages. Use the imperative mood (“Add login endpoint”) and explain the why, not just the what.
- Keep commits atomic. Each commit should represent a single logical change.
- Pull before pushing. Always integrate remote changes locally first to catch conflicts early.
- Use a
.gitignorefile. Exclude build artifacts, dependencies, environment files, and OS‑specific files. - Review your history before sharing. Use
git logorgit diffto audit changes; rebase interactively to clean up messy local commits. - Never commit secrets. API keys, passwords, and tokens belong in environment variables or secret managers. If you accidentally commit one, rotate it immediately and rewrite history.
Common Mistakes
- Force pushing (
git push --force). This overwrites remote history and can destroy teammates’ work. Use--force-with-leaseas a safer alternative, but still exercise caution. - Committing large binary files. Git isn’t designed for binaries; use Git LFS or external storage.
- Long‑lived branches. Branches that live for weeks accumulate merge conflicts and diverge significantly. Integrate frequently.
- Ignoring merge conflicts. A conflicted state blocks further work. Resolve conflicts promptly and ensure the code still compiles and tests pass.
- Amending pushed commits. Editing history that others may have based work on leads to duplication and confusion.
Git in Modern Development
Git is no longer just a command‑line tool; it is deeply integrated into every part of the software development lifecycle.
- IDEs and editors like VS Code provide visual diff tools, inline blame annotations, and one‑click staging. The Visual Studio Code Guide shows how to leverage these features.
- CI/CD pipelines trigger on push events, run tests, and deploy code automatically. They rely on Git’s commit graph for incremental builds.
- Code review platforms (GitHub, GitLab, Bitbucket) wrap pull requests and merge requests around Git branches, enabling structured collaboration.
- AI coding assistants now understand Git history and can summarise changes, generate commit messages, and even resolve simple merge conflicts.
Understanding the underlying Git commands helps you debug pipeline failures, recover from a bad merge, and fully exploit the advanced features these integrations offer.
Related Tools
Git itself is the engine; an ecosystem of tools enhances the experience.
- GitHub – the most popular hosting platform, adding pull requests, issues, and Actions.
- GitLab – includes built‑in CI/CD and container registries.
- Bitbucket – often used in Atlassian‑centric environments.
- GitHub CLI – manage issues, PRs, and actions directly from the terminal.
- Git GUIs (GitKraken, Sourcetree) – visual interfaces for those who prefer them.
Each adds value, but the core skills taught in this guide remain universally applicable.
Frequently Asked Questions
-
Is Git difficult to learn?
The basics are simple and can be learned in an afternoon. The deeper concepts (rebasing, interactive rebase, reflog) become intuitive with practice. Start withadd,commit,pull, andpush, and expand gradually. -
What’s the difference between Git and GitHub?
Git is the version control system; GitHub is a cloud‑based hosting service that stores Git repositories and adds collaboration features like pull requests, issues, and CI/CD. -
Should beginners learn Git first?
Yes. Understanding Git before diving into complex frameworks helps you experiment fearlessly, revert mistakes, and collaborate with others from day one. -
When should I use rebase instead of merge?
Use rebase to keep a clean, linear history when integrating feature branches. Avoid rebasing shared branches; it rewrites public history. -
What is a detached HEAD?
It occurs when you check out a specific commit rather than a branch. Any commits you make in this state are orphaned unless you create a branch. To get back, switch to an existing branch. -
How often should I commit?
Every logical change—no more, no less. Many developers commit several times per day. Commit whenever you’ve reached a point you might want to return to or share. -
Can Git manage large files?
By default, Git stores the full file in every commit, which becomes inefficient for large binaries. Use Git LFS (Large File Storage) to track binary assets separately. -
Is Git suitable for solo developers?
Absolutely. Git acts as an unlimited undo history, a time‑travel debugging tool, and a structured way to experiment with new ideas in branches. -
What is Git Flow?
A branching model with dedicatedmain,develop,feature,release, andhotfixbranches. It suits projects with scheduled releases but can be too heavy for continuous delivery. -
What’s the safest way to undo a commit?
If the commit is local and not pushed,git reset --soft HEAD~1keeps your changes. If it’s pushed, usegit revertto create a new inverse commit without rewriting history.
Conclusion
Git is the common thread running through modern software engineering. It empowers you to track every change, collaborate seamlessly, and fearlessly explore new ideas. The commands and workflows covered in this guide form the foundation you’ll build on throughout your career.
Now that you understand the core concepts, deepen your toolkit: learn to automate repository interactions with the [GitHub CLI] , supercharge your editing with the [VS Code Git integration] , and compare your JSON configurations and hashes using our [online diff checker] and [hash generator] . For broader tooling decisions, explore the Tool Comparisons section to see how Git‑adjacent tools stack up.
Return to the Tool Guides hub whenever you need practical, hands‑on instruction for any developer tool in your stack. Build better with Git—and with every tool that surrounds it.