מדוע ללא Conventional Commits היסטוריית השינויים אינה קריאה
כל עוד אין הסכמה על הפורמט, כל קומיט נכתב איך שיוצא: «תיקון», «תיקנתי», «עוד עריכות», «השלמה למשימה». פורמלית היסטוריית השינויים קיימת, אך למעשה אי אפשר להבין ממנה מה שינו ולשם מה. כעבור חודש גם מחבר השורה לא ישחזר זאת — יישארו רק התאריך ושם המשפחה.
בהמשך נשבר כל מה שנשען על ההיסטוריה הזו. רשימת השינויים לקראת מהדורה נאספת ידנית, תוך קריאה של עשרות הודעות, והיא בכל זאת סוטה מהמציאות: חלק מהתיקונים לא נכללים בה, ושורות מסוימות מתארות עבודות שלא נכנסו למהדורה. ניתוח מהדורה הופך לארכאולוגיה לפי תאריכים וענפים.
המחיר מורגש במיוחד בעת ניתוח תקלה. צריך למצוא את השינוי שהכניס את הפגם, אך חיפוש לפי תיאור אינו עובד: בהודעות אין לא תת-המערכת שנפגעה ולא אופי התיקון. יש לעבור על טווח קומיטים, לבדוק דיפים ידנית ולתשאל אנשים — אלו שעות במקום דקות, והכול על רקע מהדורה בוערת.
Conventional Commits מגדיר להודעה מבנה: סוג השינוי, תחום, תיאור קצר וסימן מפורש לשינוי לא תואם. היסטוריה כזו נקראת על ידי אדם ומנותחת על ידי כלים: ממנה נאסף CHANGELOG אוטומטית, ולפי סוג הקומיט רואים אם המהדורה זקוקה למיגרציה. קריאות ההיסטוריה מפסיקה להיות תלויה במשמעת של מפתחים בודדים.
תקן ההודעות אינו עוסק ביופי הלוגים, אלא בכך שהמהדורה וניתוח התקלה יישענו על עובדות, ולא על הזיכרון של המשתתפים. להלן נבחן כיצד זה נבנה בפועל.
מה נותן פורמט אחיד להודעות על תיקונים
הודעה על תיקון מפסיקה להיות טקסט חופשי והופכת לנתונים: סוג השינוי, התחום שנפגע, התמצית, מספר המשימה. תקן Conventional Commits מגדיר את הסימון הזה, וכלי הניתוח אוסף בעצמו את יומן השינויים — גרסה, רשימת תיקונים, שינויים שוברים המסומנים בנפרד.
איסוף אוטומטי מסיר את השלב הידני לפני המהדורה, שלרוב אכל יום-יומיים, ואיתו — סעיפים נשכחים ופערים בין תיאור המהדורה לתוכנה.
פורמט אחיד להודעות מצמצם את חלק הפעולות הידניות בהכנת הגרסה לכמה אישורים: המהנדס סוקר את הטיוטה שנאספה ומפעיל את המהדורה. בדיקת הפורמט בצד השרת מסננת הודעות בלתי קריאות לפני שהן מגיעות לענף הראשי, ולכן אין צורך לנתח ולתקן את היומן בדיעבד, כשההקשר כבר אבד.
משתנה גם סוג הכשלים שמגיעים למשתמש. כשסוג התיקון נראה מההיסטוריה, שינוי שובר מסומן במפורש ואינו נכנס למהדורה רגילה בשל חוסר תשומת לב. החזרה לאחור נעשית מדויקת: מהיומן רואים איזו גרסה הביאה את הרגרסיה, ומסירים אותה בלי לעבור על כל טווח השינויים בין הבניות.
בקרת האיכות של התיקונים נשענת על אותו סימון: הבודק רואה את מטרת השינוי לפני קריאת הקוד, משימות קשורות נאספות לפי מספר באופן אוטומטי, וחלקן של התיקונים הדורשים הבהרות בבדיקה יורד הודות לתיאור מובן. חזרה לענף ישן מפסיקה להיות חפירה — ההיסטוריה נקראת באופן ליניארי ולפי המשמעות של כל שינוי.
Conventional Commits או פורמט חופשי: מה לבחור
הבחירה כאן אינה בין «תקן» לכאוס, אלא בין רמות של אכיפה. פורמט חופשי נשען על הסכמה שבעל פה, וקונבנציונלי — על כלל שבדוק מכונה: לינטר הודעות על hook לפני קומיט ואותה בדיקה בצינור הבנייה.
ככל שהדחייה מתרחשת מוקדם יותר, כך התיקון זול יותר — הודעה שנדחתה עולה דקה, וניתוח היסטוריה במהדורה — שעות.
קריטריון הישימות אינו גודל הצוות, אלא מי ובאיזו תדירות אוסף את ה-CHANGELOG וממספר גרסאות. כל עוד אדם אחד עושה זאת ידנית, די בהסכמה. ברגע שהמהדורות נעשות סדירות, ומאגרי הקוד מרובים מאחד, יש לעגן את הכלל טכנית.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| פורמט חופשי, הסכמה בעל פה | צוות אחד, מאגר קוד אחד, מהדורות נדירות | ההיסטוריה אינה קריאה, גרסאות ויומן השינויים נאספים ידנית, לפי הלוג אי אפשר לשחזר מה נכלל במהדורה |
| סוג בתחילית ללא בדיקות | 5–15 איש, מהדורה פעם בשבוע-שבועיים | ההסכמה מדרדרת: חלק מהקומיטים ללא סוג או עם סוג שגוי |
| Conventional Commits + לינטר על hook ובבנייה | כמה צוותים ומאגרי קוד, מחזור מהדורות סדיר | יש לתחזק רשימת סוגים, לעקוב אחר הגנת הענף והרשאות המיזוג |
| Conventional Commits + יצירה אוטומטית של יומן וגרסאות | מהדורות תיקון תכופות, מחזור מוצרי | שגיאה בסוג מגיעה ליומן, יש צורך בהרשאות לתגים ואיסור עריכות בענף מוגן |
האפשרויות אינן סותרות זו את זו: למהדורה אוטומטית מגיעים בדרך כלל בשלבים — תחילה בדיקת סוגים, אחר כך יצירת היומן והמספור. המגבלות של כל שלב נראות מראש, וזה בדיוק קובע היכן סביר לעצור והיכן הכלל כבר מפריע לעבודה.
שלבי הטמעת התקן ואיסוף אוטומטי של היומן
אין מטמיעים תקן בקומיט אחד: אם מפעילים מיד בדיקות נוקשות, הצוות יתחיל לעקוף אותן דרך --no-verify, והכלל יהפוך לפורמליות כבר בשבוע השני. לכן הולכים בגל — מניתוח ההיסטוריה המצטברת לאוטומציה שמחזיקה את הפורמט בעצמה.
- ביקורת היסטוריה והרגלים. מנתחים את הלוג מכמה חודשים: חלק ההודעות שמהן אי אפשר לאסוף יומן, אילו תחיליות באמת בשימוש, היכן בקומיט אחד מעורבבים שינויים הטרוגניים. הפלט — מפת סוגים והבנה של היקף הנרמול החד-פעמי.
- תיאום מילון. קובעים סט סגור של סוגים (
feat,fix,chore,docs,refactor,perf,test,build) וגבולות שימוש לכל אחד. הרשימה עוברת לקובץ מנוהל גרסאות לצד הקוד, ולא לוויקי. - הגדרת בדיקות מקומיות. מיירט בצד המפתח בודק את ההודעה לפני השליחה ומראה מיד מה חסר — סוג, תחום, תיאור. השגיאה נראית תוך שניות, ולא בשרת הבנייה.
- בקרה בצד מאגר הקוד. אותו כלל חוזר בבנייה של הענף הראשי, כדי שלא ניתן יהיה לעקוף את הפורמט בהגדרות מקומיות. שינויים שוברים מסומנים בסמן נפרד ובסעיף נפרד ביומן.
- יצירת יומן. המחולל מנתח את ההודעות, מקבץ רשומות לפי סוגים ואוסף מהדורה. התבנית קובעת את סדר הסעיפים, קישורים למשימות ומחברים — הגרסה נאספת בלי עריכה ידנית.
- הטמעה במחזור המהדורה. המהדורה, התג וקובץ היומן מופיעים כחפצים של תהליך הבנייה, ולא כמשימה למהנדס מהדורות.
- העברה לצוות. תזכיר על מסך אחד, תבנית הודעה, ניתוח שגיאות נפוצות ונקודת ביקורת כעבור חודש: בודקים את חלק ההודעות שעברו בדיקה ומתקנים כללים שהתבררו כמיותרים.
כללי בדיקה, תבניות ותקנוני הוצאת גרסאות
תקנון הבדיקה נשען לא על הסכמות בעל פה, אלא על חפצים שאליהם הצוות חוזר במצב שנוי במחלוקת. להלן מה נשאר אצל הלקוח במאגר הקוד לאחר סיום העבודה.
- תיעוד התהליך: מחזור החיים של ההודעה מהענף המקומי ועד התג, דוגמאות לקומיטים תקינים ונדחים, ניתוח שגיאות נפוצות.
- תבניות הודעות: הכנה להזנת קומיט ורמז בטרמינל, שמציע סוג, תחום שינויים ותיאור קצר.
- הגדרות בדיקות: כללי הלינטר ו-hook בשלב הכנת הקומיט — פורמט לא מתאים לא נכנס להיסטוריית הענף.
- תקנון הוצאת גרסאות: סדר הפעולות לפני המהדורה, סכימת המספור, כללי הרכבת CHANGELOG ונקודות שבהן נדרשת עריכה ידנית.
- מדיניות גישה: תפקידים במאגר הקוד, מי ממזג שינויים לענף הראשי ומי רשאי לשים תגים.
- הוראות לצוות: תזכירים למצבים נפוצים — עריכת קומיט שנשלח, החזרת מהדורה, שינוי תבנית.
- תרשימי קשרים: כיצד בדיקות, אוטומציה ושלבי המהדורה מתייחסים זה לזה, כדי שמהנדס חדש יבין בלי ליווי.
כל מסמך נמצא לצד הקוד ומתעדכן יחד איתו — הכללים אינם סוטים ממצבו בפועל של מאגר הקוד.
מקרה בוחן: פורמט אחיד ואיסוף אוטומטי של יומן השינויים
לפני: יומן השינויים נאסף ידנית
צוות של שמונה אנשים ניהל את יומן השינויים ביד: לפני המהדורה, ראש הצוות עבר על היסטוריית הקומיטים, שחזר את משמעות התיקונים מהודעות כמו «תיקונים», «תיקנתי» ו«עוד קצת» ופיזר אותן בין הסעיפים.
הכנת תיאור המהדורה ארכה עד שני ימי עבודה, וככל שהיו יותר שינויים, כך גדל הסיכוי שחלקם יאבד או ייכנס לסעיף הלא נכון.
מה שינו
הנהיגו את Conventional Commits כפורמט חובה להודעה: סוג, תחום ותיאור קצר של השינוי. ההודעה נבדקת ב-hook מקומי לפני יצירת הקומיט ושוב בצד השרת בעת קליטת הענף, ולכן הפרת פורמט פשוט אינה עוברת הלאה — מי שצריך לתקן הוא מחבר התיקון, ולא סוקר המהדורה.
מהסוגים והתחומים היומן נאסף אוטומטית: הסעיפים «חדש», «תיקונים» ו«שינויים פנימיים» נוצרים בבנייה, ומספר הגרסה עולה לפי כללי גרסאות סמנטיות בלי החלטה ידנית.
אחרי: מדדים
הכנת המהדורה הצטמצמה משני ימים ל-40 דקות — נותרת הגהה של הניסוחים, ולא שחזור ההיסטוריה. חלק התיקונים שחזרו לעבודה נוספת בגלל שינויים לא מתוארים או מתוארים לא נכון ירד מאחד מכל ארבעה לפחות מאחד מעשרים.
סירובים מהסיבה «הוציאו לא את מה שהוצהר» פסקו: תיאור המהדורה ותוכנה נוצרים כעת ממקור אחד, ופער ביניהם בלתי אפשרי טכנית.
השפעה נפרדת — ניווט צפוי מראש למי שמתעדכן מהגרסה הקודמת: מהיומן רואים אילו שינויים נוגעים בתצורה שלהם ואילו הם פנימיים.
מה לעשות אם ההיסטוריה הצטברה בפורמט חופשי
ניתן להפעיל את כללי Conventional Commits מעל כל היסטוריה קיימת — כמעט תמיד אין צורך לשכתב את העבר. rebase המוני של מאות קומיטים משנה hashים, מבטל את ערכם של קישורים במשימות וחתימות תגים, והצוות מאבד למשך שבועות את היכולת להשוות ענפים למהדורות. די להעביר גבול לפי תאריך: כל מה שאחריו הולך לפי הפורמט, כל מה שלפניו — נשאר כפי שהוא.
הגבול נקבע בבדיקה בעת הקליטה: השרת דוחה קומיט שבכותרתו אין סוג ותחום תקינים, ומחזיר למחבר הודעת שגיאה מובנת. מחולל ה-CHANGELOG מתחיל לא משורש מאגר הקוד, אלא מנקודת התחלה מסומנת במפורש — בדרך כלל התג של המהדורה הראשונה לאחר המיגרציה.
ההיסטוריה המצטברת אינה נעלמת לשום מקום: מהדורות קודמות מועברות לקובץ סטטי נפרד, שאינו מתעדכן יותר, ורשומות חדשות נאספות אוטומטית. עבור פרויקטים ישנים זה זול יותר מאשר לשחזר סוג ותחום לכל קומיט בדיעבד — מחיר עבודה כזו כמעט תמיד גבוה מהתועלת.
שכתוב מלא מוצדק בשני מקרים: מאגר הקוד נפתח החוצה ובהודעות נותר חומר פנימי, או שהקוד עובר למאגר חדש. אז מקפלים את ההיסטוריה לקומיט התחלתי אחד, וממשיכים את מספור המהדורות לפי תגים.
ספקות ומגבלות: ענפים, מיזוגים, עריכות המוניות
התקן מגדיר את פורמט ההודעה, אך אינו מתאר את התהליך — ההסתייגויות נוגעות למקומות שבהם הכללים מתנגשים עם עבודה אמיתית בענפים.
מיזוגים. כותרת קומיט המיזוג נוצרת על ידי מערכת בקרת הגרסאות, ולא על ידי אדם, ולכן אינה מתאימה לתבנית. קומיטים כאלה מוחרגים מהבדיקה ומייצוג ביומן השינויים — אחרת היומן מתמלא ברעש פנימי.
אם ענף ממוזג בקומיט אחד דחוס, הטקסט נלקח מכותרת בקשת המיזוג: הבדיקה מוטלת בצד השרת, ולא רק ב-hook מקומי.
עריכות המוניות. עיצוב, שינוי שם של מודול או ריפקטורינג אוטומטי מייצרים מאות קומיטים מאותו סוג. מקבצים אותם לסוג שינוי אחד, כדי שהיומן לא יתנפח, ואת שכתוב ההיסטוריה עושים לפני פרסום הענף — אחרת קישורים לקומיטים בדיונים מפסיקים להיפתח.
מקרים שנויים במחלוקת וגבולות. שינוי שאינו תואם לאחור לפעמים הגיוני יותר לנסח בתוך תיקון, ואת החזרה לאחור — כסוג נפרד: התקן מתיר זאת דרך בלוק תיאור בגוף ההודעה, אך דורש סימון מפורש — אחרת הניתוח האוטומטי של הגרסה יטעה.
ומגבלה כן: הכללים מתארים רק הודעות קומיטים, ואינם מחליפים הסכמה על ענפים, סדר ביקורת ותדירות מהדורות.
מה לעשות עם קומיטים של מיזוג?
אין בודקים אותם להתאמה לתבנית ואין כוללים אותם ביומן השינויים. רשומות משמעותיות נותנים הקומיטים בתוך הענף, והמיזוג נשאר פעולה פנימית.
האם ניתן לסטות מהכלל עבור עריכה המונית?
כן, אך הסטייה צריכה להיות זהה לכל המקבץ: סוג אחיד, תיאור אחד. אז היומן נשאר קוהרנטי, וההיסטוריה — ראויה לחיפוש סיבת השינוי.
נדון בהטמעת תקן התיקונים בצוות שלכם
כאשר דנים בתקן תיאור התיקונים «בעל פה», השיחה נתקלת בהרגלים אישיים: עבור אחד אלו הודעות פנימיות, עבור אחר — היסטוריית הפרויקט, שלפיה אחר כך משחזרים את סיבות השינויים.
כדי שההערכה והתוכנית יישענו על התהליך שלכם, ולא על תבנית כללית, כדאי להכין לשיחה כמה עובדות על איך התיקונים חיים כיום.
- כיצד מנסחים תיאור תיקונים ומי בודק אותו בביקורת;
- כמה ענפים מנוהלים במקביל וכיצד מתרחש המיזוג לראשי;
- כיצד מוציאות גרסאות — ידנית, לפי לוח זמנים או לפי מוכנות מקבץ תיקונים;
- מה נכנס כעת ליומן השינויים ומי אוסף אותו לפני המהדורה;
- אילו בדיקות כבר קיימות בצד השרת לפני קליטת התיקון;
- האם יש תיקונים שמשנים את התנהגות המערכת באופן לא תואם, וכיצד מסמנים אותם.
בסיום הצוות מקבל הסכמה על הפורמט, כלל לבדיקה אוטומטית של התיאור לפני קליטת התיקון והרכבת יומן השינויים ישירות מההיסטוריה. מספור הגרסאות והסעיף על שינויים לא תואמים מתחילים להיווצר על ידי מכונה, ולא על ידי הזיכרון של התורן — השלב הידני לפני המהדורה מצטמצם לסקירת הטקסט המוכן.
אנחנו מנתחים גם את המעבר בחזרה: חלק מהתיקונים בהיסטוריה הישנה אינו מסומן, ולכן עבורם אנו קובעים כללי התאמה ותקופת מעבר, שבה הבדיקה מזהירה אך אינה חוסמת. תארו את המשימה וכתבו את מה שכבר קיים — נחזור עם הערכה ותוכנית: היכן התקן מוטמע בלי חיכוך, והיכן נדרש שלב מיגרציה נפרד.







