رفتن به محتوا
LoopX

آزمون بخش ۴: حرفه‌ای

این آزمون چهار درس بخش «حرفه‌ای» را می‌سنجد. جواب هر سؤال همان لحظه با توضیح نشان داده می‌شود و نتیجه‌ات در همین مرورگر ذخیره می‌شود (پیشرفت من).

؟ آزمون بخش ۴
  1. workflow های GitHub Actions را کجا می‌گذاری؟

  2. job های یک workflow پیش‌فرض چطور اجرا می‌شوند و ترتیب را چطور می‌دهی؟

  3. چرا اولین step تقریباً هر job «uses: actions/checkout@v4» است؟

  4. چرا عنوان PR را نباید مستقیم داخل run: بگذاری؟

  5. ابزار actionlint چه می‌کند؟

  6. reflog چیست؟

  7. شاخه‌ای را با git branch -D پاک کرده‌ای. چطور برمی‌گردانی؟

  8. git cherry-pick -x هش چه می‌کند؟

  9. git bisect run ./test.sh چه می‌کند و تست چه کد خروجی‌ای می‌دهد؟

  10. چهار نوع شیء Git؟

  11. شناسه‌ی یک blob از چه ساخته می‌شود؟

  12. شاخه در Git پشت پرده چیست؟

  13. چرا «بازنویسی تاریخچه» در واقع commit جدید می‌سازد؟

  14. git gc و packfile چه می‌کنند؟

  15. در پروژه‌ی تیمی، چرا بعد از حل conflict تست‌ها را اجرا می‌کنیم؟

  16. برای رساندن یک رفع باگ به نسخه‌ی منتشرشده‌ی v1.0.0 بدون ویژگی‌های نیمه‌تمام main چه می‌کنی؟

🏁 چالش: نجات، جست‌وجو و CIسخت

با آنچه در این بخش آموختی، چهار کار را روی یک مخزن آزمایشی انجام بده:

۱. ده commit با پیام‌های قراردادی بساز که فایل calc.py در آن‌ها یک تابع add دارد؛ در یکی از commit های میانی (بدون اینکه پیام بگوید) add را خراب کن. با git bisect run و یک اسکریپت تست، commit خراب را خودکار پیدا کن و ثابت کن همان است. ۲. یک شاخه‌ی feature/x با دو commit بساز، آن را با git branch -D پاک کن و فقط با reflog برگردان. ۳. با git cat-file و بدون checkout، محتوای فایل calc.py را از commit فعلی چاپ کن، و تعداد شیء‌های مخزن را به تفکیک نوع (blob، tree، commit) بشمار. ۴. یک workflow برای اجرای تست‌ها بنویس، با actionlint ثابت کن درست است؛ بعد یک غلط تایپی عمدی (مثلاً runs-on: ubuntu-lastest) بگذار و ببین actionlint چه می‌گوید. ۵. همه‌چیز را پاک کن.

راهنمایی

برای ۱: git bisect start HEAD <اولین commit> و git bisect run ./test.sh (اسکریپتی که اگر add(2,3) پنج نباشد با کد ۱ تمام شود؛ از python3 -B استفاده کن). برای ۲: git reflog | grep -A1 "moving from feature/x to main". برای ۳: git cat-file -p HEAD:calc.py و git cat-file --batch-all-objects --batch-check='%(objecttype)'. برای ۴: actionlint باید داخل یک مخزن Git اجرا شود.

راه‌حل
Terminal window
export PYTHONDONTWRITEBYTECODE=1
git config --global user.name "Ali"
git config --global user.email "ali@example.com"
git config --global init.defaultBranch main
mkdir -p ~/gitlab/quiz4 && cd ~/gitlab/quiz4 && git init -q
printf 'def add(a, b):\n return a + b\n' > calc.py
git add calc.py && git commit -qm "feat: add calc" && first=$(git rev-parse --short HEAD)
for i in 1 2 3 4; do echo "note $i" >> notes.txt; git add notes.txt; git commit -qm "docs: note $i"; done
sed -i 's/return a + b/return a - b/' calc.py && git commit -qam "refactor: simplify add" && bad=$(git rev-parse --short HEAD)
for i in 5 6 7 8; do echo "note $i" >> notes.txt; git add notes.txt; git commit -qm "docs: note $i"; done
cat > test.sh <<'EOF'
#!/bin/sh
python3 -B -c "from calc import add; import sys; sys.exit(0 if add(2, 3) == 5 else 1)"
EOF
chmod +x test.sh
echo "== ۱) bisect"
git bisect start HEAD $first > /dev/null
git bisect run ./test.sh 2>&1 | grep "first bad commit"
found=$(git rev-parse --short refs/bisect/bad); git bisect reset > /dev/null 2>&1
echo "مقصر واقعی: $bad ؛ پیدا شده: $found"
echo "== ۲) نجات شاخه"
git switch -qc feature/x
echo "x1" > x.txt && git add x.txt && git commit -qm "feat: add x"
echo "x2" >> x.txt && git commit -qam "feat: extend x"
git switch -q main && git branch -D feature/x -q
h=$(git reflog | grep -A1 "moving from feature/x to main" | tail -1 | awk '{print $1}')
git branch feature/x $h && git log --oneline feature/x -1
echo "== ۳) شیء‌ها"
git cat-file -p HEAD:calc.py
echo "تعداد شیء‌ها به تفکیک نوع:"
git cat-file --batch-all-objects --batch-check='%(objecttype)' | sort | uniq -c
echo "== ۴) workflow"
mkdir -p .github/workflows
cat > .github/workflows/ci.yml <<'EOF'
name: CI
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python3 -m unittest discover -s tests
EOF
actionlint -color=false; echo "درست: کد خروج $?"
sed -i 's/ubuntu-latest/ubuntu-lastest/' .github/workflows/ci.yml
actionlint -color=false 2>&1 | head -1 | cut -c1-120
echo "== ۵) پاک‌سازی"
cd ~ && rm -rf ~/gitlab ~/.gitconfig
خروجی
== ۱) bisect
14a1e4b5400ba52032421c2b68221a4c9255efb9 is the first bad commit
bisect found first bad commit
مقصر واقعی: 14a1e4b ؛ پیدا شده: 14a1e4b
== ۲) نجات شاخه
0f0dfbf feat: extend x
== ۳) شیء‌ها
def add(a, b):
return a - b
تعداد شیء‌ها به تفکیک نوع:
12 blob
12 commit
12 tree
== ۴) workflow
درست: کد خروج 0
.github/workflows/ci.yml:5:14: label "ubuntu-lastest" is unknown. available labels are "windows-latest", "windows-latest
== ۵) پاک‌سازی