מעיכת קומיטים עם Merge Squash
בעבודה עם גיט אנחנו אוהבים ליצור Feature Branch עבור כל פיצ'ר שאנחנו צריכים, ובסיום העבודה להפעיל merge כדי למזג את כל הקומיטים של ה Feature Branch בחזרה לענף הראשי. בפרויקטים גדולים לפעמים משתלם לכווץ את כל הקומיטים מהפיצ'ר בראנצ' לקומיט יחיד כדי שיהיה יותר קל להסתכל בהיסטוריה.
נניח בשביל הדוגמא ש master הוא הענף הראשי ו dev הוא ענף פיצ'ר קטן, והקומיטים שלהם נראים כך:
$ git log --oneline master
b4ff474 (HEAD -> master) c4
9da14d1 c3
146d73d c2
e82851f c1
$ git log --oneline dev
433746a (dev) c7
8324f82 c6
da5ccb8 c5
146d73d c2
e82851f c1
במצב כזה merge רגיל יחבר את כל הקומיטים כך שנקבל את עץ הפרויקט הבא:
$ git merge dev
$ git log --oneline --graph
* 9b80e8d (HEAD -> master) merge commit
|\
| * 433746a (dev) c7
| * 8324f82 c6
| * da5ccb8 c5
* | b4ff474 c4
* | 9da14d1 c3
|/
* 146d73d c2
* e82851f c1
הקומיטים c7, c6 ו-c5 שבוצעו ב Feature Branch עכשיו נמצאים איתנו ויישארו בעץ הפרויקט לנצח. דרך אחת לוותר עליהם היא "לכווץ" אותם לפני ביצוע המיזוג:
נעבור לענף dev
נחזיר את HEAD אחורה ל C2 בלי לשנות את הקבצים בתיקיית העבודה (עם פקודת reset). הקומיט C2 הוא הקומיט המשותף האחרון בין dev ל master ולכן זה בעצם הקומיט שהתחיל את הפיצול. החזרה אליו תאפשר לנו "לאחד" את קומיטים C5, C6 ו C7 לקומיט חדש יחיד.
נעשה קומיט אחד שיכלול את כל הקבצים בתיקיית העבודה, אפשר לקרוא לו C8.
אחרי פעולה זו ב dev יהיה רק קומיט יחיד (הקומיט שעשינו בסעיף 3), וכשנמזג אותו חזרה ל master נראה בהיסטוריה רק את הקומיט היחיד הזה.
לגיט יש קיצור דרך לרצף הזה שעושה משהו אפילו יותר נחמד: הפקודה git merge --squash
תיקח את כל הקבצים מענף dev למקום הנוכחי בלי להזיז את HEAD, בלי לעשות קומיט ובלי לעדכן את MERGE_HEAD
. הדבר השלישי אומר שהקומיט הבא לא יהיה Merge Commit עם שני הורים אלא קומיט רגיל.
בקוד זה נראה כך:
$ git merge --squash dev
$ git log --oneline --graph
* b4ff474 (HEAD -> master) c4
* 9da14d1 c3
* 146d73d c2
* e82851f c1
עכשיו אפשר לעשות קומיט ולקבל:
$ git add .
$ git commit -m 'C8'
$ git log --oneline --graph
* 08f5e15 (HEAD -> master) C8
* b4ff474 c4
* 9da14d1 c3
* 146d73d c2
* e82851f c1
וקיבלנו מיזוג של Feature Branch לענף הראשי תוך מחיקת ההיסטוריה של ה Feature Branch ושמירה על לוג לינארי בענף הראשי.