דלגו לתוכן

ניקוי ההיסטוריה של הקומיטים

פורסם בתאריך 23 באפריל 2024

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

טעויות נפוצות של מפתחים עם קומיטים

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

  • git commit --amend
  • git rebase -i
  • git reset
  • git stash

ניקח את הפקודות הללו ונלמד כיצד להשתמש בהן כדי לנקות את הקומיטים שלכם.

תכנון העבודה שלכם

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

תוכנית פשוטה

בואו ניצור תוכנית למשימה פשוטה שהוטלה עלינו. התבקשנו ליצור Header לאתר. אותו ה - Header מכיל לוגו, ניווט ושורת חיפוש. נראה כמו משימה פשוטה, אבל נפצל אותה לבעיות קטנות יותר:

  1. יצירת הלוגו
  2. יצירת שורת החיפוש
  3. יצירת הניווט

ניצור Branch חדש למשימה, ומכיוון שהקומיטים שלנו צריכים לשקף את התוכנית, נדמיין שההיסטוריה שלנו תיראה כך:

commit diagram

בדיאגרמה זו אנו רואים שפתחנו Branch בשם feat/header ויש לנו 3 קומיטים, כל קומיט פותר בעיה מהתוכנית שלנו, אז הקומיט הראשון ב Branch יכיל את ההודעה:

Terminal window
git commit -m "feat: created the header logo"

הקומיט השני ב Branch יכיל את ההודעה:

Terminal window
git commit -m "feat: created the header search bar"

והקומיט השלישי ב Branch יכיל את ההודעה:

Terminal window
git commit -m "feat: created the header navigation"

מה קורה לתוכנית שלנו בפועל

מייק טייסון אמר פעם:

“Everyone has a plan until they get punched in the face.”

לכולם יש תוכנית עד שהם מקבלים מכה בפנים. והנה בפועל מה שקרה לתוכנית שלנו.

git bad example

אז בפועל התוכנית שלנו נראתה כך:

  1. יצירת הלוגו
  2. יצירת שורת החיפוש
  3. תיקוני CSS ללוגו
  4. יצירת הניווט
  5. תיקון שגיאות בשורת החיפוש
  6. תיקוני lint בניווט

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

למה היסטוריה נקיה חשובה

מדוע חשוב שההיסטוריה שלי ב - Git תהיה נקייה?

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

בואו נסתכל על כלים שונים ב - Git שיעזרו לנו לנקות את הקומיטים שלנו.

git commit --amend

הפקודה git commit --amend משמשת להוספת שינויים לקומיט האחרון. אתם יכולים להשתמש בה כאשר אתם עובדים על Branch שלכם ולפני שאתם משתפים את השינויים שלכם עם אחרים. הכלים שאנחנו עוברים עליהם משנים את היסטוריית הקומיטים ועל כן פקודות אלו כאשר תדחפו את הקוד שלכם יחייבו אותם לעשות Force Push. על כן אסור לנו לבצע את הפקודות ב Branchים שנחלקים על ידי מספר מפתחים. לדוגמא Branch כמו main או develop יחייבו אותנו לעשות Force Push ולכן אסור לנו להשתמש בהם היות וזה יקשה על המפתחים שחולקים איתנו את אותו ה Branch. אבל כאשר אתם עובדים על Branch שלכם, תוכלו להשתמש בה כדי לשנות את הקומיט האחרון, ותוכלו להרגיש חופשי לעשות Force Push על Branch שלכם כאשר אתם יודעים שהוא לא משותף.

בואו נבחן דוגמא, נניח שאתם עובדים על Branch בשם feat/header ויצרתם קומיט עם ההודעה feat: created the header logo, אחרי שיצרתם את הקומיט הפרוייקט מנהל יראה את העבודה שלכם ויאמר לכם לעשות כמה שינויי CSS. במקום ליצור קומיט חדש, מאחר וזה עדיין אותו קבוצת שינויים לוגייתית, תוכלו לעשות את השינויים ב CSS ואז לעשות:

Terminal window
git add -A
git commit --amend --no-edit

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

git reset

git reset היא פקודה חזקה שיכולה לשמש לביטול קומיטים. אם תשתמשו בה בלי הפרמטר --hard היא תשמור את השינויים בקובץ העבודה, ותסיר קומיטים, וכך תוכלו לשנות את הקומיטים. בואו נראה דוגמא, נניח שאתם עובדים על Branch בשם feat/header ויצרתם קומיט עם ההודעה feat: created the header logo and the search bar, אתם מסתכלים על כמות השינויים ואתם מבחינים שהקומיט שלכם כולל המון שינויים (זו טעות נפוצה ליצור קומיט אחד שמכיל המון שינויים), ואתם רוצים לפצל את הקומיט לשני קומיטים. קומיט אחד שיכיל את השינויים שקשורים ללוגו, וקומיט שני שיכיל את השינויים שקשורים לשורת החיפוש.

ניתן לעשות:

Terminal window
git reset HEAD~1

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

git rebase -i

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

עריכת קומיטים

נניח שאתם עובדים על Branch בשם feat/header ויצרתם קומיט עם ההודעה feat: created the header logo, אחרי קומיט זה יצרתם עוד 10 קומיטים בנושא אחר, ואז מנהל הפרוייקט אומר לכם שישנם שינויי CSS שצריך לבצע ללוגו. ניתן ליצור את השינויים אך יתכן והם יהיו מתאימים יותר בשייכות הלוגית לקומיט שיצר את הלוגו. במקרה זה אחרי שנבצע את התיקונים הנדרשים נוכל לעשות:

Terminal window
git stash

לשמירת השינויים בזיכרון. ואז נוכל לעשות:

Terminal window
git rebase -i HEAD~11

למצוא את הקומיט שאנו רוצים לשנות ולשנות את המילה pick ל edit, זה ישים אותנו בקומיט שאנו רוצים לשנות. אז נוכל להוציא את השינויים מהזיכרון עם:

Terminal window
git stash pop

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

Terminal window
git add -A
git commit --amend --no-edit

שינינו את הקומיט ואז נוכל להמשיך את ה rebase עם הפקודה:

Terminal window
git rebase --continue

כאשר אנחנו עורכים קומיט אנחנו בשכיחות גבוהה גם נשתמש בפקודות git reset ו git stash ו git commit --amend כדי לשנות את הקומיט שאנחנו עורכים.

איחוד קומיטים

נאמר שאנחנו עובדים על Branch בשם feat/header ויצרנו 5 קומיטים שקשורים לשורת החיפוש. להיסטוריה נקיה יותר נרצה לאחד את הקומיטים האלו לקומיט אחד, אופציה אחת היא להשתמש בפקודה git reset שלמדנו, אבל במידה האותם קומיטים הם לא הקומיטים האחרונים ב Branch נרצה להשתמש בפקודה git rebase -i. נשנה את המילה pick ל squash על כל הקומיטים שאנחנו רוצים לאחד, ואז נשמור ונסגור את העורך.

סיכום

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