3.4 עבודה עם git הרצאה
הagent Claude Code רץ בטרמינל, ולכן git הוא כלי טבעי בשבילו בדיוק כמו בשבילכם - הוא יכול להריץ git status, git diff, git commit, לפתוח branch, וליצור PR דרך gh. זה נוח מאוד, וזה גם בדיוק המקום שבו נוחות יכולה להפוך לרשלנות: קל מאוד לתת לagent "לסיים" עבודה על ידי commit ו-push בלי שאף אחד עבר על מה שבאמת נכנס להיסטוריה. בהרצאה הזו נעבור על כל שלבי העבודה עם git מול agent - staging, ניסוח הודעות commit, יצירת branch ו-PR, סקירת diff, פתרון conflicts - ונקבע גדרות הגנה ברורות שמונעות מהנוחות הזו להזיק.
הכלל המסגרת: הagent מריץ git, אתם מאשרים¶
לפני שנכנסים לפרטים, כלל אחד שחוצה את כל ההרצאה: אף שינוי לא נכנס להיסטוריית git בלי שראיתם אותו. זה נכון גם ל-git add, גם ל-git commit, ובוודאי ל-git push. Claude Code בהגדרת ברירת מחדל מבקש אישור לפעולות כאלה, וזה לא עיצוב שרירותי - זה בדיוק שכבת ההגנה שאתם צריכים. אל תסירו אותה כדי "לחסוך זמן". הזמן שנחסך היום הוא הזמן שתשקיעו בעוד שבוע בניקוי היסטוריית git מבולגנת או, גרוע מכך, בלגלות ש-commit נדחף לענף main בלי סקירה.
Staging: מה נכנס ל-commit¶
לפני commit יש שאלה שקל לדלג עליה: האם כל מה ששונה צריך להיכנס לאותו commit? הagent שמריץ git add -A בלי לחשוב מכניס יחד שינויים לא קשורים - למשל את הפיצ'ר שביקשתם, בתוספת קובץ קונפיגורציה שהשתנה בטעות בזמן ניסוי מקומי.
> Show me git status and suggest which files belong to this commit
and which don't. Don't add anything before I approve.
$ git status --short
M src/services/orderService.ts
M src/api/controllers/orderController.ts
M .env.local
?? src/api/__tests__/orders.export.test.ts
< src/services/orderController.ts and orderController.ts belong
to the export feature. The new test also belongs. .env.local looks
like a local environment file that changed by mistake - it shouldn't
go into this commit, and it's worth making sure it's in .gitignore.
ההרגל הזה - לבקש מיפוי מפורש של מה שייך למה, לפני git add - חוסך המון conflicts ובלבול בהמשך, במיוחד כשעובדים על כמה דברים בו-זמנית.
כתיבת הודעות commit - commit messages¶
agent יכול לכתוב הודעת commit טובה, אבל רק אם נותנים לו את הcontext הנכון. הודעה טובה מסבירה למה, לא רק מה - ה"מה" כבר נמצא ב-diff עצמו.
> Write a commit message for the changes staged so far. Explain
why the change is needed, not just what changed. Keep the format
used in the project - check git log for recent examples.
בדיקת git log לפני ניסוח היא צעד חשוב: לכל פרויקט יש קונבנציה - Conventional Commits (feat:, fix:, chore:), פורמט חופשי, או משהו אחר. הagent שבודק את ההיסטוריה לפני שהוא כותב נשמע כאילו הוא תמיד היה חלק מהצוות.
$ git log --oneline -5
a3f21c9 fix: prevent duplicate webhook processing on retry
9b04e11 feat: add rate limiting to public API endpoints
7d18aa2 chore: bump prisma to 5.9.0
< feat: add CSV export endpoint for orders
Users can now export their orders within a date range as CSV
via GET /orders/export. Filters by userId to prevent leaking
other users' data; returns 400 on missing/invalid date params.
שימו לב שההודעה מזכירה במפורש את סינון ה-userId - זו בדיוק סוג הפרט שיעזור למי שיקרא את ההיסטוריה בעוד חצי שנה להבין למה השורה הזו שם.
יצירת branch ו-PR - branches and pull requests¶
כלל ברזל: אף פעם לא עובדים ישירות על main. גם כשמדובר בשינוי קטן. תמיד מבקשים מהagent ליצור branch ייעודי לפני שמתחילים לעבוד:
> Create a new branch named feature/orders-csv-export from the latest
main, and switch to it before we start implementing.
$ git checkout -b feature/orders-csv-export main
Switched to a new branch 'feature/orders-csv-export'
בסיום העבודה, דוחפים ומבקשים ליצור PR - כשהagent יכול להשתמש ב-gh (GitHub CLI) ליצור אותו ישירות, כולל תיאור:
> Push the branch and create a PR against main. In the PR
description, include a summary of the change, and a list of tests
you ran with their results.
$ git push -u origin feature/orders-csv-export
$ gh pr create --title "feat: add CSV export endpoint for orders" \
--body "## Summary
- Adds GET /orders/export to download orders as CSV for a date range
- Filters by userId - prevents data leakage between users
## Test plan
- [x] Unit tests: findByDateRange, validation, isolation between users
- [x] Full test suite passed (npm test)
"
תיאור PR שכולל test plan מפורש הוא לא רק נוחות לביקורת - הוא מכריח אתכם ואת הagent לענות בפירוש על "איך אנחנו יודעים שזה עובד", לא רק "מה השתנה".
סקירת diff לפני commit - reviewing the diff¶
זה חוזר מהרצאה 3.2, אבל בcontext git הוא מקבל ממד נוסף: git diff --staged הוא בדיוק מה שייכנס להיסטוריה, ולכן זה הרגע האחרון לתפוס בעיה לפני שהיא "רשמית".
בסקירה שימו לב במיוחד לשני דברים שקל לפספס:
- קבצים שלא היו אמורים להשתנות - למשל שינוי לא מכוון בקובץ lock, בהגדרות linter, או formatting אוטומטי שרץ על קבצים שלא נגעתם בהם ומייצר diff ענק ולא רלוונטי.
- secrets או מידע רגיש - מפתחות API, טוקנים, סיסמאות שנשארו בקוד לבדיקה. הagent לא תמיד מזהה את זה כבעיה כי מבחינתו זה "רק ערך במשתנה".
> Scan the full diff and tell me if there's any string that looks
like an API key, token, password, or other secret.
פתרון conflicts עם הagent - resolving conflicts¶
כשעולה conflict בעת מיזוג (merge) או ריבייס (rebase), אפשר לתת לagent לעזור - אבל צריך זהירות מיוחדת, כי conflict אומר ששני שינויים אמיתיים מתנגשים, ופתרון לא נכון עלול לאבד לוגיקה של אחד הצדדים בשקט.
> I have a conflict in src/services/orderService.ts after rebasing
onto main. Show me both sides of the conflict, explain what
each side is trying to do, and only then suggest a resolution.
< On the "ours" side (your branch) - added findByDateRange for CSV
export. On the "theirs" side (main) - changed the calculateTotal
signature to add a discountCode parameter. The two changes don't
logically conflict, they just touched the same area of the file.
I'll combine both: keep findByDateRange as is, and update the calls
to calculateTotal in this file so they match the new signature with
discountCode.
אחרי שהagent פותר, זה בדיוק המקום להריץ שוב את הבדיקות - conflict שנפתר "נכון" תחבירית עדיין יכול לשבור לוגיקה:
> After you resolve the conflict, run the entire test suite and show
me that everything still passes, including the calculateTotal tests.
אם ה-conflict מורכב - נוגע בלוגיקה עסקית עדינה, לא רק בקוד מכני - שקלו לפתור אותו בעצמכם עם הagent כעוזר שמסביר את שני הצדדים, במקום לתת לו לבחור פתרון לבד.
סקירת PR של אחרים - reviewing someone else's pull request¶
הagent לא שימושי רק ל-PR שלכם - הוא כלי טוב גם לסקירת קוד של חברי צוות, בתנאי שמבינים את הגבול שלו: הוא יכול לזהות בעיות טכניות ואי-עקביות, אבל הוא לא יודע את הcontext העסקי שרק בן אדם מכיר.
> Check out this PR: gh pr view 482 --json files,body
Go over the changes and flag for me: code that contradicts an
existing convention in the project, places missing a test, and
changes that look bigger than what the PR description implies.
הagent יכול לעבור על ה-diff המלא ולחפש דפוסים בעייתיים - קריאה ל-API בלי טיפול בשגיאות, שינוי בסכימת DB בלי מיגרציה נלווית, פונקציה חדשה שדומה מאוד לפונקציה קיימת (סימן לכפילות קוד). זה שימושי כשלב מקדים לפני שאתם, כבני אדם, משקיעים זמן בסקירה - אבל הוא לא תחליף לסקירה אנושית, בטח לא כשמדובר בלוגיקה עסקית עדינה או בהחלטת ארכיטקטורה. הagent לא ידע להגיד "זה נוגד את מה שסיכמנו בפגישת התכנון שבוע שעבר" - רק אתם יודעים את זה.
> Summarize for me in three points: what this PR does, the biggest
risk you see in it, and what you'd ask the developer before approving.
rebase מול merge, ועבודה מול branch משותף¶
כשכמה אנשים עובדים על אותו branch, או כשצריך לעדכן branch פיצ'ר מול main שהתקדם, יש שתי אסטרטגיות עיקריות - merge ו-rebase - וההבדל ביניהן משפיע על היסטוריית git שתישאר לתמיד. שווה לוודא שהagent פועל לפי הקונבנציה של הצוות שלכם, לא לפי ברירת מחדל כללית:
> Before you update my branch against main, check on GitHub
(or ask me) - does this team work with rebase or with merge
commits? Follow whatever is the convention, not whatever is convenient.
נקודה קריטית: rebase על branch שכבר שותף עם אנשים אחרים (נדחף ל-remote ואחרים עשויים למשוך ממנו) הוא מסוכן, כי הוא כותב מחדש היסטוריה שכבר קיימת אצל אחרים. אם יש ולו ספק אם מישהו אחר כבר משך את ה-branch, זו בדיוק הסיטואציה שבה שווה לעצור ולשאול, לא לתת לagent להחליט לבד:
> Could someone else have already pulled this branch?
If so, let's not rebase - we'll use merge so we don't
break their local history.
גדרות הגנה - guardrails¶
| כלל | למה |
|---|---|
| אף פעם לא עובדים ישירות על main | main חייב להישאר יציב; branch מייצר בידוד ומרחב לתקן טעויות |
| כל commit נסקר לפני שהוא נוצר | הודעת commit והתוכן שנכנס הם היסטוריה קבועה, לא טיוטה |
| אף push לא קורה בלי אישור מפורש | push הופך שינוי מקומי לגלוי לצוות (או ל-CI) |
| force push דורש הסכמה מודעת, ובוודאי לא ל-main/master | force push יכול למחוק היסטוריה של אחרים בשקט |
| לפני יצירת PR, מריצים בדיקות מקומית | PR עם בדיקות שנכשלות מבזבז זמן סקירה של אחרים |
| conflicts נפתרים עם הבנה של שני הצדדים, לא רק "תבחר גרסה" | פתרון עיוור עלול לאבד שינוי לוגי אמיתי של אחד הצדדים |
דוגמה מלאה: session שלם¶
1. > Create branch feature/orders-csv-export from main.
< [branch created]
2. > [work on the feature - see lecture 3.2]
3. > Show me git status and suggest what belongs to this commit.
< [mapped: 3 feature files belong, .env.local doesn't]
4. > Run git add only on what you suggested, and show me git diff --staged.
< [add done, diff shown for review]
5. > Scan the diff for secrets. Write a commit message following
the project's convention.
< [no secrets; commit message proposed]
6. > Approved. Commit, push, and create a PR with a test plan.
< [commit, push, PR created with a link]
כל שלב כאן כולל אישור מפורש שלכם לפני שהagent ממשיך לפעולה הבאה שנוגעת בהיסטוריית git - זה בדיוק ההבדל בין "נוח" ל"מסוכן".
סיכום¶
- עבודה עם git דרך agent היא נוחה מאוד, ולכן היא בדיוק המקום שבו קל לתת לפעולות בלתי הפיכות (commit, push) לקרות בלי סקירה - זה הסיכון המרכזי של ההרצאה.
- לפני staging, מבקשים מהagent למפות מפורשות אילו קבצים שייכים ל-commit, כדי לא לערבב שינויים לא קשורים.
- הודעות commit טובות מסבירות למה, לא רק מה, ונכתבות אחרי בדיקת
git logכדי לשמור על קונבנציית הפרויקט. - תמיד עובדים על branch ייעודי, לעולם לא ישירות על main - והagent יכול ליצור אותו, לדחוף, וליצור PR עם
ghכולל תיאור ו-test plan. - סוקרים
git diff --stagedבמלואו לפני commit, ומחפשים במפורש קבצים לא רלוונטיים ו-secrets שהוזרקו בטעות. - ב-conflicts, מבקשים מהagent להסביר את שני הצדדים לפני הצעת פתרון, ותמיד מריצים בדיקות אחרי פתרון conflict.
- גדרות ההגנה המרכזיות: אין עבודה על main, אין commit או push בלי אישור מפורש, ואין force push בלי הסכמה מודעת ובוודאי לא על ענפים משותפים.