DEV Community

RainyTech
RainyTech

Posted on AI-assisted

Git Tutorial for Beginners (2026): Commits, Branches, Merge Conflicts and Rebase

Picture three developers on one website. One improves login, another changes the cart, and the next morning an older folder has overwritten the newest work. Now there's project-final, project-final-2 and project-final-really-final, and nobody knows which copy is right.

That's the problem Git solves. This tutorial follows one small team building an online shop, Nova Shop, from an empty folder to a release, and every command appears exactly when it solves a real problem.

What Git is (and what GitHub is)

Git is a distributed version-control system.

  • Version control: instead of random backup folders, you save named checkpoints called commits. Each one is a snapshot of the project, with an author, a time and a message.
  • Distributed: every clone holds the project and its full history. Looking at old commits, creating branches and committing all work offline.
  • Collaboration: developers exchange commits and combine their histories.

A useful mental model: a camera (save a deliberate snapshot), a time machine (go back to an earlier state) and a team journal (what changed, and why).

GitHub is not Git. Git is the software on your computer. GitHub (or GitLab, Bitbucket, a company server) hosts a shared copy and adds pull requests, issues and permissions. git commit saves locally. Nothing is uploaded until you git push.

The team

  • Maya (product owner) wants login and a shopping cart ready for Friday.
  • Alex builds login.
  • Sam builds the cart.

Both need to change the same app in the same week.

1. Create the repository

git --version
git config --global user.name "Alex"
git config --global user.email "alex@example.com"

mkdir nova-shop && cd nova-shop
git init -b main
git status
Enter fullscreen mode Exit fullscreen mode

The name and email are authorship info stored in each commit, not a GitHub login. git init -b main creates a hidden repository and names the first branch main. It doesn't upload anything.

git status is the most useful command in Git. When you're not sure what Git expects next, read it before typing anything else.

2. The four places your work lives

  • Working directory: the files you see and edit
  • Staging area: a draft of the next commit
  • Local repository: your saved commits
  • Remote repository: the shared commits, after you push

Alex creates index.html, styles.css and app.js. He wants the first commit to hold only the page structure and styling:

git add index.html styles.css
git diff --staged
git commit -m "feat: create storefront shell"
git log --oneline
Enter fullscreen mode Exit fullscreen mode

git add doesn't save anything permanently. It selects what goes into the next commit. app.js stays untracked. That's how one messy work session becomes several clean commits.

A commit is a full project snapshot that points back to its parent. The message should say what the change does: "Update files" tells your team nothing, "Create storefront shell" does.

3. Branches: separate work, same history

A branch is a movable label pointing at a commit, not a copy of the folder. That's why branches are cheap.

git switch -c feature/login
# build login.html and auth.js
git add login.html auth.js
git commit -m "feat: add customer login form"
git commit -am "fix: validate empty password"
Enter fullscreen mode Exit fullscreen mode

Two focused commits: one adds a feature, one fixes a behavior. A reviewer can read them separately, and the team could undo the fix without losing the form. Main doesn't move.

Compare the branch with main:

git diff main...feature/login   # changes since the branches split
git log main..feature/login     # commits only on the feature branch
Enter fullscreen mode Exit fullscreen mode

Meanwhile Sam starts feature/cart from the same main commit and commits "feat: add shopping cart". Neither waits for the other.

4. Push: share your commits

git remote add origin <repository-url>
git push -u origin feature/login
Enter fullscreen mode Exit fullscreen mode

origin is just a conventional nickname for the remote. -u remembers the link, so next time git push is enough.

Push only sends commits. If auth.js has uncommitted edits, they stay on your machine. Committing saves; pushing shares.

5. Fetch and pull: get your team's work

Sam's cart got reviewed and merged into the remote main, so Alex's local main is now behind.

git fetch origin
git log main..origin/main      # what arrived?

git switch main
git pull --ff-only origin main
Enter fullscreen mode Exit fullscreen mode
  • git fetch downloads new commits but doesn't touch your branch or files. It's a safe "what changed?"
  • git pull is fetch + integrate.
  • --ff-only refuses to create a surprise merge. If your main and the remote have diverged, it stops and lets you decide.

6. Merge: combine the work

After review (a pull request is a hosting-service feature, not a Git command), the team merges login into main:

git switch main
git merge --no-ff feature/login
git log --graph --oneline --all
Enter fullscreen mode Exit fullscreen mode

--no-ff records a merge commit, the moment the feature joined the product. Some teams prefer fast-forward, squash or rebase. The rule that matters is: be consistent with your team's workflow.

7. Merge conflicts aren't errors

Alex changed a button to "Sign in". Sam changed the same line to "Continue". Both are valid, so Git can't guess and stops with conflict markers:

<<<<<<< HEAD
<button>Sign in</button>
=======
<button>Continue</button>
>>>>>>> feature/cart
Enter fullscreen mode Exit fullscreen mode

Maya picks "Continue to sign in". You edit the file to that final version, remove every marker, run the app and tests, then:

git add login.html
git commit
Enter fullscreen mode Exit fullscreen mode

Resolving a conflict is a code decision, not just deleting markers. And if a merge started at the wrong time: git merge --abort puts things back.

8. checkout vs switch vs restore

git checkout does two very different jobs, switching branches and restoring files. Modern Git splits them:

git switch main               # change branch
git switch -c feature/name    # create + switch
git switch -                  # back to the previous branch

git restore app.js            # discard unstaged edits (careful!)
git restore --staged auth.js  # unstage, keep your edits
Enter fullscreen mode Exit fullscreen mode

Run git status before switching. If switching would overwrite work, Git stops: commit it, stash it, or discard it on purpose.

9. Undo the right way

Pick the command by where the mistake is:

Mistake Command
Unwanted edit, not staged git restore <file>
Staged by accident git restore --staged <file>
Bad commit already pushed git revert <commit-id>

git revert adds a new commit that undoes the bad one. History stays intact, and teammates can pull normally.

git reset moves a branch pointer and can rewrite history. It's fine for local cleanup, but don't rewrite commits your team already has.

10. Rebase in plain language

Your private feature/profile started from an older main, and main has moved on.

  • Merge joins the two histories, often with a merge commit.
  • Rebase replays your feature commits on top of the newest main, as if you'd started from there.
git switch feature/profile
git fetch origin
git rebase origin/main
# on a conflict: fix the file, then
git add <file>
git rebase --continue
# or give up safely:
git rebase --abort
Enter fullscreen mode Exit fullscreen mode

Rebase creates new commit IDs. Great for private branches, risky for shared ones. Neither is "better". Use your team's policy.

Write commits people can use

  • One logical purpose per commit
  • Small enough to review, and tested
  • A message that completes "If applied, this commit will…": "Prevent negative cart quantity", not "fix stuff"
  • Check git status and git diff --staged first, so no secrets or temp files slip in

Prefixes like feat, fix, docs and test help, but consistency matters more than the exact format.

The daily workflow

git switch main
git pull --ff-only
git switch -c feature/cart-quantity
# build + test
git add <files>
git diff --staged
git commit -m "feat: add cart quantity controls"
git push -u origin feature/cart-quantity
# open a pull request, get review, merge
git switch main
git pull --ff-only
git branch -d feature/cart-quantity
git fetch --prune
Enter fullscreen mode Exit fullscreen mode

The sequence matters more than any single command: update, isolate, build, inspect, save, share, review, integrate, clean up.

Recap

  • Git connects project snapshots into a history you can inspect and recover.
  • add picks what goes into a commit, commit saves it locally, push shares it.
  • Branches are cheap labels, so use one per task.
  • fetch is a safe look, pull --ff-only is a safe update.
  • Conflicts are decisions, not errors.
  • restore for files, revert for shared commits, and be careful with reset.
  • Merge or rebase: follow your team's rules.

The full 25-minute walkthrough with every command on screen: https://youtu.be/S0E5qqDzmLs

Which Git command confused you most when you started? Tell me in the comments.


Drafted with AI assistance from the video lesson. Every command was re-run on Git 2.50 before publishing. I make AI, coding and tech tutorials on RainyTech.

Top comments (0)