פקודות Git בסיסיות: init, status, add, commit, log

מטרות השיעור
  • ליצור Repository ולבצע את מחזור העבודה — עריכה, add, commit
  • לקרוא ולהבין את הפלט של git status בכל מצב
  • לצפות בהיסטוריה עם git log ובשינויים עם git diff
  • להגדיר .gitignore לקבצים שלא אמורים להיכנס ל-Repository

מה נלמד?

מחזור העבודה היומיומי עם Git, פקודה אחר פקודה:

פקודהמה היא עושה
git initיוצרת Repository
git statusמה המצב עכשיו?
git addמכניסה שינויים ל-Staging
git commitשומרת תמונת מצב בהיסטוריה
git logמציגה את ההיסטוריה
git diffמציגה מה השתנה

ובנוסף: .gitignore, איך אומרים ל-Git “תתעלם מאלה”.

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

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

הסבר מהבסיס

מחזור העבודה

1. edit files          (Working Directory changes)
2. git status          (see what changed)
3. git add <files>     (choose what goes into the snapshot)
4. git commit -m "..." (save the snapshot)
5. repeat

git status — הפקודה הכי חשובה

git status לא משנה כלום. היא רק מספרת את המצב: מה Untracked, מה Modified, מה Staged. כלל זהב: לפני כל add ולפני כל commit, מריצים git status.

הודעת Commit

ההודעה מסבירה מה השתנה ולמה, בשביל מי שיקרא את ההיסטוריה (כולל אתם בעוד חודש). נעמיק בכללים בשיעור הבא. בינתיים: משפט קצר באנגלית, בציווי: "Add discount calculation", "Fix crash on empty cart".

.gitignore

לא כל קובץ צריך להיכנס ל-Repository:

  • קבצים שנוצרים אוטומטית: __pycache__/, *.pyc.
  • מידע אישי או סודי: סיסמאות, מפתחות API, קבצי .env. אסור שיגיעו ל-GitHub!
  • קבצי עבודה מקומיים: לוגים (*.log), Database מקומי, סביבות וירטואליות (venv/, נכיר בנושא Backend ומסדי נתונים).
  • קבצי מערכת: .DS_Store (מק), Thumbs.db (Windows).

קובץ בשם .gitignore בתיקיית הפרויקט מכיל תבניות (שורה לכל תבנית), ו-Git פשוט לא “רואה” קבצים שמתאימים להן.

תחביר

git init                          # create a repository in the current folder
git status                        # show the state of files
git add file.py                   # stage one file
git add folder/                   # stage everything in a folder
git add .                         # stage ALL changes in the current folder (check status first!)
git commit -m "Short message"     # commit staged changes with a message
git log                           # full history (press q to quit)
git log --oneline                 # compact history, one line per commit
git diff                          # changes NOT yet staged
git diff --staged                 # changes that ARE staged (will go into the commit)
git restore --staged file.py      # un-stage a file (keeps your edits)

.gitignore לדוגמה לפרויקט Python:

# Python cache
__pycache__/
*.pyc

# Local data and logs
*.log
*.db

# Secrets and environments
.env
venv/

# OS files
.DS_Store
Thumbs.db

# = הערה. * = “כל דבר”. שורה שמסתיימת ב-/ = תיקייה.

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

מחזור עבודה מלא, מאפס. בתוך kodkod6:

mkdir calculator
cd calculator
git init

צרו את calculator.py:

def add(a, b):
    return a + b

ועכשיו:

git status
git add calculator.py
git status
git commit -m "Add calculator with add function"
git log --oneline

פלט:

On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        calculator.py

nothing added to commit but untracked files present (use "git add" to track)
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   calculator.py
[main (root-commit) 4e7a1c2] Add calculator with add function
 1 file changed, 2 insertions(+)
 create mode 100644 calculator.py
4e7a1c2 (HEAD -> main) Add calculator with add function

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

פלטמשמעות
On branch mainאנחנו על הענף הראשי main. (ענפים הם נושא מתקדם, שלא נעסוק בו כרגע.)
No commits yetה-Repository חדש, ואין היסטוריה.
Untracked files: calculator.pyGit רואה קובץ חדש, אבל לא עוקב אחריו.
Changes to be committed: new fileאחרי add: הקובץ ב-Staging, ויכנס ל-Commit הבא.
[main (root-commit) 4e7a1c2]נוצר Commit. root-commit = הראשון בהיסטוריה. 4e7a1c2 = תחילת ה-Hash שלו.
1 file changed, 2 insertions(+)סיכום: קובץ אחד, 2 שורות נוספו.
(HEAD -> main)HEAD = “איפה אנחנו עכשיו”, ה-Commit האחרון בענף main.

שימו לב: git status מציע בעצמו מה לעשות (use "git add <file>..."). קראו את הרמזים שלו!

דוגמה נוספת

שינוי, diff, ו-Commit שני. הוסיפו ל-calculator.py:

def subtract(a, b):
    return a - b
git status
git diff
git add calculator.py
git commit -m "Add subtract function"
git log

git status:

Changes not staged for commit:
        modified:   calculator.py

git diff:

diff --git a/calculator.py b/calculator.py
--- a/calculator.py
+++ b/calculator.py
@@ -1,2 +1,6 @@
 def add(a, b):
     return a + b
+
+
+def subtract(a, b):
+    return a - b

git log:

commit 9d02b6f5e1a8c7d3b4f2e6a9c0d1e8b7f6a5c4d3 (HEAD -> main)
Author: Dana Cohen <dana@example.com>
Date:   Tue Oct 6 11:20:41 2026 +0300

    Add subtract function

commit 4e7a1c2b8f0d6e5a3c1b9d7f4e2a0c8b6d5f3e1a
Author: Dana Cohen <dana@example.com>
Date:   Tue Oct 6 11:05:12 2026 +0300

    Add calculator with add function

פירוק:

  • modified: — הקובץ מוכר ל-Git (היה ב-Commit), והשתנה.
  • ב-git diff, שורה שמתחילה ב-+ נוספה, שורה עם - נמחקה, ושורה עם רווח היא הקשר שלא השתנה. @@ -1,2 +1,6 @@ = “שורות 1–2 בגרסה הישנה הפכו לשורות 1–6 בחדשה”.
  • git log מציג מהחדש לישן: Hash מלא, מחבר, תאריך והודעה. יציאה מ-git log ארוך: המקש q.

ועכשיו .gitignore: הריצו את הקוד פעם אחת (python -c "import calculator"), ו-git status יראה את __pycache__/ כ-Untracked. צרו .gitignore עם __pycache__/, ו-git status כבר לא יציג אותה. אל תשכחו: git add .gitignore ו-Commit. הקובץ עצמו כן אמור להיות ב-Repository.

טעות נפוצה

הטעות 1: git add . בלי לבדוק status. add . מוסיף הכול, כולל קבצי לוג, __pycache__, וגרוע מכל, קבצים עם סיסמאות. קודם git status, קודם .gitignore, ורק אז add ..

ואם הוספתם משהו בטעות ל-Staging:

git restore --staged secrets.txt

הקובץ יוצא מה-Staging, והשינויים בו נשארים.

הטעות 2: Commit בלי -m. git commit לבד פותח עורך טקסט להודעה. אם לא הגדרתם core.editor, ייפתח לרוב Vim, עורך ש"קשה לצאת ממנו". אם נתקעתם ב-Vim: Esc, ואז מקלידים :q! ו-Enter (יציאה בלי שמירה), ואז מריצים שוב עם -m "...".

הטעות 3: הודעות חסרות משמעות.

a1b2c3d fix
e4f5a6b stuff
c7d8e9f asdf
f0a1b2c final

בעוד חודש, אף אחד לא יבין מה קרה בהיסטוריה הזו. כל Commit הוא “מכתב לעתיד”.

הטעות 4: להוסיף ל-.gitignore קובץ שכבר עשו לו Commit. .gitignore משפיע רק על קבצים ש-Git עוד לא עוקב אחריהם. אם app.log כבר ב-Repository, צריך גם להוציא אותו מהמעקב: git rm --cached app.log, ואז Commit.

תרגול

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

תרגיל 1: Commit ראשון

בתיקייה חדשה יש קובץ calculator.py. כתבו את רצף הפקודות שיוצר Repository, בודק את המצב, מוסיף את הקובץ ומבצע Commit ראשון עם הודעה מתאימה.

הצג פתרון
git init
git status
git add calculator.py
git commit -m "Add calculator with add and subtract"
git status
  • git init — יוצר Repository.
  • git status הראשון — מראה ש-calculator.py הוא Untracked.
  • git add — מעביר אותו ל-Staging Area.
  • git commit -m — שומר צילום מצב עם הודעה.
  • git status בסוף — מראה nothing to commit, working tree clean.

תרגיל 2: לקרוא את git status

Changes to be committed:
        modified:   calculator.py

Changes not staged for commit:
        modified:   README.md

Untracked files:
        notes.txt

לכל קובץ — באיזה מצב הוא, ומה יקרה לו אם תריצו עכשיו git commit -m "Update"?

הצג פתרון
קובץמצבב-Commit הבא?
calculator.pyהשינוי ב-Staging Areaכן
README.mdשונה, אבל לא הוסף עם git addלא
notes.txtUntracked — Git לא עוקב אחריו בכלללא

רק מה שנמצא ב-Staging Area נכנס ל-Commit.

תרגיל 3: .gitignore

בפרויקט Python יש:

main.py
calculator.py
__pycache__/
secrets.txt        (passwords)
app.log
README.md

כתבו קובץ .gitignore מתאים, והסבירו למה כל שורה בו.

הצג פתרון
# Python cache
__pycache__/
*.pyc

# Passwords and keys
secrets.txt

# Logs
*.log
  • __pycache__/ — קבצים ש-Python מייצרת אוטומטית. אין סיבה לשמור אותם.
  • secrets.txt — סיסמאות לא נכנסות ל-Git, לעולם. מה שנכנס להיסטוריה נשאר בה.
  • *.log — לוגים משתנים בכל הרצה ושייכים למחשב שעליו רצו.

main.py, calculator.py ו-README.md הם הפרויקט עצמו — הם כן נכנסים.

תרגיל 4: לקרוא git diff

-def add(a, b):
-    return a - b
+def add(a, b):
+    return a + b
  1. מה המשמעות של השורות שמתחילות ב-- ו-+?
  2. מה השינוי בפועל, ואיזו הודעת Commit מתאימה לו?
הצג פתרון
  1. - — שורה שהייתה ונמחקה. + — שורה חדשה שנוספה.
  2. הפונקציה add החסירה במקום לחבר, והשינוי מתקן את זה. הודעה מתאימה: Fix add returning a - b.

git diff מראה מה השתנה לפני git add — כדאי להריץ אותו לפני כל Commit, כדי לוודא שנכנס רק מה שהתכוונתם.

תרגיל 5: היסטוריה עם git log

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

סיכום

  • מחזור: עריכה ‏←‏ git status ‏←‏ git add ‏←‏ git commit -m "...".
  • git status = “מה המצב?”. מריצים אותה לפני כל פעולה, וקוראים את הרמזים שלה.
  • git log --oneline = היסטוריה. git diff = מה השתנה (--staged = מה ייכנס ל-Commit).
  • git add . רק אחרי status ו-.gitignore. git restore --staged מוציא מה-Staging.
  • .gitignore: __pycache__/, לוגים, .env, סודות. נכנס ל-Repository בעצמו.

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