• בלוג
  • טיפ גיט: הצגת שינויים ב Merge Commit

טיפ גיט: הצגת שינויים ב Merge Commit

01/12/2025

נתון הריפו הבא:

*   a883c36 (HEAD -> main) Merge branch 'develop'
|\
| * c363960 (develop) refactor to use function
* | d55f747 fixed text
|/
* 64b74f3 initial commit

יש לנו ענף main וענף develop, בענף develop ביצענו שינוי בקומי c363960 וענף main עשה שינוי באותו זמן ובאותו קובץ בקומי d55f747. בסוף מיזגנו את השינויים מ develop בקומיט a883c36.

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

$ git log -p -1

commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

אני רואה את קומיט המיזוג אבל נראה שאין בו שינויים כלל! מה קורה פה?

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

--diff-merges=<format>
    Specify diff format to be used for merge commits. Default is `off`

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

 $ PAGER= git log -1 -p --diff-merges=1
commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

diff --git a/demo.py b/demo.py
index 73bd701..ba6d51e 100644
--- a/demo.py
+++ b/demo.py
@@ -1,2 +1,5 @@
-if __name__ == "__main__":
+def greet():
     print("Hello World")
+
+if __name__ == "__main__":
+    greet()

מזה אנחנו מבינים שענף develop הוציא את ההדפסה של Hello World לפונקציה נפרדת בשם greet. ומה עם ענף develop עצמו? אז אין ערך 2 ל diff-merges אבל ניתן להשתמש במילה separate כדי לראות את השינויים מול כל הענפים:

$ PAGER= git log -1 -p --diff-merges=separate
commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (from d55f74779962b803a89f178a08065014dd74b3ac) (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

diff --git a/demo.py b/demo.py
index 73bd701..ba6d51e 100644
--- a/demo.py
+++ b/demo.py
@@ -1,2 +1,5 @@
-if __name__ == "__main__":
+def greet():
     print("Hello World")
+
+if __name__ == "__main__":
+    greet()

commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (from c363960ad68f3b2875b083d7bc2b92e57df1cb7a) (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

diff --git a/demo.py b/demo.py
index 3635ac7..ba6d51e 100644
--- a/demo.py
+++ b/demo.py
@@ -1,5 +1,5 @@
 def greet():
-    print("hello world")
+    print("Hello World")

 if __name__ == "__main__":
     greet()

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

אפשרות שלישית למתג זה היא combined או בקיצור c שמציגה את כל ההבדלים יחד:

$ PAGER= git log -1 -p --diff-merges=c
commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

diff --combined demo.py
index 73bd701,3635ac7..ba6d51e
--- a/demo.py
+++ b/demo.py
@@@ -1,2 -1,5 +1,5 @@@
- if __name__ == "__main__":
+ def greet():
 -    print("hello world")
 +    print("Hello World")
+
+ if __name__ == "__main__":
+     greet()

מצד אחד יותר קל להבין כאן מה השתנה אבל מצד שני יותר קשה להבין מאיזה ענף הגיע כל שינוי.

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

$ PAGER= git log -1 -p --diff-merges=r
commit a883c360dfae324a365d9bfb9ab881865a33f0c4 (HEAD -> main)
Merge: d55f747 c363960
Author: ynonp <ynonperek@gmail.com>
Date:   Sun Nov 30 13:56:36 2025 +0200

    Merge branch 'develop'

diff --git a/demo.py b/demo.py
remerge CONFLICT (content): Merge conflict in demo.py
index 96d7fe5..ba6d51e 100644
--- a/demo.py
+++ b/demo.py
@@ -1,10 +1,5 @@
-<<<<<<< d55f747 (fixed text)
-if __name__ == "__main__":
-    print("Hello World")
-=======
 def greet():
-    print("hello world")
+    print("Hello World")

 if __name__ == "__main__":
     greet()
->>>>>>> c363960 (refactor to use function)

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