קבצים שאינם למעקב

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

1. יצירת פרויקט הדוגמה

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

אני מפעיל את תוכנת PyCharm כדי ליצור פרויקט פייתון חדש ובוחר מהתפריט File ואז New Project. שימו לב ש PyCharm כולל את האופציה במסך זה ליצור גם מאגר גיט יחד עם הפרויקט. אני לא מסמן אפשרות זו כדי להוסיף את הגיט אחר כך דרך Github Desktop. לאחר יצירת הפרויקט אני יוצר בו קובץ בשם demo.py עם התוכן הבא:

print("Hello world")

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

C:\Users\ynonp\PycharmProjects\pythonProject

ולכן באפליקציית Github Desktop בתיבת Local path אני כותב:

C:\Users\ynonp\PycharmProjects\

ובתיבת name אני כותב:

pythonProject

לאחר מכן אני לוחץ Create Repository ואנחנו מוכנים להתחיל לדבר על גיט.

2. קבצים שלא בפרויקט

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

אני פותח את הפרויקט בסייר הקבצים ב Windows ואני יכול לשים לב שבתיקיית הפרויקט היו שתי תתי תיקיות ועוד קובץ פייתון אחד:

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         9/28/2024  11:35 AM                .idea
d-----         9/28/2024  11:25 AM                .venv
-a----         9/28/2024  11:35 AM             66 .gitattributes
-a----         9/28/2024  11:26 AM             20 demo.py

גיטהאב דסקטופ מראה לי שהקומיט שהוא יצר כלל מספר קבצים מתוך תיקיית .idea, קובץ חדש שהוא יצר בשם .gitattributes ואת קובץ הקוד demo.py. הקבצים מתיקיית .venv כלל לא נכנסו לריפוזיטורי וכך גם חלק מהקבצים בתיקיית .idea.

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

באותו אופן בפרויקט ווב לא נשמור את תיקיית node_modules בתוך ריפוזיטורי של גיט, רק את קבצי ה package.json ו package-lock.json באמצעותם אותה תיקייה נוצרת. בפרויקט C או C++ לא נשמור את הקבצים המקומפלים בתוך הריפוזיטורי, אלא רק את המקור שלהם ואת ה Makefile או סקריפט הקומפילציה. בקיצור אנחנו רוצים לשמור בגיט את הדברים שיש להם משמעות מבחינת גירסאות וחזרה אחורה.

3. אבל איך הוא ידע

ההגיון ברור אבל עכשיו שאלת ההמשך - איך גיט ידע להתעלם מאותם קבצים שבאמת לא צריכים להישמר במאגר? התשובה היא קובץ בשם .gitignore שיכול להופיע בתיקיית הפרויקט או בכל אחת מתתי התיקיות בפרויקט. נתבונן בתוך תיקיית .venv שנוצרה באופן אוטומטי בעת יצירת הפרויקט מפייצ'ארם ונמצא שם קובץ בשם .gitignore עם התוכן הבא:

# created by virtualenv automatically
*

סימן הכוכבית אומר לגיט שיש להתעלם מכל הקבצים והתיקיות בתיקייה זו. מה לגבי התיקייה .idea? שם יש קובץ בשם .gitignore עם התוכן הבא:

# Default ignored files
/shelf/
/workspace.xml

הקובץ קובע שתיקיית shelf והקובץ workspace.xml בתוך תיקיית .idea יישארו מחוץ לריפוזיטורי.

4. ניצור קובץ gitignore

בואו ננסה את זה גם. אני יוצר בתיקיית הראשית של הפרויקט קובץ בשם .gitignore עם התוכן הבא:

.env
*.pyc

עכשיו נעדכן את הקבצים. תחילה בקובץ demo.py אני מוסיף קצת קוד והקובץ יראה כך:

import utils

utils.say_hello()

לאחר מכן אני יוצר קובץ חדש בשם utils.py עם התוכן הבא:

def say_hello():
    print("Hello world")

ולסיום אני יוצר קובץ בשם .env עם התוכן הבא:

PASSWORD=ninja

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

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

  2. הקובץ demo.py וגם utils.py מופיעים ברשימה כי הם עודכנו. איתם גם קובץ מתוך תיקיית .idea. הוא עודכן בצורה אוטומטית על ידי פייצ'ארם. גם קובץ ה .gitignore שיצרתי מופיע ברשימה.

  3. בסייר הקבצים אני רואה שבתוך תיקיית הפרויקט נוצרה תיקייה חדשה בשם __pycache__ ובה קובץ בודד בשם utils.cpython-312.pyc. קובץ זה לא מופיע ברשימת השינויים בגלל הסיומת שלו pyc - זכרו שב .gitignore ביקשתי להתעלם מכל הקבצים בסיומת זו.

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

5. עכשיו אתם

  1. בצעו קומיט לשינויים כדי לראות שרשימת השינויים התרוקנה ויש לנו שני קומיטים בפרויקט.

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

  3. צרו בתוך התיקייה החדשה קובץ בשם intro.txt וכתבו בו טקסט כלשהו וודאו שאתם רואים את הקובץ ברשימת השינויים ב Github Desktop.

  4. הוסיפו את שם הקובץ intro.txt לסוף קובץ .gitignore וחזרו ל Github Desktop. שימו לב שהקובץ נעלם מרשימת השינויים וכעת נמצא שם רק השינוי בקובץ .gitignore.

  5. מחקו את שם הקובץ intro.txt מהקובץ .gitignore באמצעות ביטול השינוי מתוך אפליקציית Github Desktop. שימו לב שעכשיו intro.txt שוב מופיע ב Github Desktop. בצעו קומיט לשינוי.

  6. הוסיפו את הקובץ intro.txt שוב ל .gitignore וגם הוסיפו שורה לקובץ intro.txt כדי שיהיה בו שינוי. האם אתם רואים את השינוי ברשימת השינויים? מה למדתם מהניסוי?