קונפליקטים

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

1. יצירת קונפליקט

נפתח את אחד העותקים של ספר המתכונים שלנו, נכנס למתכון של הטאקוס הצמחוניים בקובץ vegan-tacos.md. בשורה 10 בקובץ אני רואה מיץ מליים אחד. נעדכן את השורה לטקסט:

- 2 limes, juiced

ונבצע קומיט. אין צורך עדיין לבצע Push.

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

- 1/2 red onion, finely chopped
- 1 tsp cumin
- 1/2 tsp chili powder

שוב קומיט ועכשיו גם Push.

נחזור לעותק הראשון - זכרו שבשביל לעבור בין העותקים אני לוחץ על התיבה Current Repository בצד שמאל למעלה של המסך ובוחר את ה Repository השני - ושם ננסה לבצע Push. התוצאה היא ההודעה:

Desktop is unable to push commits to this branch because there are commits on the remote that are not present on your local branch. Fetch these new commits before pushing in order to reconcile them with your local commits.

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

  1. הקומיט החדש שינה את כמות הלימונים ל-2.

  2. הקומיט העדכני ביותר אצלי מחק לגמרי את הלימונים.

מישהו יצטרך לוותר.

2. תיקון הקונפליקט

בחלון הבא אני רואה הודעה שאומרת לי בדיוק את זה - המצב הזה בו אני מושך קומיטים מתיקייה משותפת אבל כבר עשיתי שינויים שמפריעים לקומיטים אלה נקרא קונפליקט. במצב של קונפליקט עליי לבחור איך לשלב את שני השינויים לפני שאוכל להמשיך בעבודה. אני לוחץ על הכפתור Open in Visual Studio Code כדי לראות את שני השינויים ולנסות לשלב ביניהם. אחרי הפתיחה ב VS Code אני רואה טקסט שנראה בערך כך:

- 1/4 cup chopped cilantro
- 1/2 red onion, finely chopped
<<<<<<< HEAD
- 2 limes, juiced
=======
>>>>>>> 26cd185c44fb6a3f4e79e1429266ade8137bb596
- 1 tsp cumin
- 1/2 tsp chili powder

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

עכשיו צריך להחליט מה יהיה במתכון - 2 ליים? אף ליים? אולי חזרה ל-1? או חצי? אני מעדיף שלא יהיה ליים בכלל ולכן מעדכן את הקובץ לתוכן הבא:

- 1 avocado, diced
- 1/4 cup chopped cilantro
- 1/2 red onion, finely chopped
- 1 tsp cumin
- 1/2 tsp chili powder
- Salt and pepper to taste
- 8 small corn tortillas

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

  1. הקומיט העדכני ביותר נקרא Merge Commit. זה קומיט שנוצר אחרי ששילבתי בין שני קומיטים: אחד שמחק את הליים והשני שהעלה את הכמות ל-2 ליימים.

  2. לפניו הקומיט שמחק את הליים.

  3. ועוד אחד אחורה זה הקומיט שהוסיף ליים.

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

3. מה קרה בעותק השני

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

הדרך שלי לזהות שמשהו מוזר קרה היא להיכנס לקובץ vegan-tacos.md ולראות שהמתכון לא כולל ליימים בכלל, או ללכת להיסטוריית הקומיטים ולראות את הקומיט שמחק את הליים שהוספתי.

4. עכשיו אתם

  1. צרו קונפליקט במתכון השני בספר chickpea-and-spinach-curry.md. בשביל המשחק נסו לעדכן מספר שורות ובמקום למחוק עדכנו רק את הכמויות. שימו לב שאתם מצליחים להבין מקריאת הקובץ עם הקונפליקט מה בדיוק קרה שם.

  2. תקנו את הקונפליקט וודאו שהגירסה ב github.com מעודכנת.