ניקוי ההיסטוריה של הקומיטים
פורסם בתאריך 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 מכיל לוגו, ניווט ושורת חיפוש. נראה כמו משימה פשוטה, אבל נפצל אותה לבעיות קטנות יותר:
- יצירת הלוגו
- יצירת שורת החיפוש
- יצירת הניווט
ניצור Branch חדש למשימה, ומכיוון שהקומיטים שלנו צריכים לשקף את התוכנית, נדמיין שההיסטוריה שלנו תיראה כך:
בדיאגרמה זו אנו רואים שפתחנו Branch בשם feat/header
ויש לנו 3 קומיטים, כל קומיט פותר בעיה מהתוכנית שלנו, אז הקומיט הראשון ב Branch יכיל את ההודעה:
הקומיט השני ב Branch יכיל את ההודעה:
והקומיט השלישי ב Branch יכיל את ההודעה:
מה קורה לתוכנית שלנו בפועל
מייק טייסון אמר פעם:
“Everyone has a plan until they get punched in the face.”
לכולם יש תוכנית עד שהם מקבלים מכה בפנים. והנה בפועל מה שקרה לתוכנית שלנו.
אז בפועל התוכנית שלנו נראתה כך:
- יצירת הלוגו
- יצירת שורת החיפוש
- תיקוני CSS ללוגו
- יצירת הניווט
- תיקון שגיאות בשורת החיפוש
- תיקוני 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 ואז לעשות:
הדבר יוסיף את השינויים ב CSS לקומיט האחרון, וכך תהיה לכם רק קומיט אחד שיצר את הלוגו.
אתם יכולים גם לשנות את ההודעה של הקומיט על ידי הוספת הפרמטר --no-edit
.
git reset
git reset
היא פקודה חזקה שיכולה לשמש לביטול קומיטים.
אם תשתמשו בה בלי הפרמטר --hard
היא תשמור את השינויים בקובץ העבודה, ותסיר קומיטים, וכך תוכלו לשנות את הקומיטים.
בואו נראה דוגמא, נניח שאתם עובדים על Branch בשם feat/header
ויצרתם קומיט עם ההודעה feat: created the header logo and the search bar
,
אתם מסתכלים על כמות השינויים ואתם מבחינים שהקומיט שלכם כולל המון שינויים (זו טעות נפוצה ליצור קומיט אחד שמכיל המון שינויים), ואתם רוצים לפצל את הקומיט לשני קומיטים.
קומיט אחד שיכיל את השינויים שקשורים ללוגו, וקומיט שני שיכיל את השינויים שקשורים לשורת החיפוש.
ניתן לעשות:
הפקודה תסיר את הקומיט האחרון, אבל השינויים יישארו בקובץ העבודה.
כעת ניתן להוסיף את השינויים הקשורים ללוגו וליצור קומיט חדש, ואז להוסיף את השינויים הקשורים לשורת החיפוש וליצור קומיט נוסף.
קל להשתמש בפקודה כאשר רוצים לשנות מבנה של קומיט למבנה אחר , יותר קשה להשתמש בפקודה כאשר השינוי הוא יותר רחוק בהיסטוריה, ואז ניתן להשתמש בפקודה git rebase -i
.
git rebase -i
הפקודה git rebase -i
היא פקודה חזקה שמאפשרת לכם לשנות את ההיסטוריה של הקומיטים שלכם.
לעניות דעתי זו הפקודה החשובה ביותר לסידור היסטוריה נקייה שמתארת בדיוק את התפתחות התוכנה.
הפקודה מאפשרת לכם לפצל קומיטים, לערוך קומיטים, לשנות את סדר הקומיטים ועוד.
בואו נבחן דוגמאות שבהן אנו משתמשים בפקודה git rebase -i
לעריכת קומיטים, ולאיחוד קומיטים.
עריכת קומיטים
נניח שאתם עובדים על Branch בשם feat/header
ויצרתם קומיט עם ההודעה feat: created the header logo
,
אחרי קומיט זה יצרתם עוד 10 קומיטים בנושא אחר, ואז מנהל הפרוייקט אומר לכם שישנם שינויי CSS שצריך לבצע ללוגו.
ניתן ליצור את השינויים אך יתכן והם יהיו מתאימים יותר בשייכות הלוגית לקומיט שיצר את הלוגו.
במקרה זה אחרי שנבצע את התיקונים הנדרשים נוכל לעשות:
לשמירת השינויים בזיכרון. ואז נוכל לעשות:
למצוא את הקומיט שאנו רוצים לשנות ולשנות את המילה pick
ל edit
, זה ישים אותנו בקומיט שאנו רוצים לשנות.
אז נוכל להוציא את השינויים מהזיכרון עם:
נוסיף את השינויים לקומיט שאנחנו עורכים על ידי
שינינו את הקומיט ואז נוכל להמשיך את ה rebase עם הפקודה:
כאשר אנחנו עורכים קומיט אנחנו בשכיחות גבוהה גם נשתמש בפקודות git reset
ו git stash
ו git commit --amend
כדי לשנות את הקומיט שאנחנו עורכים.
איחוד קומיטים
נאמר שאנחנו עובדים על Branch בשם feat/header
ויצרנו 5 קומיטים שקשורים לשורת החיפוש.
להיסטוריה נקיה יותר נרצה לאחד את הקומיטים האלו לקומיט אחד, אופציה אחת היא להשתמש בפקודה git reset
שלמדנו, אבל במידה האותם קומיטים הם לא הקומיטים האחרונים ב Branch נרצה להשתמש בפקודה git rebase -i
.
נשנה את המילה pick
ל squash
על כל הקומיטים שאנחנו רוצים לאחד, ואז נשמור ונסגור את העורך.
סיכום
הנקודה המרכזית של שיעור זה היא לא שתזכרו את כל הפקודות האלו, הנקודה היא שתזכרו לשמור על היסטוריה נקייה וקריאה. ניתן לאחד, לערוך, לוסיף שינויים לקומיטים שלכם וניתן לשנות את ההיסטוריה של הקוד שלכם כך שתיהיה קריאה ונקייה לפני שאנחנו משתפים אותה עם הצוות. אתם תקצרו את הפירות לעבודה מסודרת זו כאשר תרצו לדבג את הקוד, או לבטל קומיט, או לבחון את האבולוציה של התוכנה שלכם. ברגע שתשימו דגש על הפילוסופיה של לשמור על היסטורית קומיטים נקיה וקריאה, תשתמשו בכלים ש git מספק לכם כדי לשמור על היסטוריה נקייה וקריאה, וכאשר תתאמנו על אותם כלים תהיו יותר טובים בהם ותשלטו על כל הפקודות שלמדנו בשיעור זה.