# פקודות Git בסיסיות: init, status, add, commit, log<no value>

## מה נלמד?

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

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

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

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

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

## הסבר מהבסיס

### מחזור העבודה

```text
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 פשוט לא "רואה" קבצים שמתאימים להן.

## תחביר

```powershell
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:**

```text
# Python cache
__pycache__/
*.pyc

# Local data and logs
*.log
*.db

# Secrets and environments
.env
venv/

# OS files
.DS_Store
Thumbs.db
```

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

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

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

```powershell
mkdir calculator
cd calculator
git init
```

צרו את `calculator.py`:

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

ועכשיו:

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

**פלט:**

```text
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)
```

```text
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   calculator.py
```

```text
[main (root-commit) 4e7a1c2] Add calculator with add function
 1 file changed, 2 insertions(+)
 create mode 100644 calculator.py
```

```text
4e7a1c2 (HEAD -> main) Add calculator with add function
```

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

| פלט | משמעות |
|---|---|
| `On branch main` | אנחנו על הענף הראשי `main`. (ענפים הם נושא מתקדם, שלא נעסוק בו כרגע.) |
| `No commits yet` | ה-Repository חדש, ואין היסטוריה. |
| `Untracked files: calculator.py` | Git רואה קובץ חדש, אבל לא עוקב אחריו. |
| `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`:

```python
def subtract(a, b):
    return a - b
```

```powershell
git status
git diff
git add calculator.py
git commit -m "Add subtract function"
git log
```

**`git status`:**

```text
Changes not staged for commit:
        modified:   calculator.py
```

**`git diff`:**

```text
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`:**

```text
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:

```powershell
git restore --staged secrets.txt
```

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

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

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

```text
a1b2c3d fix
e4f5a6b stuff
c7d8e9f asdf
f0a1b2c final
```

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

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

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## תרגול

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

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

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

{{< solution >}}
```powershell
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**.
{{< /solution >}}

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

```text
Changes to be committed:
        modified:   calculator.py

Changes not staged for commit:
        modified:   README.md

Untracked files:
        notes.txt
```

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

{{< solution >}}
| קובץ | מצב | ב-Commit הבא? |
|---|---|---|
| `calculator.py` | השינוי ב-**Staging Area** | **כן** |
| `README.md` | שונה, אבל **לא** הוסף עם `git add` | לא |
| `notes.txt` | **Untracked** — Git לא עוקב אחריו בכלל | לא |

רק מה שנמצא ב-Staging Area נכנס ל-Commit.
{{< /solution >}}

### תרגיל 3: .gitignore

בפרויקט Python יש:

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

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

{{< solution >}}
```text
# Python cache
__pycache__/
*.pyc

# Passwords and keys
secrets.txt

# Logs
*.log
```

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

`main.py`, `calculator.py` ו-`README.md` הם הפרויקט עצמו — הם **כן** נכנסים.
{{< /solution >}}

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

```text
-def add(a, b):
-    return a - b
+def add(a, b):
+    return a + b
```

1. מה המשמעות של השורות שמתחילות ב-`-` ו-`+`?
2. מה השינוי בפועל, ואיזו הודעת Commit מתאימה לו?

{{< solution >}}
1. **`-`** — שורה שהייתה ונמחקה. **`+`** — שורה חדשה שנוספה.
2. הפונקציה `add` החסירה במקום לחבר, והשינוי מתקן את זה. הודעה מתאימה: `Fix add returning a - b`.

`git diff` מראה מה השתנה **לפני** `git add` — כדאי להריץ אותו לפני כל Commit, כדי לוודא שנכנס רק מה שהתכוונתם.
{{< /solution >}}

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

```text
e91d5aa Fix VAT rounding
7b2e004 Add price calculator
a3f9c21 Initial project
```

1. איזו פקודה מציגה את ההיסטוריה בשורה אחת לכל Commit?
2. מה ה-Commit הישן ביותר, ומה האחרון?
3. הוסיפו את הפונקציה `multiply` ואחר כך את `divide`. כמה Commits הייתם עושים, ולמה?

{{< solution >}}
1. `git log --oneline`.
2. הישן ביותר: `a3f9c21 Initial project` (למטה). האחרון: `e91d5aa Fix VAT rounding` (למעלה).
3. **שני Commits** — אחד לכל פונקציה: `Add multiply` ואחר כך `Add divide`. כך כל Commit הוא שינוי אחד, וההיסטוריה מספרת סיפור ברור. אם `divide` תתגלה כבעייתית, קל לראות בדיוק מתי ומה נוסף.
{{< /solution >}}

<!-- exercises:end -->

## סיכום

- מחזור: **עריכה ‏←‏ `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 בעצמו.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

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

- [Pro Git — Getting a Git Repository](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository) — git init
- [Pro Git — Recording Changes](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) — status, add ו-commit
- [Pro Git — Viewing the Commit History](https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History) — git log

<!-- docs:end -->
