Table of Contents
Why Git Matters for Linux Developers
Git is the de facto version control system in modern software development and is tightly integrated with Linux workflows:
- Most open source projects (including the Linux kernel) use Git.
- Build, CI/CD, and deployment pipelines almost always start from a Git repository.
- Many tools (
git send-email,git format-patch) are tailored for UNIX-like environments.
Here you’ll learn practical Git usage from the command line, focusing on how a Linux developer actually works day to day.
Basic Git Concepts
You don’t need to memorize internal data structures, but you do need to understand the core ideas:
- Repository (repo): A project tracked by Git. Contains your code and a
.gitdirectory with history and metadata. - Commit: A snapshot of your project at a point in time, with metadata (author, date, message, parents).
- Branch: A movable pointer to a commit, used to track independent lines of development.
- HEAD: A special pointer to “where you are now”. Usually points to a branch, which in turn points to a commit.
- Remote: A reference to a server-side repo (e.g. on GitHub, GitLab). Typically named
origin. - Working tree: Your checked-out files on disk.
- Index (staging area): Where you prepare changes to be committed.
Installing and Configuring Git
Most distributions provide Git via their package manager:
- Debian/Ubuntu:
sudo apt install git - Fedora:
sudo dnf install git - Arch:
sudo pacman -S git - openSUSE:
sudo zypper install git
Minimal global configuration (run once per machine):
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.editor "nano"
git config --global init.defaultBranch mainView config values:
git config --global --list
git config --system --list # system-wide
git config --local --list # in current repoCreating and Cloning Repositories
Initializing a new repository
To start version-controlling an existing directory:
cd my-project
git init # creates .git directory
git statusAdd an initial file and commit:
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit"Cloning an existing repository
To obtain a copy of a remote project:
git clone https://github.com/user/project.git
cd projectCommon variants:
- With SSH (preferred for pushing to your own repos):
git clone git@github.com:user/project.git- Clone into a custom directory:
git clone https://github.com/user/project.git mydirThe Three States: Working Tree, Staging Area, Commits
Git tracks files in three main places:
- Working tree: your current files; may have untracked or modified changes.
- Staging area (index): files you’ve marked to include in the next commit (
git add). - Repository (history): committed snapshots.
Use git status frequently to see where changes are.
Everyday Commands: Status, Add, Commit
Checking status
git statusShows:
- Untracked files (
??in short format) - Modified but unstaged files
- Staged changes
Short format:
git status -sb # concise status with branchAdding changes
To stage a specific file:
git add file.cTo add everything (tracked and untracked) in the current directory:
git add .To stage only some hunks from a file (useful for splitting commits):
git add -p file.c
You’ll be shown each hunk and can choose y (stage) or n (skip), etc.
Making a commit
Once changes are staged:
git commit -m "Implement feature X"
If you omit -m, your editor opens so you can write a multi-line message.
Good commit messages:
- First line: short summary (50–72 characters).
- Blank line.
- Optional detailed explanation.
Example:
git commit
# In editor:
# Add config loader for JSON files
#
# This introduces a small helper library to read JSON config
# files. It is used by the main server binary to...Inspecting History: log, show, diff
Viewing commit history
Basic history:
git logA more compact, on-one-line view:
git log --oneline
git log --oneline --graph --decorate --allFilter by file:
git log -- path/to/file.cView a specific commit (replace with real hash):
git show 3f7a9acShows the commit message and the patch.
Viewing differences
Compare working tree vs last commit:
git diffCompare staged vs last commit:
git diff --cachedCompare two commits:
git diff old_commit new_commit
git diff 3f7a9ac HEADDiff for a specific file:
git diff HEAD~1 HEAD -- path/to/file.cWorking with Branches
Listing and creating branches
List branches:
git branch # local branches
git branch -a # local + remote-trackingCreate a new branch from current HEAD:
git branch feature-xCreate and switch immediately:
git switch -c feature-x
# or older style:
git checkout -b feature-xSwitching branches
git switch main
# or:
git checkout mainDeleting branches
After merging a feature branch:
git branch -d feature-x # safe; refuses if unmerged
git branch -D feature-x # force deleteMerging and Resolving Conflicts
Fast-forward vs merge commit
If your branch is strictly ahead of main, merging can be a “fast-forward”:
git switch main
git merge feature-x # may just move main pointer forwardIf both branches have diverged, Git creates a merge commit:
git merge feature-x # opens editor for merge commit messageHandling merge conflicts
When Git cannot automatically merge:
- It stops and marks conflicted files.
git statusshowsboth modified.
Conflicted sections look like:
<<<<<<< HEAD
current branch version
=======
feature-x branch version
>>>>>>> feature-xResolve by editing files to the correct content, then:
git add path/to/conflicted_file
git commit # completes the mergeYou can also abort the merge:
git merge --abortWorking with Remotes: fetch, pull, push
Most workflows use a remote named origin:
Check remotes:
git remote -vAdd a remote:
git remote add origin git@github.com:user/project.gitFetching vs pulling
git fetch: download new data from remote but don’t change your current working tree.git pull:fetch+ merge (or rebase) into the current branch.
Fetch only:
git fetch origin
git log --oneline --graph --allUpdate your current branch with remote changes:
git pull origin main
You can configure a default upstream so you can just run git pull:
git branch --set-upstream-to=origin/main mainPushing changes
First push of a new local branch:
git push -u origin feature-xSubsequent pushes:
git pushPush a specific branch:
git push origin mainDelete a remote branch:
git push origin --delete feature-xStashing Work-In-Progress (WIP)
Sometimes you need to switch branches but have uncommitted changes:
Save them temporarily:
git stash
# or include untracked files:
git stash -uList stashes:
git stash listRestore latest stash and drop it:
git stash popRestore without dropping:
git stash apply stash@{1}Undoing and Fixing Mistakes
Git provides several ways to adjust recent work. Use them carefully, especially on shared branches.
Amending the last commit
To fix the message or add omitted files:
git add missed_file.c
git commit --amendThis rewrites the last commit; avoid doing this after you’ve pushed that commit to a shared branch.
Resetting
git resetmoves branch and optionally modifies index/working tree.
Common forms:
- Soft reset (keep changes staged):
git reset --soft HEAD~1
# now previous commit’s changes are staged again- Mixed reset (default; keep in working tree, unstage):
git reset HEAD~1
# previous commit’s changes become unstaged- Hard reset (discard changes):
git reset --hard HEAD~1
# WARNING: lose work; use with cautionTo discard all local changes and return to last commit:
git reset --hard HEADRestoring files
When you only want to revert a file, not change history:
git restore path/to/file.c # reset working copy to HEAD
git restore --staged path/to/file.c # unstage without touching file
(On older Git versions, similar operations used git checkout.)
Git Ignore Rules
Many generated files (build artifacts, logs) should not be tracked.
Create a .gitignore file:
# ignore object files
*.o
# ignore build directory
build/
# ignore editor backups
*~Apply globally (for your user only):
echo "*.swp" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global
Ignored files won’t show as untracked in git status.
Collaboration Patterns: Forks, Feature Branches, Pull Requests
While specific hosting platforms have their own UI, the Git side is similar:
- Feature branches: Develop each change in a dedicated branch off
mainordevelop:
git switch -c fix-issue-123 main
# work, commit
git push -u origin fix-issue-123- Code review / pull request / merge request: Open on your Git hosting service, reviewers comment, then it’s merged.
- Forks: For projects you don’t own:
- Fork on the hosting site.
git cloneyour fork.- Add the original project as an additional remote (often named
upstream):
git remote add upstream https://github.com/original/project.git
git fetch upstream
git switch main
git merge upstream/main
# or: git rebase upstream/mainThese patterns are central to open source contribution and CI/CD workflows.
Useful Git Tips for Linux Developers
- Use
.gitignorefor build artifacts: e.g.build/,dist/,.o,.so,*.pyc. - Create small, focused commits: easier to review and revert.
- Use
git log -porgit showbefore pushing to review what you’re sending. - Alias common commands in your Git config:
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate --all"- Integrate with build tools and CI: most CI configurations (covered elsewhere) will assume your code lives in Git and will check out specific commits or branches.
With these fundamentals, you can comfortably manage source code on Linux, collaborate with others, and integrate Git into build and CI/CD workflows.