linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Chapters
  • How it works
  • Lessons
  • Knowledge base
  • Interview prep
home/git/lessons/git-lab-06-1-branches-workflow

lesson ── git-labs ── ~22 мин ── 8 шагов

Branches: create, switch, merge, delete

The goal is to take a feature branch through its full cycle. You create it from main, make a couple of commits, see a fast-forward merge and a three-way merge, try to delete an unmerged branch, and get an honest refusal from Git.

▶ интерактивный sandbox

Поднимется контейнер gitlab/git-base с git, bash, pre-commit. В браузере откроется терминал, можно сразу git init. Каждый шаг проверяется автоматически. Сеть air-gapped, github.com недоступен.

запустить sandbox →

stack ── git · bash · 256 MB RAM · air-gapped · самоуничтожается через 30 мин простоя

Шаги

  1. 01

    Create a repo with one commit

    bash
    cd /home/student/work
    mkdir -p branches-lab && cd branches-lab
    git init -b main
    echo "base" > readme.txt
    git add . && git commit -m "init"
    git branch

    There is one branch right now, main. Next you create your own.

    ✓ A repo with one commit on main. Ready to branch.

  2. 02

    Create branch feat/quick and switch to it

    bash
    cd /home/student/work/branches-lab
    git switch -c feat/quick      # -c = create, same as `checkout -b`
    git branch                    # an asterisk marks the active branch
    git log --oneline --graph --all   # --graph = ASCII graph, --all = all refs

    switch -c (== checkout -b) creates a branch from HEAD and switches to it. git branch now shows both, with an asterisk on the active one.

    подсказка

    If you get `unknown switch 'switch'`, the git is old. Use `checkout -b feat/quick`.

    ✓ The branch is created, and you are on it.

  3. 03

    Make a commit on the branch

    bash
    cd /home/student/work/branches-lab
    echo "quick feature" > quick.txt
    git add . && git commit -m "feat: add quick"
    git log --oneline --graph --all

    feat/quick now has 2 commits, main has 1. The graph does not show any divergence yet, because main has not branched off.

    ✓ The branch moved one commit ahead.

  4. 04

    Do a fast-forward merge into main

    bash
    cd /home/student/work/branches-lab
    git switch main
    git merge feat/quick          # ff = just move the ref forward, no merge commit
    git log --oneline --graph --all

    The message is Fast-forward. main and feat/quick now point to the same commit. There is no merge commit: main just slid forward, because main and feat/quick had not diverged.

    ✓ Fast-forward done. The graph stayed linear.

  5. 05

    Set up a situation for a three-way merge

    For a three-way merge, both branches have to diverge from a common ancestor.

    bash
    cd /home/student/work/branches-lab
    git switch -c feat/slow
    echo "slow line" > slow.txt
    git add . && git commit -m "feat: add slow"
    git switch main
    echo "main update" >> readme.txt     # >> = append, does not overwrite
    git commit -am "main: update readme"  # -a = stage already-tracked files, -m = message
    git log --oneline --graph --all

    Now main and feat/slow have diverged. The graph shows a V shape.

    ✓ The branches have diverged. Ready for the three-way.

  6. 06

    Do a three-way merge

    bash
    cd /home/student/work/branches-lab
    # --no-edit = take the default merge-commit message, do not open the editor
    git merge --no-edit feat/slow
    git log --oneline --graph --all

    The message is Merge made by the 'ort' strategy. A merge commit with two parents appears in the log. The graph is no longer linear.

    Files from both branches end up in the working tree. They touched different files, so there is no conflict.

    ✓ The merge commit is created. That is the three-way.

  7. 07

    Delete a merged branch

    bash
    cd /home/student/work/branches-lab
    git branch -d feat/quick      # -d = "delete if merged", safe
    git branch -d feat/slow
    git branch

    Both delete without complaint, since they are merged into main. branch -d checks this itself and refuses when they are not.

    ✓ The merged branches are gone. Only main remains.

  8. 08

    Create an unmerged branch and try to delete it

    bash
    cd /home/student/work/branches-lab
    git switch -c feat/draft
    echo "draft idea" > draft.txt
    git add . && git commit -m "draft"
    git switch main
    git branch -d feat/draft      # fails: the branch is not merged into main

    You should get the error: error: The branch 'feat/draft' is not fully merged.. This is Git's protection: you could lose commits by deleting a branch that is not in main.

    To force the delete, use a capital -D:

    bash
    git branch -D feat/draft      # -D (capital) = forced delete
    git branch

    Now it really is deleted. If the commit is used nowhere else, git gc sweeps it up when it runs (by hand or as gc --auto). The reflog keeps a record of the branch for about 30 days by default, after which the commit becomes a candidate for collection.

    ✓ You saw Git's protection, and the forced delete worked.

Что ты узнал

A branch is a pointer to a commit. You create it with git branch or switch -c, and switch with switch. A merge can be fast-forward or three-way, depending on whether the target moved. You delete with branch -d (safe) or -D (forced).

команды

  • git switch -c feat/xcreate and switch
  • git merge feat/xmerge feat/x into the current branch (ff or 3-way)
  • git merge --no-ff feat/xforce a merge commit even when ff is possible
  • git branch -d feat/xdelete if the branch is merged
  • git branch -D feat/xdelete by force

концепции

  • · fast-forward: the target branch did not move, the ref just slides over
  • · three-way: both branches moved, you need a merge commit with two parents
  • · branch -d refuses when the branch is not merged, which is protection, not a bug

← предыдущая

Three areas: working tree, index, repository

следующая →

Atomic commits: add -p and amend

Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies