Version Control: למה צריך, ומושגי היסוד של Git

מטרות השיעור
  • להסביר מהי בקרת גרסאות ואילו בעיות היא פותרת
  • להגדיר Repository, Working Directory, Staging Area ו-Commit
  • לתאר את המסלול של שינוי — מעריכה, דרך Staging, ועד Commit
  • להתקין ולהגדיר את Git עם שם ומייל

מה נלמד?

  • מהי Version Control (בקרת גרסאות), ולמה כל מפתח משתמש בה.
  • מהו Git.
  • שלושת האזורים: Working Directory, Staging Area, Repository.
  • מהו Commit.
  • הגדרה ראשונית של Git.

למה צריך את זה?

מכירים את התיקייה הזו?

project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py
project_final_v3_fixed_REALLY_FINAL.py

הבעיות:

  • איזו גרסה עובדת? מה בדיוק השתנה בין v2 ל-v3?
  • “שברתי משהו, ואתמול זה עבד!” איך חוזרים למצב של אתמול?
  • עבודה בצוות: שניים ערכו את אותו קובץ. איך משלבים את השינויים בלי לדרוס?
  • גיבוי: הלפטופ נגנב. הפרויקט אבד?

Version Control פותרת את כל אלה. בכל חברת תוכנה בעולם, כל שורת קוד מנוהלת בה. בלי Git, אי אפשר לעבוד בצוות פיתוח, ובראיון עבודה מצפים שתכירו אותו.

הסבר מהבסיס

מהי Version Control?

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

מהו Git?

Git היא מערכת בקרת הגרסאות הנפוצה בעולם, בפער עצום. היא:

  • מקומית — כל ההיסטוריה שמורה אצלכם במחשב, בתיקייה נסתרת .git. עובד גם בלי אינטרנט.
  • מבוזרת (Distributed) — לכל מפתח יש עותק מלא של כל ההיסטוריה.
  • מהירה וחינמית, וכתובה במקור על ידי לינוס טורבאלדס, יוצר Linux.

Git ≠ GitHub! Git הוא הכלי שרץ אצלכם. GitHub הוא אתר שמאחסן עותק של ה-Repository שלכם בענן, ומוסיף כלים לשיתוף ולעבודת צוות. נכיר אותו בשיעור השלישי.

Repository (מאגר)

Repository (בקיצור Repo) = פרויקט ש-Git עוקב אחריו: התיקייה עם הקבצים, ועוד התיקייה הנסתרת .git שבה שמורה כל ההיסטוריה.

Commit — תמונת מצב

Commit = תמונת מצב (Snapshot) שמורה של הפרויקט ברגע מסוים, עם:

  • הודעה שמסבירה מה השתנה ולמה.
  • מחבר (שם ומייל) וזמן.
  • מזהה ייחודי (Hash), למשל a3f9c21.
  • הפניה ל-Commit הקודם, וכך נוצרת שרשרת היסטוריה.
(a3f9c21) ◄── (7b2e004) ◄── (e91d5aa)   ← HEAD (latest)
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
אנלוגיה: נקודות שמירה במשחק

Commit = נקודת שמירה במשחק מחשב. לפני הקרב עם הבוס שומרים. אם מפסידים, חוזרים לנקודה. ההבדל: ב-Git כל נקודת שמירה נשארת לתמיד, עם תיאור, ואפשר לחזור לכל אחת מהן או להשוות ביניהן.

שלושת האזורים

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

 Working Directory        Staging Area            Repository (.git)
 (the files you edit)     (ready for the next     (committed history)
                           commit)
       │                        │                        │
       │──── git add ──────────►│                        │
       │                        │──── git commit ───────►│
       │◄──────────────────── (checkout / restore) ──────│
אזורמה זהאיך מגיעים אליו
Working Directoryהתיקייה שאתם עובדים בה: הקבצים כמו שהם עכשיו בדיסקפשוט עורכים קבצים
Staging Area (נקרא גם Index)“אזור הכנה”: השינויים שבחרתם להכניס ל-Commit הבאgit add
Repositoryההיסטוריה השמורה: כל ה-Commitsgit commit

למה צריך Staging? כי לפעמים שיניתם 5 קבצים, אבל רק 3 מהם שייכים לאותו שינוי לוגי (“תיקון באג במחשבון”). Staging מאפשר לבחור בדיוק מה נכנס לכל Commit, כך שכל Commit הוא יחידה הגיונית אחת.

אנלוגיה: צילום תמונה קבוצתית

Working Directory = כל האנשים באירוע. Staging Area = האנשים שהזמנתם לעמוד מול המצלמה (“בואו, אתם, לתמונה”). Commit = לחיצה על הכפתור: התמונה נשמרת באלבום (Repository) לתמיד. מי שלא עמד מול המצלמה לא נכנס לתמונה, גם אם הוא באירוע.

מצבי קבצים

מצבמשמעות
Untrackedקובץ חדש ש-Git עוד לא עוקב אחריו
Modifiedקובץ מוכר ששונה מאז ה-Commit האחרון, אבל עוד לא ב-Staging
Stagedהשינוי ב-Staging, ומוכן ל-Commit
Committed (Unmodified)זהה ל-Commit האחרון, “נקי”

תחביר

התקנה: Git הותקן ביום הראשון של הקורס. בודקים: git --version.

הגדרה חד-פעמית (פעם אחת למחשב). Git רושם את השם והמייל בכל Commit:

git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
פקודהמשמעות
user.name / user.emailמי כתב את ה-Commit. בשיעור 3, אותו מייל כמו בחשבון ה-GitHub.
init.defaultBranch mainשם הענף הראשי יהיה main (המוסכמה המודרנית).
core.editor "code --wait"אם Git צריך לפתוח עורך, יפתח VS Code.
--globalההגדרה חלה על כל הפרויקטים במחשב.

בדיקה:

git config --global --list

דוגמת קוד ראשונה

נראה את רעיון ה"שלושה אזורים" בפקודות. בשיעור הבא נפרק כל אחת לעומק.

mkdir ~\dev\kodkod6\git-demo
cd ~\dev\kodkod6\git-demo
git init

פלט:

Initialized empty Git repository in C:/Users/dana/dev/kodkod6/git-demo/.git/

עכשיו יש Repository. התיקייה הנסתרת .git נוצרה. אפשר לראות אותה עם ls -Force (PowerShell) או ls -a (Bash).

פירוק הקוד שורה אחר שורה

שורההסבר
mkdir ...git-demoתיקייה רגילה לפרויקט.
cd ...git-demoנכנסים אליה. כל פקודות Git פועלות על ה-Repository של התיקייה הנוכחית.
git initinitialize: הופך את התיקייה ל-Repository, ויוצר בתוכה את .git.
.git/“המוח” של ה-Repository: כל ה-Commits, ההיסטוריה וההגדרות. לא נוגעים בה ידנית. אם מוחקים אותה, כל ההיסטוריה נמחקת (הקבצים עצמם נשארים).

דוגמה נוספת

מסע של שינוי אחד, דרך שלושת האזורים, עם git status אחרי כל צעד (הפירוט המלא בשיעור הבא):

New-Item hello.py
git status
git add hello.py
git status
git commit -m "Add hello.py"
git status

פלט (מקוצר):

Untracked files:
        hello.py

Changes to be committed:
        new file:   hello.py

[main (root-commit) 3c1f2a9] Add hello.py
 1 file changed, 0 insertions(+), 0 deletions(-)

nothing to commit, working tree clean
שלבמצב hello.pyאזור
אחרי New-ItemUntrackedWorking Directory בלבד
אחרי git addStagedStaging Area
אחרי git commitCommitted, ו-“working tree clean”Repository

טעות נפוצה

הטעות 1: git init בתיקייה הלא נכונה, למשל בתיקיית הבית (C:\Users\dana) או בתוך תיקייה שכבר נמצאת בתוך Repository אחר. אז Git עוקב אחרי כל הקבצים במחשב, או שנוצרים Repositories מקוננים ומבלבלים.

תמיד: cd לתיקיית הפרויקט, pwd כדי לוודא, ורק אז git init. ואם טעיתם: מוחקים את התיקייה הנסתרת .git שנוצרה בטעות (רק אותה!).

הטעות 2: “עשיתי git add, אז זה שמור.” לא! add רק מכין. רק commit שומר בהיסטוריה. ושינוי שעשיתם אחרי ה-add לא נכלל, עד שתעשו add שוב.

הטעות 3: לחשוב ש-Git מגבה בענן. Git מקומי. אם הלפטופ אבד, ה-Repository אבד איתו, אלא אם עשיתם push ל-GitHub (שיעור 3).

הטעות 4: לא להגדיר user.name / user.email.

Author identity unknown
*** Please tell me who you are.

Git מסרב לבצע Commit בלי לדעת מי המחבר. מריצים את פקודות ה-config מלמעלה.

תרגול

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

תרגיל 1: למה צריך ניהול גרסאות?

בתיקייה של דני יש את הקבצים:

project_final.py
project_final_v2.py
project_final_v2_WORKS.py
project_final_v3_dont_touch.py

תנו שלוש בעיות בשיטה הזו, ואיך Git פותר כל אחת.

הצג פתרון
הבעיהאיך Git פותר
לא ברור מה ההבדל בין הקבצים ומה השתנה בכל אחדכל Commit שומר בדיוק מה השתנה, עם הודעה שמסבירה למה
אי אפשר לדעת איזו גרסה היא באמת האחרונה ועובדתיש היסטוריה מסודרת אחת, ו-HEAD מצביע על המצב הנוכחי
כשעובדים כמה אנשים, כל אחד מוסיף “עוד גרסה”כולם עובדים על אותו Repository, ו-Git יודע לחבר את השינויים

תרגיל 2: שלושת האזורים

לכל פעולה — באיזה אזור נמצא השינוי אחריה: Working Directory, Staging Area או Repository?

  1. ערכתם את calculator.py ושמרתם.
  2. הרצתם git add calculator.py.
  3. הרצתם git commit -m "Add subtract".
הצג פתרון
  1. Working Directory — השינוי קיים רק בקובץ על הדיסק.
  2. Staging Area — השינוי סומן כחלק מה-Commit הבא.
  3. Repository — השינוי נשמר כצילום מצב בהיסטוריה.

תרגיל 3: הגדרה ראשונה

כתבו את הפקודות שמגדירות ל-Git את השם Dana Cohen ואת האימייל dana@example.com, ואז יוצרות Repository חדש בתיקייה הנוכחית. למה Git צריך שם ואימייל?

הצג פתרון
git config --global user.name "Dana Cohen"
git config --global user.email "dana@example.com"
git init

Git רושם בכל Commit מי ביצע אותו. בלי שם ואימייל, Git לא יסכים לבצע Commit. --global שומר את ההגדרה פעם אחת לכל ה-Repositories במחשב.

תרגיל 4: שרשרת של Commits

(a3f9c21) <── (7b2e004) <── (e91d5aa)  <- HEAD
"Initial      "Add price     "Fix VAT
 project"      calculator"    rounding"
  1. מה זה כל אחד מהמזהים a3f9c21, 7b2e004, e91d5aa?
  2. על מה מצביע HEAD?
  3. למה כל Commit “מצביע” על הקודם לו?
הצג פתרון
  1. אלה מזהים של Commits — כל Commit מקבל מזהה ייחודי (כאן מקוצר).
  2. HEAD מצביע על ה-Commit הנוכחי — e91d5aa, “Fix VAT rounding”. זה המצב שבו הקבצים נמצאים עכשיו.
  3. כך נוצרת היסטוריה: מכל Commit אפשר ללכת אחורה ולראות מה היה לפניו, ולחזור לכל נקודה בעבר.

תרגיל 5: למה צריך Staging Area?

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

הצג פתרון

ה-Staging Area מאפשר לבחור מה ייכנס לכל Commit:

  1. git add calculator.py → Commit: “Fix rounding bug in calculator”.
  2. git add README.md → Commit: “Improve README”.
  3. את קובץ הבדיקה הזמני לא מוסיפים בכלל.

כך כל Commit הוא שינוי לוגי אחד עם הודעה ברורה — ולא ערבוב של כל מה שנגעתם בו באותו יום.

סיכום

  • Version Control מתעדת כל שינוי, ומאפשרת לחזור אחורה, להשוות ולעבוד בצוות. Git הוא הכלי. GitHub הוא האתר שמאחסן בענן.
  • Repository = פרויקט + התיקייה הנסתרת .git עם כל ההיסטוריה.
  • Commit = תמונת מצב עם הודעה, מחבר, זמן ומזהה (Hash).
  • שלושה אזורים: Working Directory → (git add) → Staging Area → (git commit) → Repository.
  • הגדרה חד-פעמית: git config --global user.name / user.email.

דוקומנטציה רשמית