• בלוג
  • איך אני עובד עם git

איך אני עובד עם git

25/01/2026

גיט הוא כלי ניהול הגרסאות המרכזי בתעשייה והוא סופר גמיש. בגלל הגמישות אפשר להתאים אותו לכל ארגון ולכל שיטת עבודה שזה דבר טוב, אבל תוצאת לוואי של יכולת זו היא שקל מאוד להתבלבל ולבחור שיטת עבודה שלא מתאימה לכם. בפוסט היום אשתף שני עקרונות מנחים שעוזרים לי להחליט איך לעבוד עם גיט בפרויקט ואראה איך ליישם אותם במספר סיטואציות.

1. עקרונות מנחים

שני העקרונות הבאים משותפים לכל פרויקט קוד שעובד עם גיט:

  1. מרגע ששלחתי קומיטים למאגר מרוחק קשה להוציא אותם
  2. גיט הוא מאגר מידע

קומיט בגיט הוא אבן ואבן שנזרקת לתוך הבאר קשה מאוד להוציא. המשחק הראשון שלנו הוא לזרוק כמה שפחות אבנים ובמיוחד להיזהר מלזרוק את האבנים הלא נכונות. קומיט מכיל את מצב הפרויקט ברגע נתון. מרגע שדוחפים קומיט עם מפתח גישה לאחד הקבצים המפתח הזה יישאר בריפו לעד, גם אם בקומיט עתידי נמחק את הקובץ. מרגע שמישהו לקח קומיט שלי וממשיך לבנות עליו קוד יהיה קשה מאוד לבטל את הקומיט כי אותו קוד שפותח על בסיסו יהפוך ללא רלוונטי.

העקרון השני אומר שגיט הוא מאגר מידע שאמור לענות לי על שאלות לגבי הקוד. כשאני רואה חלק בקוד שאני לא מבין או לא מבין את ההקשר או מאיפה הוא הגיע אני אוכל להכנס לגיט וללמוד משם את כל סיפור הרקע. כשמאגר המידע בנוי טוב אנשים משתמשים בו, לומדים על הקוד ויכולים לקבל החלטות טובות יותר. מאגר מידע שבנוי רע הוא חסר ערך, יוצר בלבול ומכריח אותנו לתקשר באמצעים אחרים פחות יעילים.

2. מבנה קומיט

קומיט בגיט הוא עותק מלא של הפרויקט בנקודה מסוימת בזמן. בהסתכלות על גיט כמאגר מידע קומיט מייצג פעולה או שינוי מצב של הפרויקט והודעת הקומיט צריכה להסביר את השינוי הזה.

גיט כמאגר מידע צריך להציג לי היסטוריה של השינויים בפרויקט ולספר סיפור - מה קרה, מי עשה, למה עשו, במה לא טיפלו, במה טיפלו אחר כך, מה חשבו שיקרה, מה באמת קרה. ניקח לדוגמה את הריפו של opencode ונראה כמה קומיטים אחרונים משם:

https://github.com/anomalyco/opencode/commits/dev/

קומיט 0cc206a:

update: border radius on popover card

שינוי הקוד משנה את ערך border-radius בקובץ שנקרא session-review.css. מההודעה אני לומד שהערך הזה משמש להצגת כרטיס popover שזה טוב. ההודעה לא מסבירה למה החליטו לשנות את הערך, האם זה חלק משינוי עיצוב כללי יותר או משהו נקודתי שעלה מהערה של משתמש או ממקום אחר. הקומיט מספר לי מה עשו אבל לא למה עשו.

קומיט c9215e8:

fix(ui): style review tab comment button to match file tab - blue background, white comment icon

הפעם ההודעה מספרת סיפור יותר מלא. יש פה תיקון של ממשק לא עקבי, כפתור comment בטאב ה review נראה קודם שונה מכפתור commment בטאב ה file. גם בלי להכיר את הפרויקט ואת הטאבים השונים אני מבין מאיפה זה בא ולמה החליטו לבצע את השינוי. גם השינויים עצמם ב CSS ובקובץ ה tsx תואמים את ההערה.

בשני הקומיטים השינויים עצמם בקוד מאוד מדויקים, מדובר על 2-3 שורות שהשתנו.

לעומתם קומיט c4d223e קצת יותר מבלבל. הודעת הקומיט היא:

perf(app): faster workspace creation

ותוכן הקומיט כולל 329 שורות שנוספו ו 44 שורות שנמחקו. כן אני יכול לבקש מ AI שיתמצת לי את השינוי לפי השינויים בקוד אבל אני לא יכול להיות בטוח שאקבל תשובה מדויקת. הייתי שמח לקבל הודעה ארוכה יותר שמסבירה מה בדיוק נעשה כדי לשפר את מהירות יצירת ה workspace. מה היתה הבעיה הקודמת ביצירת ה workspace, איך פתרתם אותה והאם יש מצבים בהם לא טיפלתם או משהו שהשארתם לעתיד.

דבר נוסף שאני לומד מקריאת מסך רשימת הקומיטים של opencode הוא שפשוט יש שם המון קומיטים. באותו רצף עבודה ספרתי כמעט 30 קומיטים, כולל תיקוני UI שקשורים לאותו נושא ומפוזרים על פני 6-7 קומיטים שונים ולפעמים דורסים אחד את השני. הבעיה בריבוי קומיטים מסוג זה היא שגם ההודעות מפוצלות בין המון קומיטים וקשה להבין איזה הודעה שייכת לאיזה שינוי קוד.

נשווה את זה לעץ הקומיטים של קודקס שהוא כבר הרבה יותר מסודר:

https://github.com/openai/codex/commits/main/

קומיט 713ae22 מגיע עם ההודעה הבאה:

Another round of improvements for config error messages (#9746)
In a [recent PR](#9182), I made some
improvements to config error messages so errors didn't leave app server
clients in a dead state. This is a follow-on PR to make these error
messages more readable and actionable for both TUI and GUI users. For
example, see #9668 where the user was understandably confused about the
source of the problem and how to fix it.

The improved error message:
1. Clearly identifies the config file where the error was found (which
is more important now that we support layered configs)
2. Provides a line and column number of the error
3. Displays the line where the error occurred and underlines it

For example, if my `config.toml` includes the following:
```toml
[features]
collaboration_modes = "true"

Here's the current CLI error message: Error loading config.toml: invalid type: string "true", expected a boolean in `features`

And here's the improved message: Error loading config.toml: /Users/etraut/.codex/config.toml:43:23: invalid type: string "true", expected a boolean | 43 | collaboration_modes = "true" | ^^^^^^

The bulk of the new logic is contained within a new module config_loader/diagnostics.rs that is responsible for calculating the text range for a given toml path (which is more involved than I would have expected).

In addition, this PR adds the file name and text range to the ConfigWarningNotification app server struct. This allows GUI clients to present the user with a better error message and an optional link to open the errant config file. This was a suggestion from @.bolinfest when he reviewed my previous PR. ```

ההודעה כוללת את הסיפור המלא של השינוי: מה קרה, למה זה קרה, קישור לבעיה שהיתה למשתמש אמיתי עם המצב הקודם, שיקולים טכניים בפיתוח ושינויי תשתית שהיה צריך להכניס בשביל המנגנון. מדובר על קומיט שכולל תוספת של 738 שורות ומחיקה של 23, כלומר יש פה diff מאוד משמעותי וסיפור משמעותי שמלווה אותו. הודעת הקומיט מעולה אבל יכול להיות שהיה משתלם לפצל אותה לכמה קומיטים.

קומיט eca365c הוא כבר יותר קצר ומשנה בסך הכל סימן אחד בקוד - גרסה של ספריה מ 4 ל-5. בואו נראה את הודעת הקומיט:

 Upgrade GitHub Actions for Node 24 compatibility (#9722)
 ## Summary

 Upgrade GitHub Actions to their latest versions to ensure compatibility
 with Node 24, as Node 20 will reach end-of-life in April 2026.

 ## Changes

 | Action | Old Version(s) | New Version | Release | Files |
 |--------|---------------|-------------|---------|-------|
 | `actions/cache` |
 [`v4`](https://github.com/actions/cache/releases/tag/v4) |
 [`v5`](https://github.com/actions/cache/releases/tag/v5) |
 [Release](https://github.com/actions/cache/releases/tag/v5) | bazel.yml
 |

 ## Context

 Per [GitHub's
 announcement](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/),
 Node 20 is being deprecated and runners will begin using Node 24 by
 default starting March 4th, 2026.

 ### Why this matters

 - **Node 20 EOL**: April 2026
 - **Node 24 default**: March 4th, 2026
 - **Action**: Update to latest action versions that support Node 24

 ### Security Note

 Actions that were previously pinned to commit SHAs remain pinned to SHAs
 (updated to the latest release SHA) to maintain the security benefits of
 immutable references.

 ### Testing

 These changes only affect CI/CD workflow configurations and should not
 impact application functionality. The workflows should be tested by
 running them on a branch before merging.

 Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>

ההודעה כוללת הסבר מלא על השינוי, למה היה צריך אותו ואיזה בדיקות נעשו או היה צריך לעשות. מי שיפעיל בעתיד git blame על השורה הזאת יוכל לקבל תמונת מצב מלאה של הבדלי הגרסאות וגם הבנה טובה של איך לשדרג גרסה בעתיד.

3. הכי קל - עבודה מבוססת טראנק

אחרי שהבנו מה המטרה יהיה יותר קל לראות שיטות עבודה ואיך הן מייצרות יומן פעילות שיהיה לנו כיף לקרוא בעתיד.

בגיט כל קומיט מתבסס על קומיט קודם שנקרא parent commit וההיסטוריה היא שרשרת של כל הקומיטים. כל קומיט כולל את קוד הפרויקט באותה נקודה של הקומיט והודעת הסבר.

כשהסתכלנו על יומני קומיטים של opencode ו codex ראינו שהיומן מוצג בתור רשימה של קומיטים אחד אחרי השני, כל קומיט בא עם הודעה שמסבירה אותו והקוד וממש קראנו את הסיפור של הקוד דרך הקומיטים. אם בזמן פיתוח הקוד אנחנו יודעים לעבוד מסודר ומכירים את הסיפור של כל פיצ'ר נוכל לכתוב את הקומיטים כמו שנרצה לקרוא אותם:

  1. נכתוב מימוש מלא של פיצ'ר או תיקון.
  2. נעשה קומיט עם הודעת שגיאה אינפורמטיבית שמספרת את כל הסיפור.
  3. נמשיך לפיצ'ר או התיקון הבא.

אחרי הקומיט נוכל לעשות push כדי לדחוף אותו לשרת וכך אנשים אחרים שיקבלו את הקומיט יוכלו להתבסס עליו בכתיבת קוד חדש.

במציאות מאוד קשה לדעת בזמן אמת שאנחנו כותבים את המימוש הנכון. אנחנו אוהבים להשתמש בגיט גם בתור נקודת שמירה ולכן בקידוד אמיתי אני אכתוב קצת קוד, אעשה קומיט כשדברים נראים הגיוניים, אמשיך לכתוב קוד ולעשות קומיטים, מדי פעם אבין שאני לא בכיוון ואז אחזור אחורה עם git reset ואמשיך לחקור כיוון נוסף עד שאגיע לפתרון טוב שעובד. בנקודה הזאת אני אפעיל rebase ואסדר את הקומיטים מחדש לפי סדר הגיוני, אם יש כמה קומיטים על אותם קטעי קוד אני אשאיר רק את האחרון, אתקן הודעות קומיט לא מספיק טובות ואצור את יומן העבודה שיהיה כיף לקרוא בעתיד. רק אחרי שיש לי את הפיצ'ר עם יומן קומיטים ערוך אני אפעיל push כדי לשתף את העבודה עם אחרים.

4. כשצריך לשתף פותחים ענף

בעבודה בצוות לא תמיד אפשר להתקדם לבד: ייתכן ויש מפתחי צד שרת ומפתחי צד לקוח ורק יחד אפשר לראות אם הפרויקט עובד, לפעמים צריך להעלות את המערכת לשרת באינטרנט כדי לבדוק אינטגרציה עם מערכות אחרות, לפעמים אנחנו עובדים 2-3 אנשים על אותו פיצ'ר וכל שינוי שלי יכול להתנגש עם שינויים שלהם.

כדי לשתף את העבודה שלי עם מערכות או אנשים אחרים אני חייב לדחוף את הקומיטים לשרת מרוחק. אם אנחנו צוות קטן וכולם צריכים לראות את השינויים של כולם נוכל להמשיך לעבוד על הריפו הראשי אבל בדרך כלל רק חלק מהאנשים שעובדים על פרויקט יעבוד בשיתוף על פיצ'ר מסוים ולכן נפתח ענף רק עבור אותו פיצ'ר ולאותם אנשים שצריכים לעבוד עליו בשיתוף פעולה.

בענף הזה נעבוד באותה שיטה שכבר סיכמנו - כל אחד מתקדם על המכונה שלו עם קומיטים וכשצריך לשתף דוחפים את הקומיטים לענף, אבל פה יש טוויסט: אם אני צריך לחזור אחורה מקומיטים שכבר נדחפו עליי לעדכן את כל האנשים שעובדים על אותו ענף כדי שהם לא יבססו עבודה שלהם על קומיטים ישנים. בשביל זה עלינו לעצור את הפעילות, כולם ידחפו את העבודה שלהם לריפו, אחד יריץ ריבייס כדי לערוך או למחוק קומיטים ישנים ואחרי זה כולם יעשו pull --rebase כדי לקבל את הגרסה החדשה של הענף. בגלל ששלב זה דורש סיכנרון ננסה לצמצם בעריכת קומיטים ונערוך פעם אחת בצורה מסודרת כשהפיצ'ר גמור לפני המיזוג לענף הראשי.

5. שמירת מספר גרסאות עם tags

אחרי שהמערכת מגיעה למצב יציב אנחנו רוצים לסמן "גרסה". גרסה יכולה להיות משהו שעולה לשרת, ספריה שמתפרסמת ללקוחות, אפליקציה שעולה לחנות אפליקציות, בקיצור משהו שאנחנו משתפים ויכולים לדבר עליו לפי מזהה.

בגיט אני מסמן גרסה עם tag לדוגמה בקודקס הקומיט 28c32c6 מסומן עם התג rust-v0.79.0. כשאני צריך לחזור לגרסה מסוימת למשל כדי להוציא תיקון דחוף אני תמיד יכול לחזור ל tag, לייצר את התיקון בתור קומיט חדש ולייצר tag חדש עם מספר גרסה קטן גבוה יותר. בסיטואציה כזאת אפשר לייצר ענף זמני עבור התיקון ולמחוק אותו אחרי שמייצרים את גרסת התיקון.

בניגוד לענף (branch) המשמש לשיתוף פעולה ותקשורת בזמן העבודה, התג הוא סימון לעתיד. הוא יעזור לי לחזור לנקודה בקוד, להשוות מולה או להמשיך פיתוח ממנה.

גיט הוא קודם כל מאגר מידע. הוא מספר את הסיפור של הקוד שלכם, איך הפרויקט נבנה, מה הסיבה לכל שורת קוד במערכת ומה חשוב לדעת כשמגיעים לשנות דברים בעתיד. הצעד הראשון בשיפור העבודה עם גיט הוא לקרוא ממנו יותר - הסתכלו בהיסטוריית הגיט של הפרויקט שלכם, קראו את הודעות הקומיט הישנות, נסו להבין מתוך הודעות הקומיט מה קרה שם. ככל שתעשו את זה לעתים קרובות אתם תלמדו מה הדברים שחשובים לכם ביומן הפעילות שמלווה את הקוד שלכם.