מה כדאי לסטודנט לדעת - Git

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

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

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

אז מה זה ניהול גרסאות ולמה זה חשוב?

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

דבר נוסף שיכול לקרות, שננסה לשנות איזה משהו מסובך בקוד שלנו, ניגע באיזה 5 מחלקות בכמה קבצים שונים, נשנה כל מיני ברירות מחדל ואופס- לא חשבנו על משהו ובעצם זה לא ילך. איך חוזרים אחורה? לא חושב שמספיק לעשות Ctrl+Z לכל הקבצים..

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

הבעיות

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

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

הפתרון

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

בשונה מהרבה תוכנות לניהול גרסאות, ששומרות שינויים שנעשו מגרסה לגרסה (למשל- שורה 3 בקובץ file.f נמחקה, שורה 8 בקובץ my.file נוספה), גיט שומר בכל פעם את הגרסה הנוכחית של הקובץ. מכיוון שגיט שם דגש על מהירות, היכולת הזאת מאפשרת לגיט לעבור בין הגרסאות השמורות בקלות, כי כל גרסה פשוט שמורה במסד הנתונים, בעוד שתוכנות אחרות יצטרכו לעבור על כל השינויים שהם שמרו ולעשות אותם מחדש.

איך זה עובד?

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

למה זה מיוחד? כי בצורה הזאת אנחנו מקבלים את הפיצ'ר אולי הכי עיקרי בגיט- הענפים. בגלל שגיט לא מחליט על סדר הגרסאות למשל על פי תאריך, אלא כל גרסה (קומיט) מצביעה על הגרסה שלפניה, כל מה שצריך להחזיק זה את הגרסה האחרונה (כי דרכה נוכל לנווט אחורה, LinkedList וזה..) כך שכל ענף הוא בעצם "מצביע" על קומיט מסוים.

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

אז מה יש לנו:

נעבור על ארבעת הבעיות שתיארנו.

חוסר יכולת לבטל שינויים של הקוד

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

"זוכרים"? בשביל שלא נצטרך לזכור (ובשביל עוד דברים) יש לנו את הענפים (מצביעים, כן?).

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

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

קושי בעבודה מבוזרת

אז איך פותרים את הסיפור הזה?

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

עדכון השרת- השרת מבין שעדכון הענף לא סותר את המצב הקיים, אז הוא מבצע את העדכון.

השני שינסה לעדכן את הremote יגלה שבעצם הענף שאצלו בתיקייה והענף שבremote כבר לא אותו דבר. ברגע שמנסים לאחד 2 ענפים שונים, גיט מבצע את פעולת merge, שבה הוא משווה את 2 הענפים (2 גרסאות, קומיטים) עם הגרסה המשותפת האחרונה שלהם. אם כל אחד שינה משהו אחר, שורות אחרות בקובץ או קבצים אחרים, גיט יבצע איחוד אוטומטי של השינויים. אם יש סתירות, ו2 האנשים נגעו באותו מקום, גיט יבקש מאיתנו לפתור את השינויים ידנית.

ביצוע Merge- שני ענפים שונים (אמנם אותו שם, אבל ענף אחד בשרת וענף אחד אצלנו) מתאחדים לCommit אחד אחרי Merge.

גיבויים של הקוד

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

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

עבודה במקביל על כמה שינויים ללא תלות של שינוי אחד בשני

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

מעבר בין ענפים לצורך תיקון באג במוצר

יתרונות נוספים

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

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

קריאה נוספת

  • רן בר זיק באתר "אינטרנט ישראל"- רן בר זיק הוא מפתח Frontend והוא מסביר באתר שלו על המון דברים מעניינים, מפיתוח בטכנולוגיות Web ועד "סייבר". הקישור מפנה לסדרת ההדרכות שלו על גיט.
  • הספר של גיט- לקוראי האנגלית, כאן ההסבר הרשמי של גיט על הטכניקות של הכלי, תוך כדי הסברים על אופן השימוש בפועל.
  • ממשק משתמש לגיט- תוכנת Git Extension היא תוכנה נחמדה לעבודה מול גיט בממשק משתמש אינטראקטיבי ולא בשורת הפקודה. אני משתמש הרבה בתוכנה הזאת.

מושגים

  • Git- גִיט הוא כלי לניהול גרסאות, שמאפשר לנו לעבוד על אותו קוד עם אנשים אחרים, ולעבור בקלות ובמהירות בין גרסאות שונות של הקוד לצורך משימות שונות.
  • GitHub- גִיטהָאבּ הוא אתר לשיתוף קוד שמתבסס על תוכנת גיט.
  • Commit- קוֹמִיט היא הפעולה הבסיסית בGit, שאומר לכלי לשמור את המצב הנוכחי כגרסה.
  • Feature- תכונה. משמש אותנו לתיאור "יכולת" מסוימת. למשל- "ווטסאפ הוסיפו פיצ'ר חדש, וי כחול".
  • Branch- מצביע על Commit מסוים בגיט. או ביותר אנושי- רצף קומיטים כלשהו.