Git may be confusing to learn at first, but once you master a few essential commands, it will greatly speed up your development workflow. If you are new to Ubuntu and just getting started with Git or managing multiple servers on Rocky Linux using Git or working in any type of DevOps pipeline, Git is the tool that you will use every single day. This guide covers the most important Git commands for linux developers which includes real terminal examples, troubleshooting fixes, and a cheat sheet that you can keep open while you work.
Note:
This guide is written for Ubuntu 24.04 and Rocky Linux 9 users. All commands work on CentOS Stream 10 and other RHEL-based distros as well. If you are new to the Linux terminal, check out our basic Linux commands guide before continuing.
Examples
What Is Git?
Git is a free, open-source distributed version control system that tracks changes in your code over time. It was created by Linus Torvalds in 2005 to manage the Linux kernel source code. Instead of saving one single file and overwriting it each time, Git stores a full history of every change ever made to your project.
The key idea is that your entire project history lives locally on your machine. You do not need internet access to commit, branch, or roll back changes. You only need a connection when syncing with a remote server like GitHub or GitLab.
Every developer on a team can work on their own copy of the code, and Git handles merging everything back together. This makes it the backbone of modern software development, DevOps pipelines, and even Linux system administration scripts.
Note:
Git versions differ between distros. Ubuntu 24.04 ships with Git 2.43, while Rocky Linux 9 comes with Git 2.39. Both fully support all modern commands covered in this article, including git switch and git restore introduced in Git 2.23.
Installing Git on Linux (Ubuntu and Rocky Linux)
Most Linux distributions include Git in their default repositories. Here is how to install and verify it on the two most common enterprise Linux platforms.
On Ubuntu 24.04 (apt)
LinuxTeck.com
On Rocky Linux 9 / CentOS Stream 10 / RHEL 9 (dnf)
LinuxTeck.com
After installation, verify the version installed on your system:
LinuxTeck.com
git version 2.39.3 (Rocky Linux 9)
Tip:
If you need a newer Git version on Rocky Linux 9 than what the default repo provides, you can enable the remi repository to get the latest release via dnf.
Git Command Syntax
Every Git command follows the same basic structure. Once you understand this pattern, reading any Git command becomes straightforward.
LinuxTeck.com
Where:
gitis the program itself[command]is what you want Git to do, likecommit,push, orbranch[options]are optional flags that change how the command behaves, like--globalor-m[arguments]are the targets the command acts on, like a file name or branch name
For example: git commit -m "initial commit" uses the commit command, the -m option to supply a message inline, and the message string as the argument.
Essential Git Commands Reference Table
The table below lists the most used Git commands grouped by category. Use this as your quick-reference cheat sheet for Linux development and DevOps work.
| CATEGORY | COMMAND | WHAT IT DOES |
|---|---|---|
| Setup | git config --global user.name |
Set your global username for commits |
| Setup | git config --global user.email |
Set your global email for commits |
| Setup | git config --list |
List all current Git configuration settings |
| Init | git init |
Start a new Git repository in current folder |
| Init | git clone [url] |
Copy a remote repository to your local machine |
| Stage | git status |
Show modified, staged, and untracked files |
| Stage | git add [file] |
Stage a specific file for the next commit |
| Stage | git add . |
Stage all changed files in the current directory |
| Commit | git commit -m "msg" |
Commit staged changes with a message |
| Commit | git commit --amend |
Edit the last commit message or add missed files |
| Branch | git branch |
List all local branches |
| Branch | git switch [name] |
Switch to a branch (modern replacement for checkout) |
| Branch | git switch -c [name] |
Create and switch to a new branch |
| Branch | git merge [branch] |
Merge a branch into the current branch |
| Remote | git remote -v |
Show all linked remote repositories |
| Remote | git fetch |
Download remote changes without merging |
| Remote | git pull |
Fetch and merge remote changes into current branch |
| Remote | git push origin [branch] |
Push local commits to the remote branch |
| Inspect | git log --oneline |
Show condensed commit history |
| Inspect | git diff |
Show unstaged changes in working directory |
| Inspect | git blame [file] |
Show who changed each line of a file |
| Undo | git restore [file] |
Discard local changes to a file (modern) |
| Undo | git reset --soft HEAD~1 |
Undo last commit, keep changes staged |
| Undo | git revert [commit] |
Create a new commit that reverses a past commit |
| Stash | git stash |
Save uncommitted changes temporarily |
| Stash | git stash pop |
Restore the most recently stashed changes |
| Tags | git tag v1.0 |
Create a lightweight tag at the current commit |
| Tags | git push --tags |
Push all tags to the remote repository |
| History | git rebase main |
Replay branch commits on top of main for clean linear history |
| History | git rebase -i HEAD~3 |
Interactive rebase to squash or rename the last 3 commits |
| History | git cherry-pick <hash> |
Apply a single commit from another branch to current branch |
| History | git reflog |
Show all HEAD movements including deleted commits and resets |
| Debug | git blame <file> |
Show author and commit for every line of a file |
| Debug | git bisect start |
Start binary search to find the commit that introduced a bug |
| Debug | git bisect good / bad |
Mark a commit as working or broken during bisect session |
| Debug | git bisect reset |
End bisect session and return to original HEAD |
Essential Git Commands for Linux Developers - Examples
I. Setting Up Git for the First Time
Before you run any Git command on a new Linux machine, you need to configure your identity. Git uses this information to label every commit you make. Run these two commands once globally and Git will remember them across all projects.
LinuxTeck.com
git config --global user.email "you@example.com"
git config --list
user.email=you@example.com
core.repositoryformatversion=0
core.filemode=true
Tip:
Your email should match the one registered on GitHub or GitLab. If they do not match, your commits will not be linked to your account profile.
II. Initializing a New Repository and Making Your First Commit
Starting a new project from scratch on your Linux machine involves three steps: initialize the repo, stage your files, and make the first commit. This is the core loop you will repeat hundreds of times as a developer.
LinuxTeck.com
git init
echo "# My Project" > README.md
git add .
git commit -m "initial commit: add README"
[main (root-commit) 3f2a1b4] initial commit: add README
1 file changed, 1 insertion(+)
create mode 100644 README.md
III. Branching with git switch (Modern vs Classic)
Most older tutorials use git checkout to switch and create branches. Since Git 2.23, the recommended approach is to use git switch for branches and git restore for files. Both old and new forms work, but the modern commands are clearer about their intent. Here is a side-by-side comparison:
| Classic (git checkout) | Modern (git switch / git restore) |
|---|---|
git checkout feature |
git switch feature |
git checkout -b feature |
git switch -c feature |
git checkout -- file.txt |
git restore file.txt |
LinuxTeck.com
git branch
* feature/login-page
main
Note:
Both Ubuntu 24.04 (Git 2.43) and Rocky Linux 9 (Git 2.39) fully support git switch and git restore. You can safely use the modern commands on both platforms.
IV. Cloning a Repository and Connecting to a Remote
Most real-world work starts by cloning an existing project. After cloning, Git automatically sets up the remote connection called origin. You can verify this and add extra remotes if needed.
LinuxTeck.com
cd repo
git remote -v
remote: Enumerating objects: 48, done.
origin https://github.com/user/repo.git (fetch)
origin https://github.com/user/repo.git (push)
V. git fetch vs git pull — Knowing the Difference
This is one of the most common points of confusion for beginners. git fetch downloads remote changes but does not touch your working files. git pull does a fetch and then immediately merges those changes into your current branch. Use git fetch when you want to review what changed before merging.
LinuxTeck.com
git log HEAD..origin/main --oneline
git pull origin main
* branch main -> FETCH_HEAD
a1b2c3d Add new feature
Already up to date.
Tip:
In a team environment, use git fetch first to review incoming changes, then decide whether to merge or rebase. This avoids surprise conflicts in shared branches.
VI. Viewing History with git log
The git log command shows the full commit history of your project. The default output is verbose, so most developers use flags to condense it. The combination below gives you a clean visual graph of your branch history.
LinuxTeck.com
* 7e9f01a Add README update
| * 3c4d5e6 (feature/login-page) Add login form
|/
* 9a8b7c6 Initial commit
VII. Undoing Changes Safely with git restore and git revert
There are two safe ways to undo work in Git depending on what you need. Use git restore to discard unstaged local changes to a file. Use git revert to undo a past commit by creating a new commit that cancels it out. This keeps the project history clean, which matters in shared branches.
LinuxTeck.com
git revert a1b2c3d
Warning:
Avoid using git reset --hard on shared branches. It rewrites history and will break the workflow for everyone else on the team. Use git revert instead.
VIII. Using git stash to Save Work in Progress
Sometimes you are mid-way through a task and need to switch branches fast without committing half-finished work. git stash saves your uncommitted changes to a temporary stack and gives you a clean working directory.
LinuxTeck.com
git switch main
git stash pop
Switched to branch 'main'
On branch feature/login-page
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0}
IX. Git Aliases for Faster Work in the Terminal
You can create shortcuts for Git commands you type constantly. These are stored in your ~/.gitconfig file and work across all projects on your Linux machine. For Linux sysadmins and DevOps engineers working in the terminal all day, aliases save real time. This topic is closely related to Linux Bash scripting and automation, where reusable commands are a core concept.
LinuxTeck.com
git config --global alias.co switch
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.last "log -1 HEAD"
Now instead of typing git status you just type git st. Verify your aliases were saved:
LinuxTeck.com
name = Your Name
email = you@example.com
[alias]
st = status
co = switch
lg = log --oneline --graph --decorate --all
last = log -1 HEAD
X. Git in a Real DevOps Workflow (Feature Branch to Release)
Here is a complete end-to-end Git workflow that mirrors what real teams do in production. This covers creating a feature branch, committing work, pushing to the remote, tagging a release, and rolling back if something goes wrong. If you are building DevOps skills, this workflow connects directly to what is covered in our Linux DevOps career guide.
LinuxTeck.com
echo "fix applied" >> payment.py
git add payment.py
git commit -m "fix: correct payment calculation rounding"
git push -u origin feature/payment-fix
git switch main
git merge feature/payment-fix
git tag -a v1.2.0 -m "Release v1.2.0 - payment fix"
git push origin main --tags
[feature/payment-fix 4c5d6e7] fix: correct payment calculation rounding
1 file changed, 1 insertion(+)
Branch 'feature/payment-fix' set up to track remote branch.
Switched to branch 'main'
Updating 9a8b7c6..4c5d6e7
Fast-forward
[v1.2.0] Release v1.2.0 - payment fix
Tip:
Always use annotated tags with -a for releases. They carry extra metadata like the tagger name, date, and message. Lightweight tags (just git tag v1.0) are fine for local bookmarks only.
XI. Using .gitignore to Keep Your Repo Clean
A .gitignore file tells Git which files and folders to never track. This is important for keeping things like log files, compiled binaries, environment variables, and editor config files out of your repository. You should create this file at the root of every project before the first commit.
Create the .gitignore file using your text editor and add one pattern per line:
LinuxTeck.com
Add the following lines inside the file, then save and exit:
LinuxTeck.com
*.env
node_modules/
__pycache__/
.DS_Store
dist/
Now stage and commit the file:
LinuxTeck.com
git commit -m "chore: add .gitignore"
1 file changed, 7 insertions(+)
create mode 100644 .gitignore
XII. Tagging Versions and Rolling Back
Tags mark important points in project history, like version releases. If a release breaks something in production, you can roll back to the last stable tag using git reset or by checking out the tagged commit on a new branch.
LinuxTeck.com
git switch -c hotfix/rollback v1.1.0
v1.1.0
v1.2.0
Switched to a new branch 'hotfix/rollback'
Note:
Creating a hotfix branch from a tag is safer than resetting main. It keeps your main history intact while you investigate and fix the issue.
XIII. git rebase — Keep a Clean Linear History
Rebasing replays your branch commits on top of another branch, giving you a clean straight-line history instead of a tangled merge graph. Senior developers use rebase before opening pull requests so reviewers see a clean commit trail. This is different from merge, which creates an extra merge commit. The golden rule is: never rebase commits that have already been pushed to a shared branch.
LinuxTeck.com
git rebase main
To do an interactive rebase and clean up the last 3 commits before pushing (squash, rename, or drop them):
LinuxTeck.com
Warning:
Only use git rebase on commits that exist locally or on your own private feature branch. Rebasing shared public branches rewrites history for everyone and causes serious sync problems on the team.
XIV. git cherry-pick — Apply One Specific Commit
Cherry-pick lets you take a single commit from any branch and apply it to your current branch without merging the whole branch. This is very useful for hotfixes: if a bug fix was committed to a feature branch and you need it on main right now, you cherry-pick just that one commit.
LinuxTeck.com
git switch main
git cherry-pick 4c5d6e7
[main 9f1a2b3] fix: correct payment calculation rounding
Date: Wed May 6 10:23:11 2026 +0000
1 file changed, 1 insertion(+)
Tip:
To cherry-pick multiple commits in one go, list their hashes separated by spaces: git cherry-pick abc1234 def5678. Or use a range: git cherry-pick abc1234^..def5678.
XV. git reflog — Recover Lost Commits and Deleted Branches
The reflog is Git's secret safety net. It records every single move your HEAD pointer has made, even operations like rebase, reset, and deleted branches that are no longer visible in normal git log. If you accidentally reset too far or deleted a branch you needed, git reflog shows you the full hidden history so you can get back to any previous state.
LinuxTeck.com
4c5d6e7 HEAD@{1}: commit: fix: correct payment calculation rounding
a1b2c3d HEAD@{2}: merge feature/login-page: Fast-forward
9a8b7c6 HEAD@{3}: commit (initial): initial commit: add README
To restore a lost commit or recover a deleted branch, use the hash from reflog output:
LinuxTeck.com
Tip:
Reflog entries are kept for 90 days by default. So even if you did a hard reset days ago and just realized you lost something important, git reflog can still find it for you.
XVI. git reset — Rewrite History Locally
There are three levels of git reset and understanding the difference between them is important. All three move the branch pointer back to a previous commit, but they handle your working files differently. Only use reset on commits that have not been pushed to a shared branch.
| COMMAND | STAGED CHANGES | WORKING FILES | USE CASE |
|---|---|---|---|
git reset --soft HEAD~1
|
Kept staged | Untouched | Re-commit with a better message |
git reset HEAD~1
|
Unstaged | Untouched | Undo commit, keep file edits |
git reset --hard HEAD~1
|
Wiped | Wiped | Fully discard last commit locally |
LinuxTeck.com
git reset HEAD~1
git reset --hard HEAD~1
Warning:
git reset --hard
permanently deletes your uncommitted changes. There is no undo for this unless you have the commit hash saved in git reflog. Never use it on a shared branch.
XVII. git blame — Find Who Changed a Line and When
git blame shows you the author, commit hash, and timestamp for every single line in a file. When something is broken and you need to know who wrote that specific line and in which commit, this is the command you reach for. It is also useful for understanding why a decision was made by checking the commit message tied to that line.
LinuxTeck.com
9a8b7c6 (Maria Dev 2026-04-28 14:30:05 +0000 2) return price + (price * tax)
4c5d6e7 (Alex Kim 2026-05-01 09:14:22 +0000 3) # rounding fix applied here
To blame a specific range of lines only, use the -L flag:
LinuxTeck.com
XVIII. git bisect — Find the Commit That Broke Everything
git bisect uses binary search through your commit history to find the exact commit that introduced a bug. Instead of checking commits one by one, Git cuts the search range in half each time you mark a commit as good or bad. For a project with hundreds of commits, this can narrow down a broken commit in just 7 or 8 steps. This is a command that separates junior from senior developers because most beginners never learn it, but it saves enormous time during production debugging.
LinuxTeck.com
git bisect bad
git bisect good 9a8b7c6
[a1b2c3d] Add payment module
Git now checks out a commit in the middle. Test your code, then tell Git whether this commit is good or bad. Keep repeating until Git identifies the exact culprit:
LinuxTeck.com
# or
git bisect bad
# when done finding the culprit:
git bisect reset
commit 4c5d6e7
Author: Alex Kim <alex@example.com>
Date: Wed May 1 09:14:22 2026 +0000
fix: correct payment calculation rounding
Tip:
Always run git bisect reset when you are done. This returns your repository to the original HEAD state before bisecting started, so you are not left on a detached HEAD.
Rules Senior Developers Follow:
- Use
git rebasebefore opening a pull request to keep commit history clean - Use
git reverton shared branches, nevergit reset --hard - Use
git resetonly on local, unpushed commits - Tag every production release with an annotated tag so rollbacks are fast
- Never force push to main or a shared branch without team agreement
Common Git Errors and How to Fix Them on Linux
Most Git errors are easy to fix once you know what they mean. Below are the most common ones you will hit on Ubuntu and Rocky Linux, with exact commands to solve each one.
Error 1: fatal: not a git repository
This means you ran a Git command outside a Git project folder. Either initialize a new repo or navigate to your existing project directory.
LinuxTeck.com
# or navigate into the existing project
cd /path/to/your/project
Error 2: You are in detached HEAD state
This happens when you check out a commit hash directly instead of a branch. Your changes will not be saved to any branch. To get back to a safe state, create a new branch from here or return to main.
LinuxTeck.com
# or just return to main
git switch main
Error 3: Merge conflict in file.txt
A conflict happens when two branches changed the same part of a file. Git marks the conflict areas in the file with angle brackets. Open the file, remove the conflict markers, keep the version you want, then stage and commit.
LinuxTeck.com
# edit the conflicted file manually to resolve
nano file.txt
git add file.txt
git commit -m "resolve merge conflict in file.txt"
Error 4: Permission denied (publickey) when pushing
This error means your SSH key is not set up or not loaded. On Ubuntu and Rocky Linux, generate a new SSH key and add it to your GitHub or GitLab account settings.
LinuxTeck.com
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
cat ~/.ssh/id_ed25519.pub
Copy the output of that last command and paste it into your GitHub SSH keys settings page. Then test the connection:
LinuxTeck.com
Warning:
Never share your private key file (~/.ssh/id_ed25519). Only copy and share the public key (id_ed25519.pub). The private key stays on your machine only.
Why Git Matters for Linux Developers and Sysadmins
Git is not just for software developers. Linux system administrators use Git to version-control configuration files, shell scripts, Ansible playbooks, and Dockerfiles. When something breaks in production, Git history tells you exactly what changed and when, which cuts down debugging time significantly.
For DevOps engineers, Git is the starting point of every CI/CD pipeline. Code cannot be built, tested, or deployed automatically without a Git repository at the foundation. Tools like Jenkins, GitHub Actions, and GitLab CI all trigger on Git events like commits and tags. If you are working toward a DevOps role, understanding Git commands deeply is listed as a required skill in virtually every job description. Our Linux shell scripting interview questions guide also highlights Git knowledge as a common topic in technical interviews.
Git also protects you from yourself. Every commit is a restore point. Even if you accidentally delete files or break something with a bad edit, you can always go back. On a Linux server managing scripts and configs, that safety net is genuinely valuable. When combined with tools like cron for scheduling, which you can explore in our cron command guide, Git-controlled scripts become much easier to maintain over time. Mastering essential git commands for Linux developers is now a core requirement listed in sysadmin and DevOps job descriptions worldwide.
Key Takeaways
- Install Git on Ubuntu 24.04 with
sudo apt install gitand on Rocky Linux 9 withsudo dnf install git. The versions differ slightly (2.43 vs 2.39) but both fully support all modern commands. - Always configure your identity with
git config --global user.nameandgit config --global user.emailbefore your first commit. - The modern commands
git switchandgit restore(Git 2.23+) replace the overloadedgit checkoutfor branch switching and file discarding respectively. git fetchdownloads remote changes safely without merging.git pullfetches and merges in one step. In team environments, prefergit fetchfirst to review incoming changes.- Use
git stashto park unfinished work temporarily when you need to switch context without committing half-done changes. - Git aliases in
~/.gitconfigsave significant time in the terminal. Set up shortcuts likegit st,git co, andgit lgearly in your workflow. - For production safety, always use
git revertinstead ofgit reset --hardon shared branches. Revert adds a new commit, keeping history intact. - Common errors like
fatal: not a git repository, detached HEAD state, and SSH key failures all have straightforward fixes once you know what they mean. - Tag releases with annotated tags using
git tag -aso you always have a clean rollback point in production. - Use
git rebasebefore opening pull requests to keep commit history linear. Never rebase shared branches. - Use
git cherry-pickto pull a single hotfix commit from a feature branch to main without merging the whole branch. git reflogis your safety net for recovering lost commits, deleted branches, and accidental hard resets. Entries are kept for 90 days.git bisectuses binary search to locate the exact commit that introduced a bug. It is one of the most powerful and underused debugging tools in Git.git blameshows who changed every line of a file and in which commit, making it the fastest way to trace the origin of a bug.
People Also Ask
What is the most important Git command to learn first?
The most important command to start with is git status. It shows you exactly what state your project is in at any moment: which files have changed, which are staged, and which are untracked. Once you understand the output of git status, every other Git command makes more sense because you can see what it actually does to your working directory. From there, learn git add, git commit, and git push in that order to complete your first basic workflow.
What is the difference between git fetch and git pull?
git fetch downloads commits, files, and references from the remote repository into your local machine, but it does not change anything in your working files or current branch. It updates your remote-tracking branches like origin/main so you can review what changed. git pull is essentially git fetch followed immediately by git merge. It downloads the changes and automatically integrates them into your current branch. Use git fetch when you want to look before you merge, especially in team projects where incoming changes could cause conflicts.
What does git stash do and when should I use it?
git stash temporarily saves your uncommitted changes to a stack and returns your working directory to a clean state. This is useful when you need to switch branches quickly without committing unfinished work. For example, if you are halfway through editing a feature and a critical bug report comes in on the main branch, you stash your work, switch to main, fix the bug, then come back and run git stash pop to restore exactly where you left off. You can have multiple stash entries and list them with git stash list.
How do I undo a git commit that I already pushed?
The safest way to undo a pushed commit is with git revert [commit-hash]. This creates a new commit that undoes the changes from the specified commit without deleting history. It is safe to use on shared branches because it does not rewrite any existing commits. Avoid using git reset --hard on pushed commits in a shared repository because it rewrites history and forces others to re-sync their local copies, which causes problems in team environments.
Is git checkout still used or has it been replaced?
git checkout still works and will not be removed from Git. However, since Git 2.23, the recommended approach is to use git switch for changing branches and git restore for discarding file changes. The reason is that git checkout was doing too many different things depending on how you used it, which confused beginners. The new commands are more specific and easier to understand. Both Ubuntu 24.04 and Rocky Linux 9 ship with Git versions that support both the old and new syntax, so you can use either in practice.
How do I see what changed in my repository on Linux?
There are a few commands for this depending on what you want to see. Use git status to see which files are modified, staged, or new. Use git diff to see the exact line-by-line changes in files that are not yet staged. Use git diff --staged to see changes that are staged but not yet committed. Use git log --oneline to see the list of past commits. And use git show [commit-hash] to see the full diff for any specific past commit. For a full reference of every Git command and option, the official Git documentation is the most reliable source to bookmark.
From your first terminal command to advanced sysadmin skills — every guide here is written in plain English with real examples you can run right now.