Chapterبەش 2 · Lectureوانە 2.2

Branches and Merging: Working on Many Things at Onceلقەکان و بەیەککردن: کارکردن لەسەر چەند شتێک لە یەک کاتدا

How a team works on several things at once without breaking main. With Bazaar Cart's delivery fee and a honey-price bug, the lesson shows that a branch is a movable name and HEAD marks where you are, creates and switches branches, deals with unfinished work (commit or stash), merges by fast-forward and by a three-way merge commit, resolves a real merge conflict and the SyntaxError that leftover markers cause, and covers avoiding conflicts, deleting and naming branches, tags as fixed names, and the GitHub flow and trunk-based strategies, with a word on rebase.

تیمێک چۆن لە یەک کاتدا لەسەر چەند شتێک کار دەکات بێ ئەوەی main تێک بدات. بە کرێی گەیاندنی Bazaar Cart و نرخی هەنگوین، وانەکە پیشان دەدات ناوێکی جووڵاوە و نیشانی دەدات لە کوێیت، دروست دەکات و لە نێوانیاندا دەگوازێتەوە، کاری تەواونەکراو ( یان stash) چارەسەر دەکات، بە و بە سێ‌لایەنە دەکات، ڕاستەقینە و ئەو نیشانە بەجێماوەکان دروستی دەکەن چارەسەر دەکات و باس لە دوورکەوتنەوە لە ناکۆکی، سڕینەوە و ناونانی ، وەک ناوی جێگیر و ستراتیژییەکانی GitHub flow و ⁦trunk-based⁩ دەکات، لەگەڵ وشەیەک لەبارەی rebase.

18 min read20 خولەک خوێندنەوە · 17 stepsهەنگاو

What you will learnچی فێر دەبیت

  • Explain what a branch and HEAD are, and create and switch branches.
  • Handle unfinished work before switching with a commit or git stash.
  • Tell a fast-forward merge from a three-way merge and read the merge commit in git log --graph.
  • Resolve a merge conflict and find leftover conflict markers.
  • Keep conflicts small, delete and name branches, mark a version with a tag and choose a branching strategy.
  • ڕوون بکەیتەوە و چین و دروست بکەیت و لە نێوانیاندا بگوازیتەوە.
  • پێش گواستنەوە کاری تەواونەکراو بە یان git stash چارەسەر بکەیت.
  • لە سێ‌لایەنە جیا بکەیتەوە و لە ⁦git log --graph⁩ بخوێنیتەوە.
  • چارەسەر بکەیت و نیشانە بەجێماوەکانی ناکۆکی بدۆزیتەوە.
  • ناکۆکییەکان بچووک بهێڵیتەوە، بسڕیتەوە و ناویان لێ بنێیت، بە نیشان بکەیت و هەڵبژێریت.

Two jobs at the same timeدوو کار لە یەک کاتدا

Bazaar Cart works, and two jobs arrive at once (prices in this lesson are made up, in IQD). Karwan must add the delivery fee, rule R4; it will take him a day or two. Meanwhile Dilan, the tester, finds a bug: honey costs 30,000 IQD per kilogram, but prices.py says 3000 — a zero has been missing since the very first commit. Shilan must fix it today. Neither job may break main, the code Soran's shop uses every day.

Bazaar Cart کار دەکات و دوو کار پێکەوە دێن (نرخەکانی ئەم وانەیە دەستکردن و بە دینارن). کاروان دەبێت کرێی گەیاندن زیاد بکات، ڕێسای ⁦R4⁩؛ ڕۆژێک یان دوو ڕۆژی پێدەچێت. لەو کاتەدا دیلان، ، دەدۆزێتەوە: هەنگوین کیلۆی بە ⁦30,000⁩ دینارە، بەڵام prices.py دەڵێت 3000 — سفرێک لە یەکەم ونە. شیلان دەبێت ئەمڕۆ چاکی بکات. هیچ کامیان نابێت main تێک بدەن، ئەو کۆدەی دوکانەکەی سۆران هەموو ڕۆژێک بەکاری دەهێنێت.

The answer is branches: separate lines of work inside one repository. Each person works on their own branch; when the work is ready and checked, it is merged back into main.

وەڵامەکە : هێڵی جیای کار لە ناو یەک . هەر کەسێک لەسەر خۆی کار دەکات؛ کاتێک کارەکە ئامادە و پشکنراو بوو، دەگەڕێتەوە ناو main ().

A new dolma recipeڕێچەتەیەکی نوێی دۆڵمە

Hana's family keeps a recipe book. When she wants to try a new dolma recipe, she writes it on a separate page and cooks it a few times. Only when the family likes it does she copy it into the book. The book — like main — is never spoiled by an experiment.

خێزانەکەی هانا کتێبێکی ڕێچەتەی خواردنیان هەیە. کاتێک دەیەوێت ڕێچەتەیەکی نوێی دۆڵمە تاقی بکاتەوە، لەسەر پەڕەیەکی جیا دەینووسێت و چەند جارێک لێی دەنێت. تەنیا کاتێک خێزانەکە حەزیان لێ بوو، دەیگوازێتەوە ناو کتێبەکە. کتێبەکە — وەک main — هەرگیز بە تاقیکردنەوەیەک تێک ناچێت.

Where the analogy stops workingسنووری ئەم نموونەیە

Git does not copy the book for a branch: a branch is only a name, so it costs almost nothing. And Git usually joins the pages by itself; a person decides only when two people changed the same line.

Git کتێبەکە بۆ کۆپی ناکات: تەنیا ناوێکە، بۆیە نزیکەی هیچی تێناچێت. هەروەها Git زۆرجار خۆی پەڕەکان بەیەک دەگەیەنێت؛ تەنیا کاتێک دوو کەس هەمان دێڕیان گۆڕیبێت کەسێک بڕیار دەدات.

The main line of commits runs from left to right. Two branches leave it: feature/delivery-fee above with two commits (Karwan: the delivery fee) and fix/honey-price below with one commit (Shilan: the honey price). Both come back into main through merges. Each person works on a separate line; main keeps working the whole time; when a piece is ready, it is merged back.هێڵی سەرەکیی کۆمیتەکان لە چەپەوە بۆ ڕاست دەڕوات. دوو لق لێی جیا دەبنەوە: feature/delivery-fee لە سەرەوە بە دوو کۆمیت (کاروان: کرێی گەیاندن) و fix/honey-price لە خوارەوە بە یەک کۆمیت (شیلان: نرخی هەنگوین). هەردووکیان بە بەیەککردن دەگەڕێنەوە ناو main. هەر کەسێک لەسەر هێڵێکی جیا کار دەکات؛ main هەموو کاتێک کار دەکات؛ کاتێک بەشێک ئامادە بوو، دەگەڕێتەوە ناوی.
Two lines of work, one safe main.دوو هێڵی کار، یەک mainـی سەلامەت.CêIT

A branch is a movable nameلق ناوێکی جووڵاوە

Remember that every commit points to its parent (Git basics). A branch is simply a name that points to one commit — in Git it is a tiny file of 41 bytes holding a commit hash, so making one is instant and copies nothing. main is an ordinary branch that git init -b main made. When you commit, the branch you are on moves forward to the new commit.

لەبیرت بێت هەر ئاماژە بە دایکەکەی دەکات (بنەماکانی Git). تەنیا ناوێکە کە ئاماژە بە یەک دەکات — لە Gitـدا بچکۆلەیە بە قەبارەی ⁦41⁩ کە هەڵدەگرێت، بۆیە دروستکردنی یەکسەرییە و هیچ شتێک کۆپی ناکات. main ئاساییە کە git init -b main دروستی کرد. کاتێک دەکەیت، ئەو لەسەریتی دەچێتە پێش بۆ نوێیەکە.

HEAD is Git's marker for where you are: it points to your current branch. git branch lists the branches and marks HEAD's branch with *; git branch <name> makes a new branch but does not switch to it.

نیشانەی Gitـە بۆ ئێستا لە کوێیت: ئاماژە بە ئێستات دەکات. git branch لیست دەکات و بە * نیشان دەکات؛ git branch <name> نوێ دروست دەکات بەڵام ناتباتە سەری.

Branches of the repositoryلقەکانی کۆگای کۆدەکەBASHType in a terminalلە تێرمیناڵدا بینووسە
git branch
Six commits in a row from 08d3d64 to 463271a, each pointing to its parent. The label main points to 463271a, and HEAD points to main. A dashed label feature/delivery-fee, made by git branch feature/delivery-fee, also points to 463271a. Notes: main is a name that points to one commit and moves forward with every new commit on it; git branch makes a new name on the same commit, a 41-byte file, nothing is copied; HEAD still points to main because git branch does not switch.شەش کۆمیت بە ڕیز لە 08d3d64ـەوە تا 463271a، هەریەکە ئاماژە بە دایکەکەی دەکات. ناوی main ئاماژە بە 463271a دەکات و HEAD ئاماژە بە main دەکات. ناوێکی پچڕپچڕ، feature/delivery-fee، کە git branch feature/delivery-fee دروستی کردووە، ئەویش ئاماژە بە 463271a دەکات. تێبینی: main ناوێکە کە ئاماژە بە یەک کۆمیت دەکات و بە هەر کۆمیتێکی نوێ لەسەری دەچێتە پێشەوە؛ git branch ناوێکی نوێ لەسەر هەمان کۆمیت دروست دەکات، فایلێک بە قەبارەی 41 بایت، هیچ شتێک کۆپی ناکرێت؛ HEAD هێشتا ئاماژە بە main دەکات چونکە git branch ناتگوازێتەوە.
Branches and HEAD are labels on commits. و ناونیشانن لەسەر .CêIT

Make a branch and switch to itلقێک دروست بکە و بچۆ سەری

git switch -c feature/delivery-fee creates the branch and switches to it (-c = create; older tutorials write git checkout -b). Karwan adds one line, DELIVERY_FEE = 2500 — Soran's price at that time — and commits:

git switch -c feature/delivery-fee دروست دەکات و دەچێتە سەری (-c = create؛ فێرکارییە کۆنەکان git checkout -b دەنووسن). کاروان یەک دێڕ زیاد دەکات، DELIVERY_FEE = 2500 — نرخی سۆران لەو کاتەدا — و دەکات:

Work on a branchکارکردن لەسەر لقێکBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch -c feature/delivery-fee
git branch
git add prices.py
git commit -m "Add a delivery fee of 2,500 IQD"
git log --oneline --graph --all
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 5

--graph --all draws every branch as a text graph; each * is a commit. Here main is still one commit behind.

--graph --all هەموو وەک دەقی دەکێشێت؛ هەر *ـێک . لێرەدا main هێشتا یەک لە دواوەیە.

After git switch -c feature/delivery-fee and git commit -m "Add a delivery fee of 2,500 IQD": the new commit 07af517 sits above the main line and points to 463271a. The label feature/delivery-fee points to 07af517 and HEAD points to feature/delivery-fee; main still points to 463271a. New commits move the branch that HEAD is on; main stays where it was.دوای git switch -c feature/delivery-fee و git commit -m "Add a delivery fee of 2,500 IQD": کۆمیتە نوێیەکە، 07af517، لە سەرووی هێڵی mainـەوەیە و ئاماژە بە 463271a دەکات. ناوی feature/delivery-fee ئاماژە بە 07af517 دەکات و HEAD ئاماژە بە feature/delivery-fee دەکات؛ main هێشتا ئاماژە بە 463271a دەکات. کۆمیتی نوێ ئەو لقە دەجووڵێنن کە HEAD لەسەریەتی؛ main لە شوێنی خۆی دەمێنێت.
HEAD decides which branch a commit moves. بڕیار دەدات کام بجووڵێنێت.CêIT

Switching with unfinished workگواستنەوە بە کاری تەواونەکراوەوە

Karwan has started writing delivery_fee() but has not committed it. Now Shilan needs main. Switching would replace prices.py with main's version and destroy his edit, so Git refuses:

کاروان دەستی کردووە بە نووسینی delivery_fee() بەڵام هێشتا نەکردووە. ئێستا شیلان پێویستی بە main هەیە. گواستنەوە prices.py بە وەشانەکەی main دەگۆڕێت و دەستکارییەکەی لەناو دەبات، بۆیە Git ڕەتی دەکاتەوە:

Git protects your editGit دەستکارییەکەت دەپارێزێتBASHType in a terminalلە تێرمیناڵدا بینووسە
git status --short
git switch main

Two ways out. Usually simplest: commit the unfinished work on the branch (you can improve it in later commits). For a short break there is git stash: it puts your uncommitted changes in a drawer and makes the working tree clean; later, on the same branch, git stash pop brings them back:

دوو ڕێگە هەیە. زۆرجار سادەترینیان: کارە تەواونەکراوەکە لەسەر بکە (دەتوانیت لە دواتردا باشتری بکەیت). بۆ پشوویەکی کورت git stash هەیە: گۆڕانکارییە دەخاتە چەکمەجەیەکەوە و پاک دەکاتەوە؛ دواتر، لەسەر هەمان ، git stash pop دەیانگەڕێنێتەوە:

Put the edit asideدەستکارییەکە لاوە دابنێBASHType in a terminalلە تێرمیناڵدا بینووسە
git stash
git status --short
git switch main
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

WIP = work in progress. New, untracked files are not stashed unless you add -u.

WIP = کاری بەردەوام. نوێی چاودێرینەکراو stash ناکرێن مەگەر -u زیاد بکەیت.

Three steps. 1, half-finished work: prices.py is modified and git switch main fails with error: Your local changes would be overwritten; Git refuses because the edit would be lost. 2, git stash: the working tree is clean and the edit waits in a drawer labelled WIP on feature/delivery-fee. 3, later: git switch main, help Shilan, git switch - (back), git stash pop; the half-finished edit is back. Bottom: usually simpler, commit your work on the branch first; use the stash for a short break.سێ هەنگاو. 1، کارێکی نیوەچڵ: prices.py دەستکاری کراوە و git switch main بە error: Your local changes would be overwritten سەرناکەوێت؛ Git ڕەتی دەکاتەوە چونکە دەستکارییەکە ون دەبوو. 2، git stash: فۆڵدەری کار پاکە و دەستکارییەکە لە چەکمەجەیەکدا بە ناوی WIP on feature/delivery-fee چاوەڕێ دەکات. 3، دواتر: git switch main، یارمەتیی شیلان، git switch - (گەڕانەوە)، git stash pop؛ دەستکارییە نیوەچڵەکە گەڕایەوە. خوارەوە: زۆرجار سادەتر، سەرەتا کارەکەت لەسەر لقەکە کۆمیت بکە؛ stash بۆ پشوویەکی کورت بەکار بهێنە.
Commit or stash before you switch.پێش گواستنەوە یان stash بکە.CêIT

Fast-forward: the name just movesبەیەککردنی بەپێشخستن: تەنیا ناوەکە دەجووڵێت

Shilan makes her own branch from main, fixes the honey price and commits. Then she switches back to main and merges her branch into it — git merge always brings the named branch into the branch you are on:

شیلان خۆی لە main دروست دەکات، نرخی هەنگوین چاک دەکات و دەکات. پاشان دەگەڕێتەوە سەر main و خۆی تێکەڵی دەکات — git merge هەمیشە ئەو ناوی دەبەیت دەهێنێتە ناو ئەو لەسەریتی:

Shilan’s fix, merged into mainچاککردنەکەی شیلان، تێکەڵ بە mainBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch -c fix/honey-price
git diff
git add prices.py
git commit -m "Fix the price of honey: 30,000 IQD per kg"
git switch main
git merge fix/honey-price
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 6

Updating 463271a..2f5c2b5 + Fast-forward: main simply moved from its old commit to Shilan's.

Updating 463271a..2f5c2b5 + Fast-forward: main تەنیا لە کۆنەکەی خۆیەوە چوو بۆ شیلان.

Nothing new had happened on main since Shilan's branch started, so there was nothing to combine. Git only moved the name main forward to her commit: a fast-forward merge. No new commit is made, and the history stays one straight line.

لەو کاتەوەی شیلان دەستی پێکرد، هیچ شتێکی نوێ لەسەر main ڕووی نەدابوو، بۆیە هیچ شتێک نەبوو تا پێکەوە ببەسترێت. Git تەنیا ناوی mainـی بۆ ئەو برد: . هیچ نوێ دروست ناکرێت و مێژووەکە وەک هێڵێکی ڕاست دەمێنێتەوە.

Before: commits 2ff6abe, 463271a and 2f5c2b5 in a straight line; main and HEAD point to 463271a, fix/honey-price to 2f5c2b5. After git merge fix/honey-price: main (with HEAD) has moved forward to 2f5c2b5, next to fix/honey-price; a dashed label shows where main was. The output Updating 463271a..2f5c2b5, Fast-forward: main had no new commits, so Git only moves the name forward; no new commit is made.پێش: کۆمیتەکانی 2ff6abe، 463271a و 2f5c2b5 لەسەر هێڵێکی ڕاست؛ main و HEAD ئاماژە بە 463271a دەکەن و fix/honey-price بە 2f5c2b5. دوای git merge fix/honey-price: main (لەگەڵ HEAD) چووەتە پێشەوە بۆ 2f5c2b5، لە تەنیشت fix/honey-price؛ ناوێکی پچڕپچڕ پیشان دەدات main پێشتر لە کوێ بوو. دەرخستەکە: Updating 463271a..2f5c2b5، Fast-forward: main هیچ کۆمیتێکی نوێی نەبوو، بۆیە Git تەنیا ناوەکە دەباتە پێشەوە؛ هیچ کۆمیتێکی نوێ دروست ناکرێت.
Fast-forward: no new commit, the name moves.: نوێ نییە، ناوەکە دەجووڵێت.CêIT

Three-way merge: a commit with two parentsبەیەککردنی سێ‌لایەنە: کۆمیتێک بە دوو دایک

Karwan goes back to his branch, takes his work out of the stash and finishes it: delivery_fee() in prices.py and a delivery line in cart.py:

کاروان دەگەڕێتەوە سەر ، کارەکەی لە stash دەردەهێنێت و تەواوی دەکات: delivery_fee() لە prices.py و دێڕێکی گەیاندن لە cart.py:

Back to the featureگەڕانەوە بۆ تایبەتمەندییەکەBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch feature/delivery-fee
git stash pop
git add prices.py cart.py
git commit -m "Add delivery_fee() and show the fee in cart.py"

Now main has a commit his branch does not have (Shilan's fix), and his branch has two commits main does not have: the two lines of work have diverged. Git compares three snapshots — the common ancestor and the two branch tips — joins both sets of changes and records the result in a merge commit with two parents:

ئێستا main هەیە کە ئەو نییەتی (چاککردنەکەی شیلان) و ئەویش دوو هەیە کە main نییەتی: هەردوو هێڵی کارەکە لێک جیا بوونەتەوە. Git سێ وێنەی تەواو بەراورد دەکات — هاوبەشەکەی پێشوو و دوایین هەردوو — هەردوو کۆمەڵە گۆڕانکارییەکە پێکەوە دەبەستێت و ئەنجامەکە لە بە دوو دایک تۆمار دەکات:

A real three-way mergeبەیەککردنێکی سێ‌لایەنەی ڕاستەقینەBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch main
git merge feature/delivery-fee
git log -1
python3 cart.py
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

Merge made by the 'ort' strategy. 'ort' has been Git's default since 2021; older books still print 'recursive'.

Merge made by the 'ort' strategy. لە ساڵی ⁦2021⁩ـەوە ⁦'ort'⁩ ڕێگەی بنەڕەتیی Gitـە؛ کتێبە کۆنەکان هێشتا ⁦'recursive'⁩ دەنووسن.

Lineدێڕی 3

Merge: 2f5c2b5 fadb817 — the two parents.

Merge: 2f5c2b5 fadb817 — هەردوو دایکەکە.

1, the common ancestor 463271a. From it, the main line goes to 2f5c2b5 (2, the tip of main) and the feature/delivery-fee line goes through 07af517 to fadb817 (3, the tip of the branch). The merge commit 58bc993, where main and HEAD now point, has two parents: 2f5c2b5 and fadb817. Git compares 2 and 3 with 1, joins both sets of changes and records them in a new commit with two parents. Output: Merge made by the 'ort' strategy.1، کۆمیتە هاوبەشەکەی پێشوو 463271a. لەوێوە هێڵی main دەچێت بۆ 2f5c2b5 (2، دوایین کۆمیتی main) و هێڵی feature/delivery-fee بە 07af517ـدا دەچێت بۆ fadb817 (3، دوایین کۆمیتی لقەکە). کۆمیتی بەیەککردنەکە، 58bc993، کە ئێستا main و HEAD ئاماژەی پێ دەکەن، دوو دایکی هەیە: 2f5c2b5 و fadb817. Git ⁦2⁩ و ⁦3⁩ بە ⁦1⁩ بەراورد دەکات، هەردوو کۆمەڵە گۆڕانکارییەکە پێکەوە دەبەستێت و لە کۆمیتێکی نوێی دوو دایکدا تۆماریان دەکات. دەرخستەکە: Merge made by the 'ort' strategy.
Three snapshots in, one merge commit out.سێ وێنەی تەواو دەچنە ژوورەوە، یەک دەردەچێت.CêIT

The whole story in motionهەموو چیرۆکەکە بە جووڵە

Here is everything so far, first as an animation, then as Git draws it in text. Read the text graph from the bottom up: each * is a commit, |/ is where a branch started, and the * where two lines meet again is a merge commit.

ئەمە هەموو ئەوەیە کە تا ئێستا ڕوویدا، سەرەتا وەک ئەنیمەیشن، پاشان وەک ئەوەی Git بە دەق دەیکێشێت. دەقییەکە لە خوارەوە بۆ سەرەوە بخوێنەرەوە: هەر *ـێک ، |/ ئەو شوێنەیە کە دەستی پێکرد و ئەو *ـەی دوو هێڵ تێیدا دیسان دەگەنەوە یەک .

Animation in eight steps. 1: main has the shop's working code (2ff6abe, 463271a). 2: git switch -c feature/delivery-fee puts a new name on the same commit and HEAD moves to it. 3: Karwan commits 07af517 on his branch; only feature/delivery-fee moves. 4: Shilan, on fix/honey-price made from main, commits 2f5c2b5. 5: git merge fix/honey-price: fast-forward, main moves to 2f5c2b5. 6: Karwan commits fadb817. 7: git merge feature/delivery-fee: a three-way merge makes 58bc993 with two parents; Merge made by the 'ort' strategy. 8: fast-forward moves the name; a three-way merge adds a merge commit that joins two lines.
Animation in eight steps. 1: main has the shop's working code (2ff6abe, 463271a). 2: git switch -c feature/delivery-fee puts a new name on the same commit and HEAD moves to it. 3: Karwan commits 07af517 on his branch; only feature/delivery-fee moves. 4: Shilan, on fix/honey-price made from main, commits 2f5c2b5. 5: git merge fix/honey-price: fast-forward, main moves to 2f5c2b5. 6: Karwan commits fadb817. 7: git merge feature/delivery-fee: a three-way merge makes 58bc993 with two parents; Merge made by the 'ort' strategy. 8: fast-forward moves the name; a three-way merge adds a merge commit that joins two lines.
Watch the labels: branches move, commits stay.سەیری ناوەکان بکە: دەجووڵێن، دەمێننەوە.CêIT
The same story as textهەمان چیرۆک بە دەقBASHType in a terminalلە تێرمیناڵدا بینووسە
git log --oneline --graph --all

Merge conflictsناکۆکییەکانی بەیەککردن

Most merges are automatic. A merge conflict happens only when both branches changed the same lines of a file in different ways: Git cannot know which is right, so it stops and asks a person. The next day Soran phones: fuel is dearer, delivery is now 3,000 IQD. Shilan changes DELIVERY_FEE = 2500 to 3000 on fix/delivery-fee. At the same time Karwan, on feature/free-delivery, adds the rest of R4 — free delivery from 50,000 IQD of goods — and adds a comment on the same line. Shilan's branch is merged first (a fast-forward). Then Karwan's:

زۆربەی خۆکارن. تەنیا کاتێک ڕوو دەدات کە هەردوو هەمان دێڕەکانی بە دوو شێوەی جیاواز گۆڕیبن: Git نازانێت کامیان ڕاستە، بۆیە دەوەستێت و پرسیار لە کەسێک دەکات. ڕۆژی دواتر سۆران تەلەفۆن دەکات: سووتەمەنی گرانتر بووە، گەیاندن ئێستا ⁦3,000⁩ دینارە. شیلان لەسەر fix/delivery-fee، DELIVERY_FEE = 2500 دەگۆڕێت بۆ 3000. لە هەمان کاتدا کاروان، لەسەر feature/free-delivery، بەشەکەی تری ⁦R4⁩ زیاد دەکات — گەیاندنی بێبەرانبەر لە ⁦50,000⁩ دینار کاڵا بەرەو سەرەوە — و لەسەر هەمان دێڕ زیاد دەکات. سەرەتا شیلان تێکەڵ دەکرێت (). پاشان هی کاروان:

Git stops and asksGit دەوەستێت و دەپرسێتBASHType in a terminalلە تێرمیناڵدا بینووسە
git merge feature/free-delivery
git status
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

CONFLICT (content): the same lines differ. The merge is paused, not lost.

CONFLICT (content): هەمان دێڕەکان جیاوازن. وەستاوە، ون نەبووە.

Git writes both versions into prices.py, between conflict markers. Everything between <<<<<<< HEAD and ======= is your side (the branch you are on, main); everything between ======= and >>>>>>> is the incoming branch:

Git هەردوو وەشانەکە لە ناو prices.pyـدا دەنووسێت، لە نێوان نیشانەکانی ناکۆکیدا. هەموو ئەوەی لە نێوان <<<<<<< HEAD و =======ـدایە لای خۆتە (ئەو لەسەریتی، main)؛ هەموو ئەوەی لە نێوان ======= و >>>>>>>ـدایە هاتووەکەیە:

Lines 9–18 during the mergeدێڕەکانی ⁦9–18⁩ لە کاتی بەیەککردنەکەداprices.pyPYTHON
    "honey": 30000,
}

<<<<<<< HEAD
DELIVERY_FEE = 3000
=======
DELIVERY_FEE = 2500  # IQD, inside Sulaimani
FREE_DELIVERY_FROM = 50_000  # goods total in IQD
>>>>>>> feature/free-delivery

Changed your mind? git merge --abort puts everything back as it was before the merge.

پەشیمان بوویتەوە؟ git merge --abort هەموو شتێک دەگەڕێنێتەوە بۆ ئەوەی پێش بوو.

prices.py during the merge, lines 9 to 18. <<<<<<< HEAD starts your side, the branch you are on (HEAD = main): DELIVERY_FEE = 3000. ======= is the divider between the two versions. Then the incoming side: DELIVERY_FEE = 2500 # IQD, inside Sulaimani and FREE_DELIVERY_FROM = 50_000 # goods total in IQD, ending with >>>>>>> feature/free-delivery, the branch you are merging. Resolved: keep what both people meant and delete the three marker lines: DELIVERY_FEE = 3000 # IQD, inside Sulaimani and FREE_DELIVERY_FROM = 50_000 # goods total in IQD.prices.py لە کاتی بەیەککردنەکەدا، دێڕەکانی 9 تا 18. <<<<<<< HEAD لای خۆت دەست پێدەکات، ئەو لقەی لەسەریتی (HEAD = main): DELIVERY_FEE = 3000. ======= جیاکەرەوەی نێوان هەردوو وەشانەکەیە. پاشان لای هاتوو: DELIVERY_FEE = 2500 # IQD, inside Sulaimani و FREE_DELIVERY_FROM = 50_000 # goods total in IQD، کە بە >>>>>>> feature/free-delivery کۆتایی دێت، ئەو لقەی تێکەڵی دەکەیت. چارەسەرکراو: ئەوە بهێڵەرەوە کە هەردوو کەس مەبەستیان بوو و سێ دێڕە نیشانەکە بسڕەوە: DELIVERY_FEE = 3000 # IQD, inside Sulaimani و FREE_DELIVERY_FROM = 50_000 # goods total in IQD.
Your side, the divider, their side.لای خۆت، جیاکەرەوە، لای ئەوان.CêIT

Resolving a conflictچارەسەرکردنی ناکۆکییەکی بەیەککردن

  1. Decideبڕیار بدە

    Read both sides and decide what the result must be. Here both were right: the new fee 3,000 from Shilan, the comment and FREE_DELIVERY_FROM from Karwan. If you are not sure, ask the people who wrote them.

    هەردوو لاکە بخوێنەرەوە و بڕیار بدە ئەنجامەکە دەبێت چی بێت. لێرەدا هەردووکیان ڕاست بوون: کرێ نوێیەکەی ⁦3,000⁩ لە شیلانەوە، و FREE_DELIVERY_FROM لە کاروانەوە. ئەگەر دڵنیا نیت، لەو کەسانە بپرسە کە نووسیویانە.

  2. Editدەستکاری بکە

    Write the result and delete the three marker lines.

    ئەنجامەکە بنووسە و سێ دێڕە نیشانەکە بسڕەوە.

  3. Addadd بکە

    git add prices.py tells Git the conflict is resolved.

    git add prices.py بە Git دەڵێت ناکۆکییەکە چارەسەر کراوە.

  4. Commitcommit بکە

    git commit finishes the merge. --no-edit keeps Git's ready message Merge branch '…'.

    git commit تەواو دەکات. --no-edit پەیامە ئامادەکەی Git، ⁦Merge branch '…'⁩، دەهێڵێتەوە.

The resolved lines 10–16دێڕە چارەسەرکراوەکانی ⁦10–16⁩prices.pyPYTHON
}

DELIVERY_FEE = 3000  # IQD, inside Sulaimani
FREE_DELIVERY_FROM = 50_000  # goods total in IQD


def round_up_250(amount):
Mark it resolved and finish the mergeوەک چارەسەرکراو نیشانی بکە و بەیەککردنەکە تەواو بکەBASHType in a terminalلە تێرمیناڵدا بینووسە
git diff --check
git add prices.py
git status
git commit --no-edit
python3 cart.py
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

Prints nothing: no conflict markers are left.

هیچ پیشان نادات: هیچ نیشانەیەکی ناکۆکی نەماوە.

Editors help: VS Code marks each conflict with Accept Current Change, Accept Incoming Change, Accept Both Changes and Compare Changes, and has a three-way merge editor. Here Accept Both would keep two DELIVERY_FEE lines — the buttons save typing, but you still decide.

دەستکاریکەرەکان یارمەتی دەدەن: VS Code هەر ناکۆکییەک بە Accept Current Change، Accept Incoming Change، Accept Both Changes و Compare Changes نیشان دەکات و دەستکاریکەرێکی سێ‌بەشیی هەیە. لێرەدا Accept Both دوو دێڕی DELIVERY_FEE دەهێڵێتەوە — نووسینت لێ کەم دەکەنەوە، بەڵام هێشتا تۆ بڕیار دەدەیت.

A simplified VS Code window, not a real screenshot. 1: above the conflict, the actions Accept Current Change, Accept Incoming Change, Accept Both Changes and Compare Changes; or edit the lines yourself. 2: under Merge Changes, prices.py with a Resolve in Merge Editor button, which opens the 3-way merge editor with Incoming, Current and Result. 3: green is your side (Current, HEAD), blue is the other branch (Incoming).پەنجەرەیەکی سادەکراوی VS Code، نەک وێنەی شاشەی ڕاستەقینە. 1: لە سەرووی ناکۆکییەکەوە، کارەکانی Accept Current Change، Accept Incoming Change، Accept Both Changes و Compare Changes؛ یان خۆت دێڕەکان دەستکاری بکە. 2: لە ژێر Merge Changes، prices.py لەگەڵ دوگمەی Resolve in Merge Editor، کە دەستکاریکەری سێ‌بەشیی بەیەککردن بە Incoming، Current و Result دەکاتەوە. 3: سەوز لای خۆتە (Current، HEAD)، شین لقەکەی ترە (Incoming).
The buttons edit the file; you still decide. دەستکاری دەکەن؛ هێشتا تۆ بڕیار دەدەیت.CêIT

Leftover markers break the programنیشانە بەجێماوەکان بەرنامەکە تێک دەدەن

If you run the program while the markers are still in the file — or, worse, commit them — Python stops at once: <<<<<<< is not Python. This is what Karwan saw when he tried cart.py in the middle of the conflict:

ئەگەر جێبەجێ بکەیت لە کاتێکدا نیشانەکان هێشتا لە — یان خراپتر، بکەیت — Python یەکسەر دەوەستێت: <<<<<<< Python نییە. ئەمە ئەوە بوو کە کاروان بینی کاتێک لە ناوەڕاستی ناکۆکییەکەدا cart.pyـی تاقی کردەوە:

Running the program during the conflictجێبەجێکردنی بەرنامەکە لە کاتی ناکۆکییەکەداBASHType in a terminalلە تێرمیناڵدا بینووسە
python3 cart.py

The traceback points to prices.py, line 12: the <<<<<<< HEAD line (reading a traceback, syntax errors). Before git add, let Git look for you: git diff --check lists every leftover marker.

ئاماژە بە prices.py دەکات، دێڕی ⁦12⁩: دێڕی <<<<<<< HEAD (خوێندنەوەی ڕێچکەی هەڵە، هەڵەکانی داڕستن). پێش git add، با Git بۆت بگەڕێت: git diff --check هەموو نیشانەیەکی بەجێماو لیست دەکات.

Git finds the markersGit نیشانەکان دەدۆزێتەوەBASHType in a terminalلە تێرمیناڵدا بینووسە
git diff --check

Fewer, smaller conflictsناکۆکیی کەمتر و بچووکتر

Conflicts are normal in a team, not a disaster. But each one costs time, and the longer two lines of work stay apart, the more they differ. Habits that keep conflicts small:

ناکۆکی لە تیمێکدا شتێکی ئاساییە، کارەسات نییە. بەڵام هەریەکەیان کاتی دەوێت و هەتا دوو هێڵی کار زیاتر لێک دوور بمێننەوە، زیاتر لێک جیاواز دەبن. خووەکان کە ناکۆکییەکان بچووک دەهێڵنەوە:

  • Small, short-lived branches — one task each, merged within a day or two.
  • Merge main into your branch often (git merge main while you are on your branch), so you meet other people's changes early, when they are small.
  • Talk to the team: “I am changing the delivery code today.” Two people should not rewrite the same function at the same time.
  • Keep style changes separate: re-indenting a whole file in a feature commit causes conflicts everywhere. Agree on one style.
  • Run the program and its tests after every merge — a clean merge can still combine two changes that do not work together (automated testing).
  • بچووک و کورتخایەن — هەریەکە یەک کار، لە ماوەی ڕۆژێک یان دوو ڕۆژدا تێکەڵ دەکرێن.
  • زۆرجار main تێکەڵی بکە (git merge main کاتێک لەسەر خۆتیت)، بۆ ئەوەی گۆڕانکاریی کەسانی تر زوو ببینیت، کاتێک هێشتا بچووکن.
  • لەگەڵ تیمەکە قسە بکە: «ئەمڕۆ کۆدی گەیاندن دەگۆڕم.» دوو کەس نابێت لە یەک کاتدا هەمان دووپاتە بنووسنەوە.
  • گۆڕانکاریی شێوەی نووسین جیا بکەرەوە: گۆڕینی هەموو لە تایبەتمەندییەکدا لە هەموو شوێنێک ناکۆکی دروست دەکات. لەسەر یەک شێوە ڕێک بکەون.
  • دوای هەموو و تاقیکردنەوەکانی جێبەجێ بکە — بێ ناکۆکی هێشتا دەتوانێت دوو گۆڕانکاری پێکەوە ببەستێت کە پێکەوە کار ناکەن (تاقیکردنەوەی خۆکار).
Top, short-lived branches: six small branches each leave main and come back after hours or a day; small merges, few conflicts. Bottom, a long-lived branch: it runs beside main for many commits while main also moves on; three weeks later the merge brings many conflicts. Merge main into your branch often, keep branches small, talk to your team.سەرەوە، لقی کورتخایەن: شەش لقی بچووک هەریەکە لە main جیا دەبێتەوە و دوای چەند کاتژمێرێک یان ڕۆژێک دەگەڕێتەوە؛ بەیەککردنی بچووک، ناکۆکیی کەم. خوارەوە، لقێکی درێژخایەن: بۆ چەندین کۆمیت لە تەنیشت main دەڕوات و mainـیش بەردەوام دەگۆڕێت؛ دوای 3 هەفتە بەیەککردنەکە ناکۆکیی زۆر دەهێنێت. main زۆرجار تێکەڵی لقەکەت بکە، لقەکان بچووک بهێڵەرەوە، لەگەڵ تیمەکەت قسە بکە.
Merge early and often.زوو و زۆرجار تێکەڵ بکە.CêIT

Delete merged branches; name them wellلقە تێکەڵکراوەکان بسڕەوە؛ ناوی باشیان لێ بنێ

A merged branch has done its job. git branch --merged lists the branches whose commits are all in the current branch, and git branch -d deletes them. Only the names go; the commits stay in main's history.

تێکەڵکراو کاری خۆی کردووە. git branch --merged ئەو لیست دەکات کە هەموو لە ئێستادان و git branch -d دەیانسڕێتەوە. تەنیا ناوەکان دەڕۆن؛ لە مێژووی mainـدا دەمێننەوە.

Tidy up after mergingدوای بەیەککردن ڕێکی بخەBASHType in a terminalلە تێرمیناڵدا بینووسە
git branch --merged
git branch -d fix/honey-price feature/delivery-fee fix/delivery-fee feature/free-delivery

Git protects unmerged work. Karwan tried a 5 % discount on experiment/discount, and Soran said no. -d refuses to delete a branch that is not merged; only -D forces it — and then those commits are lost:

Git کاری تێکەڵنەکراو دەپارێزێت. کاروان داشکاندنی ⁦5%⁩ لەسەر experiment/discount تاقی کردەوە و سۆران گوتی نا. -d ڕەت دەکاتەوە تێکەڵنەکراو بسڕێتەوە؛ تەنیا -D بە زۆر دەیسڕێتەوە — و ئەوکات ئەو ون دەبن:

-d refuses, -D forces-d ڕەت دەکاتەوە، -D بە زۆر دەیکاتBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch -c experiment/discount
git commit -am "Try 5 % off every order"
git switch main
git branch -d experiment/discount
git branch -D experiment/discount
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2

-am: stage all changed tracked files and commit in one step. Handy, but it skips your look at git status.

-am: هەموو چاودێریکراوە گۆڕاوەکان ئامادە دەکات و لە یەک هەنگاودا دەکات. بەسوودە، بەڵام سەیرکردنی git status لێ دەبڕێت.

Names tell the team what a branch is for: feature/… for new work, fix/… for bug fixes, short, lowercase, words joined with hyphens — feature/free-delivery, fix/honey-price. Some teams add the issue number: fix/12-honey-price.

ناوەکان بە تیمەکە دەڵێن بۆ چییە: feature/… بۆ کاری نوێ، fix/… بۆ چاککردنی ، کورت، بە پیتی بچووک، وشەکان بە هێڵی کورت بەستراون — feature/free-delivery، fix/honey-price. هەندێک تیم ژمارەی ئیشووەکەش زیاد دەکەن: fix/12-honey-price.

A name that stays: tagsناوێک کە دەمێنێتەوە: تاگەکانی Git

Bazaar Cart now has all of rule R4 (3,000 IQD inside Sulaimani, free from 50,000 IQD of goods) and the honey fix — a good moment to mark a version. A tag is a name for one commit that, unlike a branch, never moves:

Bazaar Cart ئێستا هەموو ڕێسای ⁦R4⁩ـی تێدایە (⁦3,000⁩ دینار لە ناو سلێمانی، بێبەرانبەر لە ⁦50,000⁩ دینار کاڵا بەرەو سەرەوە) و چاککردنەکەی هەنگوینیش — کاتێکی باشە بۆ نیشانکردنی . ناوێکە بۆ یەک کە بە پێچەوانەی هەرگیز ناجووڵێت:

Mark version 0.2.0وەشانی ⁦0.2.0⁩ نیشان بکەBASHType in a terminalلە تێرمیناڵدا بینووسە
git tag v0.2.0
git log --oneline -1

What the numbers in 0.2.0 and 1.0.0 promise, annotated tags (git tag -a) and releases are taught in Versions and builds.

ئەوەی ژمارەکانی ⁦0.2.0⁩ و ⁦1.0.0⁩ بەڵێنی دەدەن، جۆری annotatedـی (git tag -a) و لە وەشان و بیلد فێر دەکرێن.

$ git tag v0.2.0. Commits 58bc993, 709b275 and bf0326b, then two dashed future commits. The tag v0.2.0 points to bf0326b and stays there. The label main is shown three times, moving from bf0326b to the future commits: a branch moves with every commit. Versions such as 0.2.0 and 1.0.0 are explained in Versions and builds.$ git tag v0.2.0. کۆمیتەکانی 58bc993، 709b275 و bf0326b، پاشان دوو کۆمیتی داهاتووی پچڕپچڕ. تاگی Git v0.2.0 ئاماژە بە bf0326b دەکات و لەوێ دەمێنێتەوە. ناوی main سێ جار پیشان دراوە و لە bf0326bـەوە بەرەو کۆمیتە داهاتووەکان دەجووڵێت: لق بە هەر کۆمیتێک دەجووڵێت. واتای وەشانی وەک 0.2.0 و 1.0.0 لە وانەی «وەشان و بیلد»ـدا ڕوون کراوەتەوە.
A branch moves; a tag stays. دەجووڵێت؛ دەمێنێتەوە.CêIT

Branching strategies: GitHub flow and trunk-basedستراتیژییەکانی بەکارهێنانی لق: GitHub flow و ⁦trunk-based⁩

A branching strategy is the team's agreement on how branches are used: when to make one, how long it lives, how it is named and how it gets back into main. Three you will meet:

ڕێککەوتنی تیمەکەیە لەسەر چۆنیەتیی بەکارهێنانی : کەی دروست دەکرێت، چەند دەژی، چۆن ناو دەنرێت و چۆن دەگەڕێتەوە ناو main. سێ دانەیان دەبینیت:

  • GitHub flow: main is always ready to use. Every change gets a short branch, then a pull request with a review, then a merge, and the branch is deleted. Pull requests are the topic of GitHub and teamwork.
  • Trunk-based development: everyone merges into main (the trunk) at least once a day, with branches that live a day or less. Automatic tests keep main working (automated testing).
  • Long-lived branches, for example Git Flow with separate develop and release branches: they suit software released in planned versions, but the branches drift apart and merges bring more conflicts.
  • GitHub flow: main هەمیشە ئامادەی بەکارهێنانە. هەر گۆڕانکارییەک کورت وەردەگرێت، پاشان لەگەڵ پێداچوونەوە، پاشان و دەسڕدرێتەوە. بابەتی GitHub و کاری تیمیـن.
  • ⁦Trunk-based development⁩: هەموو کەسێک لانیکەم ڕۆژی جارێک کارەکەی تێکەڵی main (قەد) دەکات، بە کە ڕۆژێک یان کەمتر دەژین. main کارکەر دەهێڵنەوە (تاقیکردنەوەی خۆکار).
  • درێژخایەن، بۆ نموونە Git Flow بە جیای develop و release: بۆ ئەو گونجاون کە بە وەشانی پلاندانراو بڵاو دەکرێنەوە، بەڵام لێک دوور دەکەونەوە و ناکۆکیی زیاتر دەهێنن.

Bazaar Cart's team of four uses GitHub flow: short branches, a review before every merge, main always ready for Soran's shop. Its six steps on GitHub are shown in GitHub and Teamwork.

تیمە چوار کەسییەکەی Bazaar Cart GitHub flow بەکار دەهێنێت: کورت، پێداچوونەوە پێش هەموو ، main هەمیشە ئامادە بۆ دوکانەکەی سۆران. شەش هەنگاوەکەی لەسەر GitHub لە GitHub و کاری تیمی پیشان دراون.

GitHub flow on a main line: 1 create a branch (feature/free-delivery), 2 commit small changes, 3 open a pull request, 4 review and fix, 5 merge into main, 6 delete the branch. GitHub flow: main is always ready to use. Trunk-based teams do the same with branches that live a day or less.GitHub flow لەسەر هێڵی main: 1 لقێک دروست بکە (feature/free-delivery)، 2 گۆڕانکاریی بچووک کۆمیت بکە، 3 داواکارییەکی بەیەککردن بکەرەوە، 4 پێداچوونەوە و چاککردن، 5 بیخە ناو main، 6 لقەکە بسڕەوە. ڕەوتی GitHub: main هەمیشە ئامادەی بەکارهێنانە. ئەو تیمانەی شێوازی trunk-based بەکار دەهێنن هەمان کار دەکەن بە لقانێک کە ڕۆژێک یان کەمتر دەژین.
Short branches, reviewed, merged, deleted. کورت، پێداچوونەوە، ، سڕینەوە.CêIT

Common mistakesهەڵە باوەکان

  • Working on main by mistake. Make the branch before you start; the first line of git status (On branch …) tells you where you are.
  • Merging the wrong way. git merge X brings X into the branch you are on. To bring a feature into main, switch to main first.
  • Resolving by clicking one side without reading. Accept Current may delete a teammate's work. Read both sides; often the answer keeps parts of each.
  • Committing conflict markers → SyntaxError. Run git diff --check and the program before git add.
  • git branch -D to tidy up. It deletes unmerged work without asking. Use -d and read its message.
  • Branches that live for weeks. Merge small pieces often instead.
  • Switching with uncommitted work and not noticing that the changes came along to the other branch. Check git status after git switch.
  • کارکردن لەسەر main بە هەڵە. پێش دەستپێکردن دروست بکە؛ یەکەم دێڕی git status (On branch …) پێت دەڵێت لە کوێیت.
  • بە ئاڕاستەی هەڵە. git merge X X دەهێنێتە ناو ئەو لەسەریتی. بۆ هێنانی تایبەتمەندییەک بۆ ناو main، سەرەتا بچۆ سەر main.
  • چارەسەرکردن بە کرتەکردن لە یەک لا بێ خوێندنەوە. Accept Current لەوانەیە کاری هاوکارێک بسڕێتەوە. هەردوو لا بخوێنەرەوە؛ زۆرجار وەڵامەکە بەشێک لە هەریەکەیان دەهێڵێتەوە.
  • نیشانەکانی ناکۆکی ← SyntaxError. پێش git add، git diff --check و جێبەجێ بکە.
  • git branch -D بۆ ڕێکخستن. کاری تێکەڵنەکراو بێ پرسیار دەسڕێتەوە. -d بەکار بهێنە و پەیامەکەی بخوێنەرەوە.
  • ئەو چەند هەفتەیەک دەژین. لە جیاتی ئەوە بەشی بچووک زۆرجار تێکەڵ بکە.
  • گواستنەوە بە کاری و هەست پێنەکردن کە گۆڕانکارییەکان لەگەڵت هاتوونەتە سەر ترەکە. دوای git switch سەیری git status بکە.

Exercisesڕاهێنانەکان

ExerciseڕاهێنانFast-forward or three-way?بەیەککردنی بەپێشخستن یان سێ‌لایەنە؟

(a) Lana makes fix/typo from main, commits once, and nobody else commits; she merges it into main. (b) Rebin makes feature/map from main and commits twice; meanwhile Hana's fix is merged into main; then Rebin's branch is merged. Which kind of merge is each?

⁦(a)⁩ لانا fix/typo لە main دروست دەکات، یەک جار دەکات و کەسی تر ناکات؛ تێکەڵی mainـی دەکات. ⁦(b)⁩ ڕێبین feature/map لە main دروست دەکات و دوو جار دەکات؛ لەو کاتەدا چاککردنەکەی هانا تێکەڵی main دەکرێت؛ پاشان ڕێبین تێکەڵ دەکرێت. هەریەکەیان چ جۆرە ؟

Show answerوەڵامەکە پیشان بدە
  • (a) Fast-forward: main had nothing new, so its name just moves to Lana's commit.
  • (b) Three-way: both sides have new commits, so Git makes a merge commit with two parents.
  • ⁦(a)⁩ : main هیچی نوێی نەبوو، بۆیە ناوەکەی تەنیا دەچێت بۆ لانا.
  • ⁦(b)⁩ سێ‌لایەنە: هەردوو لا نوێیان هەیە، بۆیە Git بە دوو دایک دروست دەکات.
ExerciseڕاهێنانResolve the taxi conflictناکۆکییەکەی تەکسییەکە چارەسەر بکە

In Hawler Ride, Hana raised the base fare and Rebin added a night fare on the same line. Git shows this. Write the resolved lines, keeping both ideas.

لە Hawler Ride، هانا کرێی بنەڕەتی بەرز کردەوە و ڕێبین لەسەر هەمان دێڕ کرێی شەوی زیاد کرد. Git ئەمە پیشان دەدات. دێڕە چارەسەرکراوەکان بنووسە و هەردوو بیرۆکەکە بهێڵەرەوە.

fares.py during the merge⁦fares.py⁩ لە کاتی بەیەککردنەکەداTEXT
<<<<<<< HEAD
BASE_FARE = 2500
=======
BASE_FARE = 2000
NIGHT_FARE = 3000  # from 23:00 to 06:00
>>>>>>> feature/night-fare
Show answerوەڵامەکە پیشان بدە
ResolvedچارەسەرکراوPYTHON
BASE_FARE = 2500
NIGHT_FARE = 3000  # from 23:00 to 06:00

Hana's new base fare (2,500) and Rebin's night fare both stay; the three marker lines are gone. Then git add fares.py and git commit. If the night fare was meant to be relative to the old base fare, ask Rebin before you decide.

کرێ بنەڕەتییە نوێیەکەی هانا ⁦(2,500)⁩ و کرێی شەویی ڕێبین هەردووکیان دەمێننەوە؛ سێ دێڕە نیشانەکە نەماون. پاشان git add fares.py و git commit. ئەگەر کرێی شەوی بەپێی کرێ بنەڕەتییە کۆنەکە دانرابوو، پێش بڕیاردان لە ڕێبین بپرسە.

ExerciseڕاهێنانDraw the graphگرافەکە بکێشە

Starting from one commit A on main, these commands run: git switch -c feature/x, commit B, git switch main, commit C, git merge feature/x. Draw the commits, the branch names and HEAD.

لە یەک A لەسەر mainـەوە، ئەم جێبەجێ دەکرێن: git switch -c feature/x، B، git switch main، C، git merge feature/x. ، ناوی و بکێشە.

Show answerوەڵامەکە پیشان بدە
A real run, with commit messages A, B and Cجێبەجێکردنێکی ڕاستەقینە، بە پەیامی کۆمیتی A، B و CBASHType in a terminalلە تێرمیناڵدا بینووسە
git log --oneline --graph --all

C and B both have A as their parent. The merge commit (the top line) has two parents, C and B, so the graph splits below it. main and HEAD are on the merge commit; feature/x stays on B until you delete it.

C و B هەردووکیان A وەک دایک هەیانە. (دێڕی سەرەوە) دوو دایکی هەیە، C و B، بۆیە لە ژێریدا دەبێت بە دوو. main و لەسەر ؛ feature/x لەسەر B دەمێنێتەوە تا دەیسڕیتەوە.

ExerciseڕاهێنانMake a conflict on purposeبە ئەنقەست ناکۆکییەک دروست بکە

In your practice repository from the last lesson, make two branches from main that change the same line of menu.txt differently. Merge both into main, resolve the conflict, and finish with git log --oneline --graph.

لە practiceـی وانەی پێشوودا، دوو لە main دروست بکە کە هەمان دێڕی menu.txt بە دوو شێوەی جیاواز دەگۆڕن. هەردووکیان تێکەڵی main بکە، ناکۆکییەکە چارەسەر بکە و بە git log --oneline --graph کۆتایی پێ بهێنە.

Hintئاماژە

Both branches must start from the same main commit and edit the same line.

هەردوو دەبێت لە هەمان mainـەوە دەست پێبکەن و هەمان دێڕ دەستکاری بکەن.

Show answerوەڵامەکە پیشان بدە
One possible wayیەک ڕێگەی گونجاوBASHType in a terminalلە تێرمیناڵدا بینووسە
git switch -c fix/dolma-price
# change the dolma line, then:
git commit -am "Change the dolma price"
git switch main
git switch -c feature/dolma-name
# change the same line in another way, then:
git commit -am "Rename dolma to yaprax"
git switch main
git merge fix/dolma-price        # Fast-forward
git merge feature/dolma-name     # CONFLICT (content)
# edit menu.txt, remove the markers, then:
git diff --check
git add menu.txt
git commit --no-edit
git log --oneline --graph
ExerciseڕاهێنانName the branchesناو بۆ لقەکان دابنێ

Give a branch name for each task: (1) show prices in Kurdish digits; (2) the total is wrong for 0 g of tea; (3) try a dark colour theme, which may be thrown away.

بۆ هەر کارێک ناوێکی دابنێ: ⁦(1)⁩ پیشاندانی نرخەکان بە ژمارەی کوردی؛ ⁦(2)⁩ کۆی گشتی بۆ 0 گرام چا هەڵەیە؛ ⁦(3)⁩ تاقیکردنەوەی ڕەنگێکی تاریک کە لەوانەیە فڕێ بدرێت.

Show answerوەڵامەکە پیشان بدە
  • (1) feature/kurdish-digits
  • (2) fix/zero-grams-total
  • (3) experiment/dark-theme — delete it with -D if the team says no.
  • ⁦(1)⁩ بۆ نموونە feature/kurdish-digits
  • ⁦(2)⁩ بۆ نموونە fix/zero-grams-total
  • ⁦(3)⁩ experiment/dark-theme — ئەگەر تیمەکە گوتی نا، بە -D بیسڕەوە.

Summaryپوختە

  • A branch is a movable name for a commit; it costs almost nothing. HEAD marks where you are. git switch -c <name> creates a branch and moves to it.
  • New commits move only the branch HEAD is on. git log --oneline --graph --all draws every branch.
  • Unfinished work blocks a switch when it would be overwritten: commit it, or git stash and later git stash pop.
  • git merge X brings X into the current branch. Fast-forward: the name only moves. Three-way: a merge commit with two parents ('ort' strategy).
  • A merge conflict means both sides changed the same lines. Decide, edit, delete the markers, git add, git commit; git merge --abort cancels.
  • Leftover markers break the code (SyntaxError); git diff --check finds them.
  • Small, short-lived branches, merging main in often and talking to the team keep conflicts small.
  • Delete merged branches with git branch -d; name them feature/… and fix/…. A tag such as v0.2.0 never moves.
  • Strategies: GitHub flow and trunk-based (short branches) vs long-lived branches (Git Flow). Never rebase commits others already have.
  • Next: GitHub and teamwork — the same branches, shared through a remote repository and pull requests.
  • ناوێکی جووڵاوە بۆ ؛ نزیکەی هیچی تێناچێت. نیشانی دەدات لە کوێیت. git switch -c <name> دروست دەکات و دەچێتە سەری.
  • نوێ تەنیا ئەو دەجووڵێنن کە لەسەریەتی. git log --oneline --graph --all هەموو دەکێشێت.
  • کاری تەواونەکراو ڕێگە لە گواستنەوە دەگرێت ئەگەر لەناو بچێت: بکە، یان git stash و دواتر git stash pop.
  • git merge X X دەهێنێتە ناو ئێستا. : تەنیا ناوەکە دەجووڵێت. سێ‌لایەنە: بە دوو دایک (⁦'ort' strategy⁩).
  • واتە هەردوو لا هەمان دێڕەکانیان گۆڕیوە. بڕیار بدە، دەستکاری بکە، نیشانەکان بسڕەوە، git add، git commit؛ git merge --abort هەڵیدەوەشێنێتەوە.
  • نیشانە بەجێماوەکان کۆدەکە تێک دەدەن (SyntaxError)؛ git diff --check دەیاندۆزێتەوە.
  • بچووک و کورتخایەن، زۆرجار تێکەڵکردنی main و قسەکردن لەگەڵ تیم ناکۆکییەکان بچووک دەهێڵنەوە.
  • تێکەڵکراوەکان بە git branch -d بسڕەوە؛ ناویان بنێ feature/… و fix/…. وەک v0.2.0 هەرگیز ناجووڵێت.
  • ستراتیژییەکان: GitHub flow و ⁦trunk-based⁩ ( کورت) بەرامبەر درێژخایەن ⁦(Git Flow)⁩. هەرگیز ئەو rebase مەکە کە کەسانی تر هەیانە.
  • دواتر: GitHub و کاری تیمی — هەمان ، کە لە ڕێی و هاوبەش دەکرێن.

Lesson complete!وانەکە تەواو بوو!

Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.

Key termsزاراوە سەرەکییەکان

Next lessonوانەی داهاتوو

GitHub and Teamwork: Remotes, Pull Requests and IssuesGitHub و کاری تیمی: کۆگاکانی کۆدی دوور، داواکارییەکانی بەیەککردن و ئیشووەکان

References and further readingسەرچاوەکان و خوێندنەوەی زیاتر

This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.

Appearanceڕووکار

Modeدۆخ
Styleشێواز
Coloursڕەنگەکان

Saved on this device only.تەنیا لەسەر ئەم ئامێرە پاشەکەوت دەکرێت.