הצילו גיט - אי אפשר לגשת לקובץ

19/09/2023

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

1. איך נכנסים לבור

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

$ git add demo

גיט נלחץ ומדפיס הודעה ארוכה ממנה אני קורא רק את השורה הראשונה:

warning: adding embedded git repository: demo
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint:   git submodule add <url> demo
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint:   git rm --cached demo
hint:
hint: See "git help submodule" for more information.

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

$ rm -rf demo/.git
$ git add demo
$ git commit -m 'add demo'

הפעם ב add אין שגיאה והקומיט גם עבר בשלום. את התוצאה דחפתי לריפו בקישור הזה: https://github.com/ynonp/add-subproject-demo.

אם תיכנסו לריפו תשימו לב שאתם לא באמת יכולים להיכנס לתיקיית demo או לראות את הקבצים שבתוכה.

2. מה שבור בפרויקט

נפעיל log כדי לראות מה נשבר:

$ git log -p


commit 6d0d2fd41a8aa93a302d62cea5918b783ac00232 (HEAD -> main, origin/main)
Author: ynonp <ynonperek@gmail.com>
Date:   Mon Sep 18 21:39:37 2023 +0300

    add demo

diff --git a/demo b/demo
new file mode 160000
index 0000000..badb3c5
--- /dev/null
+++ b/demo
@@ -0,0 +1 @@
+Subproject commit badb3c5753a70c02e4e05a62ef9d6fcb65758d6c

commit 64f5679443ac216fb0e94483e679473f6f458294
Author: ynonp <ynonperek@gmail.com>
Date:   Mon Sep 18 21:36:30 2023 +0300

    hello world\

diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1 @@
+hello world

ונשים לב באמצע לשורה:

+Subproject commit badb3c5753a70c02e4e05a62ef9d6fcb65758d6c

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

3. איך יוצאים מהבור

אחרי שהבנו את הבעיה אפשר לחזור ולקרוא את האזהרה של גיט:

hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint:   git rm --cached demo
hint:
hint: See "git help submodule" for more information.

בגלל שתת-הפרויקט demo הסתיר את התיקיה demo (וזה החלק המבלבל פה), אני צריך למחוק אותו לפני שאוכל להוסיף את התיקיה.

$ git rm --cached demo
$ git add demo
$ git commit -m 'add demo'

4. מה היה צריך לעשות מראש

שווה לזכור ש add באמת עושה דברים, והפעולה ההפוכה שלו היא reset, לכן אם קיבלתי אזהרה מפחידה מגיט אחרי add הדבר הכי קל לעשות הוא:

$ git add demo
warning: adding embedded git repository: demo
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint:   git submodule add <url> demo
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint:   git rm --cached demo
hint:
hint: See "git help submodule" for more information.

$ git reset
$ rm -rf demo/.git
$ git add demo
$ git commit -m 'add demo'

ביטול ה add עם reset לפני שממשיכים היה חוסך את הכנסת תת הפרויקט ואת הבילבול שבא איתו.