ניהול גרסאות

בקרת גרסאות (version control או source control) היא מנגנון לתיעוד, מעקב ובקרה אחר שינויים בגרסאות מרובות של אותה יחידת מידע. מערכות בקרת גרסאות מאפשרות עבודה במקביל של מספר אנשים על אותו הפרויקט באופן יעיל. המילה "גרסאות" מתייחסת לתוכן ולא למספר הגרסה.

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

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

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

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

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

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

מודלי אחסון
במערכות פשוטות (RCS, מעקב אחר שינויים במסמכי Microsoft Word, ועוד) כל המידע נמצא במסמך עצמו או צמוד אליו. מערכות מורכבות יותר מאפשרות למשתמשים ממקומות שונים לעבוד (לרוב במקביל) על המידע.
 מודלי אחסון ריכוזיים - באופן מסורתי, מערכות בקרת גרסאות השתמשו במודלי אחסון ריכוזיים, שבהם כל פונקציות ניהול הגרסאות בוצעו על שרת משותף. לכן, הם מכונים גם מודלי שרת-לקוח: בדרך-כלל, המשתמש המקומי מתחבר לשרת המרכזי, שאצלו נמצא העותק הראשי.
 מודלי אחסון מבוזרים - מערכות כגון גיט ומרקוריאל עובדות במודל מבוזר: כל מפתח עובד עם מאגר זיכרון (Repository) מקומי משלו והשינויים משולבים בין המאגרים בשלב נפרד. מצב פעולה זה מאפשר למפתחים לעבוד אף ללא חיבור רשת ובנוסף הוא מאפשר למפתחים יכולות ניהול גרסאות מלאות, ללא צורך בקבלת הרשאות, שמוענקות על ידי רשות מרכזית.

נעילת קובץ
ברוב הפרויקטים של פיתוח תוכנה, מספר מפתחים עובדים על תוכנה אחת באותו זמן. אם שני מפתחים מנסים לשנות את אותו קובץ באותו זמן, ללא כל שיטה לניהול גישה לקובץ, המפתחים עלולים לבטל זה את עבודתו של זה. רוב מערכות ניהול הגרסאות פותרות עניין זה באחת משתי דרכים:
 נעילת קבצים – זוהי הדרך הפשוטה והפרימיטיבית ביותר. כאשר מפתח רוצה לעבוד על קובץ, הוא "שם מנעול" וירטואלי על הקובץ. בזמן הזה, ועד שאותו משתמש שומר באופן סופי את הקובץ ומשחרר את המנעול, המערכת מונעת מכל משתמש אחר לשמור שינויים לקובץ. בגישה הזו עושה שימוש, לדוגמה, מערכת Microsoft Visual SourceSafe.
 מיזוג שינויים – מפתחים שונים יכולים לעבוד במקביל על עותקים שונים של אותו קובץ. אם מתגלה (בדרך-כלל, בזמן קבלת עדכון לעותק המקומי מהמאגר הראשי) שמישהו אחר שינה את הקובץ, ובוצעו בו גם שינויים מקומיים, נעשה ניסיון למזג את כל השינויים לעותק אחד קוהרנטי. מערכת CVS, לדוגמה, עובדת בדרך זו.

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

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

מילון מונחים
 Repository (מאגר)

המאגר שבו נשמרים קובצי המידע ההיסטוריים והנוכחיים - לרוב בשרת. לעיתים משתמשים במילה depot (מחסן).

 Working copy (עותק עבודה) עותק מקומי של קבצים מה-Repository, בזמן או בגרסה מסוימים. כל העבודה הנעשית על קובצי המאגר מתבצעת בעותק העבודה, ומכאן שמו.

 Check-out פעולה שיוצרת עותק עבודה מקומי מהמאגר. פעולה זו יכולה להתבצע על גרסה מבוקשת או על הגרסה האחרונה. פעולה זו קרויה גם checkout או co.

 Commit (שמירת שינויים) מתרחש כאשר העתק של שינויים שנעשו בעותק העבודה נכתבים למאגר. לעיתים קרוי submit (שליחה), install (התקנה/קיבוע), check-in או ci (רישום).

 Change  מייצג שינוי מסוים במסמך תחת ניהול גרסאות. הגרעיניות של מה שנחשב לשינוי משתנה בין מערכת למערכת. קרוי גם diff (קיצור של difference - הבדל) או delta (דלתא - הפרש).

 Change list  במערכות ניהול גרסאות שתומכות בטרנזקציה להחלת Commit מרובה שינויים, changelist (או change set - קבוצת שינויים) מזהה קבוצת שינויים שנעשו כ-commit יחיד (גרסה אחת).

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

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

 Merge  מיזוג שני סטים של שינויים, שנעשו בקובץ או בסט של קבצים, לתוך גרסה אחידה של קובץ או של סט קבצים זה. קרוי גם integration (אינטגרציה - שילוב/מיזוג). מצב זה יכול לקרות:
כאשר משתמש אחד, שעובד על קבצים אלו, מבצע לתוך עותק העבודה שלו עדכונים עם שינויים שנעשו על ידי אחרים ונשמרו לתוך המאגר. באופן הפוך, תהליך דומה יכול לקרות במאגר כאשר משתמש מנסה לבצע check-in לשינויים שלו.
לאחר הסתעפות (branched) של סט קבצים, כאשר בעיה שהייתה קיימת לפני ההסתעפות תוקנה במסעף אחד וצריכה להיות ממוזגת לתוך המסעף השני.
כאשר מבקשים למזג ליחידה אחת, קבצים שפוצלו (branched) ופותחו באופן עצמאי במשך תקופה.

 Revision גרסה בתוך שרשרת של שינויים. קרוי גם version (גרסה).

 Tag  סימון קבוע לקבצים רבים בנקודת זמן חשובה. קבצים אלו, בנקודת זמן זו, יכולים כולם להיות מסומנים בשם בעל משמעות מובנת למשתמש. קרוי גם release (שחרור) או Label (תווית).

 Import (ייבוא) פעולת העתקה של עץ תיקיות מקומי, שאינו עותק העבודה, לתוך המאגר.

 Export (ייצוא) פעולה דומה ל-check-out, מלבד זאת שעץ התיקיות המקומי שהיא יוצרת נקי מ-Metadata של ניהול גרסאות, כזה שבו נעשה שימוש בעותק העבודה. לעיתים קרובות נעשה בזה שימוש לקראת פרסום התוכן.

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

 Resolve  התערבות המשתמש, במטרה ליישב התנגשות של שני שינויים באותו מסמך.

 Annotate  הצגת תוכנו של קובץ, לצד הגרסה ממנה הגיעה כל שורה. משמש, בדרך-כלל, להראות מי אחראי לחלק מסוים מהתוכן, ולכן ידוע גם כ־blame (אישום).

ראו גם
 ניהול גרסאות תוכנה

קישורים חיצוניים

 Understanding Version-Control Systems - מאמר מאת אריק ריימונד על ההיסטוריה של בקרת גרסאות והתפתחות המונחים ודרכי העבודה בהן

 הערות שוליים 

*