To try the hands-on steps you will need Git installed from git-scm.com and a terminal. Everything here is free.
To try the hands-on steps you will need Git installed from git-scm.com and a terminal. Everything here is free.
Git records the history of your project as a chain of snapshots. You save a snapshot with a commit, you try ideas on branches, and you share through a remote like GitHub or GitLab. Learn about a dozen commands and the mental model behind them, and you can work on any team on the planet. This part gets you from an empty folder to a merged branch, all on your own machine.
Who this is for: a college passout or career switcher heading into DevOps who has used a computer but never tracked code with Git. If you have followed Part 4 on the Linux command line, you already have the terminal habits this part builds on.
You have seen the folder. A project directory with report, report_v2, report_final, and report_final_ACTUAL sitting side by side. Somebody emailed a zip called latest.zip and now nobody knows which copy is real. Two people edited the same file over the weekend and one of them just lost an afternoon of work. Git exists to kill that folder for good. It keeps one directory and remembers every version inside it, so you can see what changed, who changed it, and go back to any point without keeping ten copies.
Here is the whole idea in one terminal session. Read it top to bottom before we take it apart.
$ git config --global init.defaultBranch main
$ mkdir notes && cd notes
$ git init
Initialized empty Git repository in /home/dev/notes/.git/
$ echo 'first line' > README.md
$ git add README.md
$ git commit -m 'start the notes file'
[main (root-commit) 8f3c2a1] start the notes file
1 file changed, 1 insertion(+)
create mode 100644 README.md
$ echo 'second line' >> README.md
$ git add README.md
$ git commit -m 'add a second line'
[main 4b1d9e0] add a second line
1 file changed, 1 insertion(+)
$ git log --oneline
4b1d9e0 add a second line
8f3c2a1 start the notes file
Six commands and you have a project with real history. The last one, git log --oneline, prints the two saved versions with their short IDs. Everything else in Git is a variation on this loop: change files, stage them, commit, repeat. Now the model that makes those commands make sense.
Where your changes actually live
The single fact that clears up most beginner confusion: a file in a Git project can be in one of three places at once. It sits in your working directory where you edit it. When you run git add, a copy of its current state moves to the staging area, a holding pen for the next commit. When you run git commit, everything staged becomes a permanent snapshot in the repository. Understanding these three areas is worth more than memorizing any command, because every confusing Git moment comes down to a file being in a different area than you thought.
Each commit stores a full snapshot plus a pointer to the commit before it. That backward chain is the history, and it is why you can walk from the newest change all the way back to the first.
Reading the state before you commit
git status is the command you run more than any other. It tells you which files changed, which are staged, and which Git is not tracking yet. Get in the habit of running it before every commit. It is the difference between committing exactly what you meant to and committing a stray debug file you forgot about.
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: config.yml
Two files changed, but only README.md is staged. If you commit right now, config.yml stays behind in your working directory. That is a feature, not a bug. Git lets you group related changes into one commit and leave the rest for later.
The commands that carry you
Git ships with more than a hundred commands. You will use about a dozen for almost everything. Here is the working set, the ones that appear in your terminal every day on a real team.
| Command | What it does |
|---|---|
git init | Turn the current folder into a Git repository |
git clone URL | Copy an existing remote repository to your machine |
git status | Show what changed and what is staged |
git add FILE | Stage a file for the next commit |
git commit -m MSG | Save a snapshot of everything staged |
git log --oneline | List the commit history, one line each |
git switch -c NAME | Create a branch and move onto it |
git switch NAME | Move to an existing branch |
git merge NAME | Bring another branch into your current one |
git pull | Fetch remote changes and merge them in |
git push | Send your commits to the remote |
git restore FILE | Throw away uncommitted changes to a file |
Twelve commands. If you know these cold, you can do ninety percent of the Git work any DevOps job will ask of you.
Branches are cheap, and that is the point
A branch is a movable label pointing at a commit. That is all it is. When you create a branch, Git does not copy your files. It just writes a new pointer, which is why branching is instant even on a huge project. You branch so you can build a feature or test a fix without touching the code everyone else depends on. When the work is good, you merge it back.
$ git switch -c add-login
Switched to a new branch 'add-login'
$ echo 'login form' > login.html
$ git add login.html
$ git commit -m 'add login form'
[add-login 2c7f5b3] add login form
1 file changed, 1 insertion(+)
$ git switch main
Switched to branch 'main'
$ git merge add-login
Updating 4b1d9e0..2c7f5b3
Fast-forward
login.html | 1 +
1 file changed, 1 insertion(+)
You did the work on add-login, switched back to main, and merged. Because main had not moved on, Git did a fast-forward: it slid the main pointer up to the new commit. Here is what that history looks like.
Day one on almost any team looks the same. You clone the shared repository, create a branch named after your ticket, commit your work, push it, and open a pull request for review. Nobody emails zip files. If you can branch, commit, and push without thinking about it, you spend your first week learning the actual product instead of fighting the tools. This one skill removes more first-week friction than any other on this list.
The error that stops you on your first push
You made your commits, you connected a remote, you run git push, and Git refuses. This is the single most common wall a beginner hits, and the message looks scarier than it is.
$ git push origin main
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:dev/notes.git'
hint: Updates were rejected because the remote contains work that
hint: you do not have locally. This is usually caused by another
hint: repository pushing to the same ref. Integrate the remote
hint: changes before pushing again.
The cause: someone else pushed commits to main after you last pulled. The remote is ahead of you, and Git will not let you overwrite their work. The fix is to bring their changes into your branch first, then push.
$ git pull --rebase origin main
$ git push origin main
Resist the urge to search for a way to force the push. git push --force makes the error disappear by deleting the other person work from the remote. On a shared branch that is how you become the reason for an incident. Pull, resolve anything that conflicts, then push.
What a merge conflict looks like
When two branches change the same lines, Git cannot decide which one wins, so it asks you. It writes both versions into the file with markers. Your job is to edit the file so it reads the way you want, delete the markers, then stage and commit.
<<<<<<< HEAD
port = 8080
=======
port = 3000
>>>>>>> feature-config
Everything above the ======= line is your current branch. Everything below is the branch you are merging in. Pick the port you want, remove all three marker lines, save, then run git add config.yml and git commit. A conflict is not a failure. It is Git being honest that a human has to make the call.
Forget checkout, learn switch and restore
For years git checkout did two unrelated jobs: it moved you between branches and it threw away file changes. That overload caused real damage, because one wrong argument could wipe your edits when you only meant to switch branches. Since Git 2.23 the project split those jobs into git switch for branches and git restore for files, and as of the 2026 releases these are the recommended commands. Older tutorials still teach checkout, so you will see it, but reach for the clearer pair.
| You want to | Old way | Clearer way |
|---|---|---|
| Move to a branch | git checkout dev | git switch dev |
| Make and enter a branch | git checkout -b dev | git switch -c dev |
| Undo edits to a file | git checkout -- app.py | git restore app.py |
| Unstage a file | git reset HEAD app.py | git restore --staged app.py |
You probably do not need GitFlow
Search for a branching strategy and you will drown in diagrams for GitFlow, with its long-lived develop, release, and hotfix branches feeding into master. It became famous around 2010 and a lot of teams cargo-culted it. My honest take after running plenty of pipelines: most small and mid-size teams do not need it, and it slows them down. Short-lived branches off main that get reviewed and merged within a day or two, a style people call trunk based development, keep history simple and releases frequent. Reach for a heavier model only when you genuinely maintain several released versions at once. Learn the mechanics of branching and merging first. The strategy on top is a team decision, not a beginner requirement.
What is the difference between git fetch and git pull?
git fetch downloads new commits and branch pointers from the remote but leaves your working branch untouched, so you can inspect what changed before doing anything. git pull is git fetch followed immediately by a merge (or a rebase if you pass --rebase) into your current branch. Interviewers ask this to check whether you understand that fetch is safe and read-only while pull actually changes your working branch.
Everything here runs on your own machine with nothing installed but Git. In an empty folder: run git init, create a file, and make three commits with real messages. Then git switch -c experiment, change the file, commit, switch back to main, and git merge experiment.
How to check it worked: run git log --oneline --graph --all. You should see your commits drawn as a graph with the branch splitting off and merging back. If the graph shows one straight line, your merge fast-forwarded, which is correct when main did not change while you were away.
Five things beginners ask about Git
Is Git the same as GitHub? No. Git is the version control tool that runs on your machine and needs no internet. GitHub, GitLab, and Bitbucket are websites that host Git repositories so teams can share them and add reviews, issues, and pipelines. You can use Git for years with no account anywhere.
Should I learn the command line or a Git GUI? Learn the command line first. GUIs hide what is happening, and every DevOps environment, especially a server you SSH into, gives you the terminal and nothing else. Once the commands make sense, use a GUI for reading history if you like. Start with the words.
Why did my new repo start on a branch called master? Until Git 3.0, which is landing in late 2026, a fresh git init still names the first branch master unless you set otherwise. Teams standardized on main. Run git config --global init.defaultBranch main once and every new repository starts on main.
What is a detached HEAD? It is the warning you get when you check out a specific commit instead of a branch. You can look around and even commit, but those commits are not on any branch and are easy to lose. If you see it, just run git switch main to get back to solid ground.
How often should I commit? Commit when a small piece of work is complete and the code is in a sane state, often several times an hour. Small commits with clear messages make history readable and make it trivial to undo one change without losing the rest. A commit message like fix stuff helps nobody, including future you.
Git rewards a little daily practice more than any amount of reading. Make a scrappy repo today, break it on purpose, and recover it. That is how the model stops feeling like magic. Next in the series we build the DevOps mental model of how the web works, so the pipelines and deploys ahead have somewhere to land. If you want the programming side in parallel, the Python for Beginners series pairs well, and the Cloud for Beginners series covers where this code eventually runs.
References
Git official documentation: git-restore
The GitHub Blog: the latest on Git updates
Git official documentation: git-switch


DrJha