GitLearn — Examples
GitLearn
⟳ Flow
15px

📂 Real-World Examples

Each example is a scenario-based walkthrough using only Git commands — no framework-specific steps. Click any card to expand it.

Beginner 01 — Create a New Project and Push to GitLab
Starting from scratch — init, .gitignore, first commit, push.

Scenario

You're starting a brand new project from scratch and need to get it into GitLab.

Step 1 — Create the GitLab Repository First

  1. Go to your GitLab instance → New Project → Create blank project
  2. Set a name (e.g., MyApp)
  3. Set visibility (Private/Internal/Public)
  4. Uncheck "Initialize repository with a README" — you'll push from local
  5. Copy the repo URL (e.g., git@gitlab.company.com:team/MyApp.git)

Step 2 — Create Your Project Folder

Create the project folder and add your initial files however your stack requires. Once you have something worth tracking, continue below.

Step 3 — Initialize Git and Add .gitignore

git init

Create a .gitignore at the root to stop build output and IDE files from being committed:

# Build output (adjust for your stack)
bin/
obj/
dist/
out/

# IDE / Editor
.vs/
.idea/
*.user
*.suo
.vscode/

# OS
.DS_Store
Thumbs.db

# Environment / secrets
.env
.env.local
*.local
⚠️
Never commit files containing connection strings, API keys, passwords, or secrets.

Step 4 — First Commit

git add .
git status          # review what's staged — confirm no build output appears
git commit -m "Initial commit: scaffold MyApp"

Step 5 — Connect to GitLab and Push

git remote add origin git@gitlab.company.com:team/MyApp.git

# Rename branch to main if needed
git branch -M main

git push -u origin main

After this, every future push on this branch is just git push.

💡
git push -u origin main sets origin/main as the upstream for your local branch. After that, Git knows where to push/pull without specifying it each time.

Beginner 02 — Existing Repo on GitLab, Work on It Locally
Clone, understand what you have, make changes, push and stay in sync.

Scenario

The repo already exists on GitLab. You need to get it on your machine and start contributing.

Step 1 — Clone the Repository

git clone git@gitlab.company.com:team/MyApp.git

# Or clone into a specific folder name
git clone git@gitlab.company.com:team/MyApp.git my-local-folder

cd MyApp

This creates a full local copy including the entire history. The remote is automatically named origin.

Step 2 — Understand What You Cloned

git log --oneline --graph -20    # recent history
git branch -a                    # all branches (local + remote)
git remote -v                    # confirm origin points to GitLab

Step 3 — Always Pull Before You Start Work

git switch main
git pull

Step 4 — Make Changes and Push

# Create a branch for your work
git switch -c feature/add-user-endpoint

# ... make your changes ...

git status
git diff
git add src/users/users.controller.js
git commit -m "Add GET /users endpoint"

git push -u origin feature/add-user-endpoint

Then go to GitLab and open a Merge Request from your branch into main.

Step 5 — Stay in Sync While Working

git fetch origin
git rebase origin/main

If You Accidentally Work on Main

git switch -c feature/my-work    # create branch at current position
git switch main
git reset --hard origin/main     # reset main back to remote state
git switch feature/my-work       # your changes are safe on the new branch

Intermediate 03 — Multiple People Working on the Same Repo
GitHub Flow vs GitFlow, MR best practices, common team scenarios.

Scenario

A team shares one GitLab repository. Everyone needs to work on their own features without breaking each other's work.

The Golden Rules

  1. Never commit directly to main
  2. Always pull before starting work
  3. One feature = one branch = one Merge Request
  4. Small, frequent commits — easier to review and revert

GitHub Flow — Daily Workflow

# 1. Start from latest main
git switch main
git pull

# 2. Create your feature branch
git switch -c feature/user-auth

# 3. Work, commit often
git add -p
git commit -m "Add JWT authentication middleware"

# 4. Keep in sync with main daily
git fetch origin
git rebase origin/main

# 5. Push and open a Merge Request
git push -u origin feature/user-auth

After MR is approved and merged:

git switch main
git pull
git branch -d feature/user-auth    # clean up local branch

GitFlow Branch Naming

Branch typeFormatExample
Featurefeature/short-descriptionfeature/user-auth
Releaserelease/versionrelease/1.2.0
Hotfixhotfix/short-descriptionhotfix/login-crash

Common Team Scenarios

"I committed to the wrong branch"

git log --oneline -5

git switch feature/correct-branch
git cherry-pick <commit-hash>

git switch wrong-branch
git reset --hard HEAD~1    # only if not pushed yet

"My branch is 10 commits behind main"

git fetch origin
git rebase origin/main
git push -f origin feature/my-branch

Intermediate 04 — Resolving Merge Conflicts
Reading conflict markers, resolving during merge/rebase/pull, lock files.

Scenario

Two people edited the same lines in the same file. Git can't auto-merge — it needs you to decide what the final result should be.

Reading Conflict Markers

<<<<<<< HEAD
function getUser(id) {
  return db.users.find(id);
}
=======
async function getUser(id) {
  return await db.users.findById(id);
}
>>>>>>> feature/async-refactor
MarkerMeaning
<<<<<<< HEADStart of your version
=======Divider between the two versions
>>>>>>> branch-nameEnd of the incoming version

Delete the markers and keep the correct final code — often a combination of both sides.

Resolving a Merge Conflict

git status                      # shows which files have conflicts
# Edit each conflicted file
git add src/users/service.js    # mark as resolved
git merge --continue            # or: git commit

To abort and go back: git merge --abort

Resolving a Rebase Conflict

git fetch origin
git rebase origin/main
# Git pauses on each conflicted commit
# Edit the file, then:
git add src/users/service.js
git rebase --continue

After the rebase completes, force-push your branch:

git push -f origin feature/my-branch
⚠️
Only force-push your own feature branch. Never force-push main or develop.

Conflict in a Lock File (package-lock.json, yarn.lock, etc.)

# Don't manually merge lock files — accept one side then regenerate
git checkout --ours package-lock.json
# or
git checkout --theirs package-lock.json

# Regenerate
npm install

git add package-lock.json
git rebase --continue

Prevention

  • Rebase onto main frequently — the longer you diverge, the bigger the conflict
  • Communicate — if two people are touching the same area, coordinate
  • Keep PRs small — large PRs have more surface area for conflicts

Intermediate 05 — Undoing Mistakes
amend, reset, revert, restore, reflog — the right tool for each situation.

Quick Decision Guide

What happenedNot pushed yetAlready pushed
Wrong commit messagegit commit --amendAvoid — others may have pulled
Committed wrong filesgit reset HEAD~1git revert <hash>
Committed to wrong branchcherry-pick + resetgit revert + new MR
Discard all local changesgit restore .
Accidentally deleted a filegit restore <file>

Fix the Last Commit Message (Not Pushed)

git commit --amend -m "Correct message here"

Undo the Last Commit — Keep Changes Staged

git reset --soft HEAD~1

Undo the Last Commit — Keep Changes Unstaged

git reset HEAD~1

Undo the Last Commit — Discard Everything

git reset --hard HEAD~1
⚠️
--hard permanently destroys your changes. Only use it when you're certain.

Revert a Commit That's Already Pushed

git log --oneline -10

git revert a1b2c3d    # creates a new "Revert..." commit
git push

Discard Uncommitted Changes

git restore src/users/service.js    # one file
git restore .                       # everything

Recover a "Lost" Commit with Reflog

git reflog
# Find the hash of the lost commit

git cherry-pick f6e5d4c    # bring it back
💡
Reflog entries are kept for 90 days by default. Almost nothing is truly lost if you act quickly.

Remove a File from Git Without Deleting It Locally

git rm --cached .env
echo ".env" >> .gitignore
git commit -m "Stop tracking .env"

Advanced 06 — Stash: Save Work Without Committing
Stash, named stashes, apply vs pop, stash on a different branch, WIP commits.

Scenario

You're mid-feature when something urgent comes up. You're not ready to commit, but you can't leave the working directory dirty.

Basic Stash

git stash          # save tracked changes
git stash -u       # also include untracked (new) files

Give Your Stash a Name

git stash push -m "WIP: token validation logic, halfway done"

Full Workflow

# Mid-feature, urgent task arrives
git stash push -m "WIP: token validation"

git switch main
git pull
git switch -c hotfix/login-crash
# ... fix, commit, push ...

# Return to your feature
git switch feature/user-auth
git stash pop

List, Apply, Drop

git stash list                  # see all stashes
git stash pop                   # apply most recent AND remove from list
git stash apply                 # apply most recent, keep in list
git stash apply stash@{1}       # apply a specific stash by index
git stash drop stash@{1}        # delete a specific stash
git stash clear                 # delete ALL stashes

Inspect a Stash Before Applying

git stash show stash@{0}        # summary
git stash show -p stash@{0}     # full diff

WIP Commit as an Alternative

# Create a temporary commit
git add -A
git commit -m "WIP: do not merge"

# When you come back, undo it
git reset HEAD~1    # keeps your changes unstaged
💡
WIP commits survive machine restarts and are visible in git log — useful for long-running work-in-progress.

Advanced 07 — Hotfix: Urgent Fix While Mid-Feature
Production is broken. You're halfway through a feature. Here's how to fix prod without losing your work.

Scenario

You're working on feature/user-auth with uncommitted changes. A critical bug is reported in production — it needs to be fixed and deployed immediately.

Step 1 — Stash Your In-Progress Work

Don't commit half-done work. Stash it cleanly so you can come back to it later.

git stash push -m "WIP: user auth - mid refactor"
git status    # confirm working directory is clean

Step 2 — Switch to Main and Pull the Latest

git switch main
git pull      # make sure you have the latest production code

Step 3 — Create a Hotfix Branch

Always branch off main for a hotfix — not off your feature branch.

git switch -c hotfix/fix-login-crash

Step 4 — Fix, Commit, Push

# Make the fix
git add path/to/fixed-file.cs
git commit -m "fix: prevent null ref crash on login page"
git push -u origin hotfix/fix-login-crash

Open a Pull Request / Merge Request targeting main. Get it reviewed and merged.

Step 5 — Return to Your Feature and Rebase

Once the hotfix is merged, update your feature branch so it's built on top of the fix, not the old code.

git switch feature/user-auth
git stash pop                    # restore your WIP changes
git rebase origin/main           # replay your feature commits on top of the hotfix
💡
If stash pop causes conflicts, resolve them the same way as a merge conflict — edit the files, then run git add <file> and git stash drop to finish.
⚠️
Never merge your feature branch into main to fix production. A hotfix branch from main is always cleaner and safer.

Intermediate 08 — Squash Commits Before Raising a PR
Clean up your "WIP", "fix", "oops" commits into one meaningful commit before your teammates review your code.

Scenario

You've been working on a feature for a day and your branch has commits like: "WIP", "fix typo", "actually fix it", "add tests", "test fix". Before raising a PR you want these squashed into one clean commit.

Step 1 — Check How Many Commits to Squash

git log --oneline origin/main..HEAD    # shows commits on your branch not yet in main

Say you see 5 commits. You'll squash all 5 into 1.

Step 2 — Start Interactive Rebase

git rebase -i HEAD~5    # replace 5 with your actual commit count

Your editor opens with a list like:

pick a1b2c3d feat: add login page skeleton
pick b2c3d4e WIP
pick c3d4e5f fix typo
pick d4e5f6a actually fix it
pick e5f6a7b add tests

Step 3 — Mark Commits to Squash

Keep the first commit as pick. Change the rest to s (squash) — they'll be merged into the first:

pick a1b2c3d feat: add login page skeleton
s b2c3d4e WIP
s c3d4e5f fix typo
s d4e5f6a actually fix it
s e5f6a7b add tests

Save and close the editor. Git opens a second editor to write the final combined commit message — replace everything with one clean message:

feat: add login page with form validation and unit tests

Step 4 — Force Push Your Branch

You've rewritten history on your local branch — you need to force push. This is safe on your own feature branch that no one else is working on.

git push --force-with-lease
💡
--force-with-lease is safer than --force — it refuses to push if someone else has pushed to the branch since you last fetched, preventing you from accidentally overwriting their commits.
⚠️
Only squash commits on your own feature branches. Never rebase or squash on main or any shared branch — it rewrites history and causes problems for everyone.