# GitHub, Remote ו-Push — והודעות Commit טובות<no value>

## מה נלמד?

- מהו **GitHub**.
- מהו **Remote** (שרת מרוחק) ומה זה **origin**.
- איך **מעלים** קוד עם **`git push`**.
- איך כותבים **הודעות Commit** טובות.

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

עד עכשיו כל ההיסטוריה שמורה **רק אצלכם**. GitHub נותן:

- **גיבוי בענן** — הלפטופ נשבר? הקוד בטוח.
- **שיתוף** — שולחים קישור למרצה, לחברים לצוות, למעסיק.
- **תיק עבודות** — פרופיל ה-GitHub שלכם הוא קורות החיים המקצועיים של מפתח. מגייסים **באמת** מסתכלים עליו.
- **עבודת צוות** — כל הצוות מסנכרן קוד דרך אותו Repository.

מהיום, כל פרויקט בקורס (כולל הפרויקטים של נושא OOP ונושא פרויקט האינטגרציה) עולה ל-GitHub.

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

### GitHub

**GitHub** הוא אתר (ושירות) שמאחסן Repositories של Git **על שרת**. זה **Server** במובן שלמדנו בנושא מחשב, מערכת הפעלה ורשת: ה-Git המקומי שלכם הוא ה-**Client**, והוא שולח ל-GitHub את ה-Commits דרך **HTTPS**.

(יש גם שירותים דומים: GitLab ו-Bitbucket. הרעיון זהה.)

### Remote ו-origin

**Remote** = כתובת של **עותק נוסף** של ה-Repository שנמצא במקום אחר, בדרך כלל ב-GitHub. ל-Remote נותנים **כינוי**, ובמוסכמה, ה-Remote הראשי נקרא **`origin`**.

```text
Your computer                              GitHub
┌──────────────────────┐   git push    ┌──────────────────────┐
│ Local repository     │ ────────────► │ Remote repository    │
│ (.git, all commits)  │               │ "origin"             │
└──────────────────────┘ ◄──────────── └──────────────────────┘
                           git pull
```

- **`git push`** — **שולח** את ה-Commits המקומיים שעוד אין ב-Remote.
- **`git pull`** — **מוריד** Commits חדשים מה-Remote (כשמישהו אחר דחף, או כשעבדתם ממחשב אחר). לא נעמיק בזה כרגע.
- **`git clone <url>`** — מוריד Repository **קיים** מ-GitHub למחשב, כולל כל ההיסטוריה.

{{< box "analogy" "אנלוגיה: אלבום תמונות וגיבוי בענן" >}}
ה-Repository המקומי הוא אלבום התמונות בטלפון שלכם. **`commit`** = לצלם תמונה (נשמרת בטלפון). **`push`** = לסנכרן לענן. אם הטלפון אבד, התמונות שסונכרנו בטוחות, ואלה שלא סונכרנו אבדו. לכן: **commit לעיתים קרובות, push בסוף כל יחידת עבודה.**
{{< /box >}}

### אימות (Authentication)

GitHub צריך לדעת שאתם מורשים לדחוף ל-Repository. ב-Windows וב-Mac, בדחיפה הראשונה נפתח **חלון התחברות בדפדפן** (Git Credential Manager), מתחברים פעם אחת, והמערכת זוכרת. **GitHub לא מקבל את סיסמת החשבון ב-Terminal**. אם מבקשים "Password" ב-Terminal, צריך **Personal Access Token** (נראה בטעויות הנפוצות).

### הודעות Commit טובות

| כלל | ✗ לא כך | ✓ כך |
|---|---|---|
| **ציווי, הווה** ("מה ה-Commit עושה") | `Added login` | `Add login form` |
| **ספציפי** | `fix bug` | `Fix crash when cart is empty` |
| **קצר** (שורה ראשונה עד ~50 תווים) | `I changed the function that calculates the total because...` | `Apply VAT after discount in total` |
| **שינוי לוגי אחד** | `Add login, fix typos, update colors` | שלושה Commits נפרדים |
| **באנגלית** (מוסכמה בתעשייה) | | |

**מבחן:** השלימו את המשפט "If applied, this commit will **___**". `Add login form` ✓. `Added login` ✗.

## תחביר

**חיבור Repository מקומי קיים ל-GitHub ודחיפה ראשונה:**

```powershell
git remote add origin https://github.com/USERNAME/REPO-NAME.git
git branch -M main
git push -u origin main
```

**אחר כך, בכל פעם:**

```powershell
git add ...
git commit -m "..."
git push
```

**פקודות עזר:**

```powershell
git remote -v                  # show configured remotes
git clone https://github.com/USERNAME/REPO-NAME.git   # download an existing repo
```

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

**העלאת פרויקט `calculator` מהשיעור הקודם ל-GitHub, צעד אחר צעד:**

**צעד 1 — חשבון.** נכנסים ל-[github.com](https://github.com) → **Sign up**. שם משתמש מקצועי (הוא יופיע בקורות החיים!). מומלץ להשתמש באותו מייל שהגדרתם ב-`git config`.

**צעד 2 — Repository חדש.** באתר: **+** (למעלה) ‏←‏ **New repository**:

- **Repository name:** `calculator`
- **Public** (גלוי לכולם) או **Private**.
- **לא** לסמן "Add a README", ".gitignore" או "license". יש לנו כבר Repository מקומי, ונרצה להתחיל עם Remote **ריק**.
- **Create repository**.

**צעד 3 — חיבור ודחיפה.** GitHub מציג את הפקודות. מתוך התיקייה `calculator`:

```powershell
git remote add origin https://github.com/dana-cohen/calculator.git
git branch -M main
git push -u origin main
```

**פלט:**

```text
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 8 threads
Compressing objects: 100% (16/16), done.
Writing objects: 100% (18/18), 1.92 KiB | 1.92 MiB/s, done.
Total 18 (delta 4), reused 0 (delta 0), pack-reused 0
To https://github.com/dana-cohen/calculator.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.
```

**צעד 4 — בדיקה.** רעננו את דף ה-Repository ב-GitHub. הקבצים שם! לחצו על **Commits** כדי לראות את כל ההיסטוריה, עם ההודעות שכתבתם.

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

| פקודה | הסבר |
|---|---|
| `git remote add origin <url>` | "רשום Remote בשם `origin`, בכתובת הזו". רק רושם, ולא שולח כלום. |
| `git branch -M main` | מוודא שהענף הנוכחי נקרא `main`. (אם הגדרתם `init.defaultBranch main`, הוא כבר כזה, והפקודה לא מזיקה.) |
| `git push -u origin main` | **שולח** את הענף `main` ל-`origin`. `-u` (upstream) קובע את הקישור ביניהם, כך שמעכשיו מספיק `git push`. |
| `Writing objects: 100%` | ה-Commits והקבצים נשלחים (בצורה דחוסה) לשרת. |
| `* [new branch] main -> main` | נוצר ב-GitHub הענף `main`, עם ההיסטוריה שלכם. |

## דוגמה נוספת

**מחזור עבודה מלא אחרי החיבור** — שינוי, Commit, Push, ובדיקה באתר:

```powershell
git status
git add calculator.py
git commit -m "Add power function"
git push
git status
```

ב-`calculator.py`:

```python
def power(base, exponent):
    return base ** exponent
```

**פלט `git push`:**

```text
To https://github.com/dana-cohen/calculator.git
   b81c0f4..e2f7a90  main -> main
```

**פלט `git status` אחרי ה-push:**

```text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
```

**פירוק:**

- `b81c0f4..e2f7a90` — הענף ב-GitHub "התקדם" מה-Commit הקודם לחדש.
- `Your branch is up to date with 'origin/main'` — המקומי וה-Remote **מסונכרנים**. לפני ה-push, `git status` היה כותב `Your branch is ahead of 'origin/main' by 1 commit`, כלומר "יש לך Commit שעוד לא עלה".
- באתר, ב-`calculator.py`, רואים את הפונקציה החדשה, ובהיסטוריה את `Add power function`.

### README.md — כרטיס הביקור של הפרויקט

GitHub מציג אוטומטית את הקובץ `README.md` בעמוד הראשי של ה-Repository. כתבו אחד בכל פרויקט:

```text
# Calculator

A simple Python calculator - Kodkod 6 intro course, week 2.

## How to run

    python main.py

## Functions

- add, subtract, multiply, divide, power
```

הקובץ כתוב ב-**Markdown**: `#` = כותרת, `-` = רשימה. ואחר כך: `git add README.md`, `git commit -m "Add README"`, `git push`.

## טעות נפוצה

**הטעות 1: GitHub מבקש סיסמה ב-Terminal, והסיסמה "לא עובדת".**

```text
remote: Support for password authentication was removed on August 13, 2021.
fatal: Authentication failed for 'https://github.com/...'
```

GitHub לא מקבל סיסמת חשבון ב-Terminal. הפתרון המומלץ: Git for Windows ו-Mac מגיעים עם **Git Credential Manager**, שפותח חלון התחברות בדפדפן. אם הוא לא נפתח, יוצרים **Personal Access Token**: באתר ‏←‏ Settings ‏←‏ Developer settings ‏←‏ Personal access tokens. מדביקים את ה-Token במקום הסיסמה.

**הטעות 2: Remote שנוצר עם README, ו-push שנדחה.**

```text
! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/...'
hint: Updates were rejected because the remote contains work that you do not have locally.
```

סימנתם "Add a README" ביצירת ה-Repository באתר, ולכן ב-GitHub יש Commit שאין אצלכם. הפתרון הפשוט ביותר בשלב הזה: למחוק את ה-Repository באתר (Settings → Delete) וליצור אותו מחדש **ריק**. (הפתרון "האמיתי" הוא `git pull`, שעוד לא למדנו לעומק.)

**הטעות 3: `remote origin already exists`.**

```text
error: remote origin already exists.
```

כבר הוספתם Remote בשם הזה (אולי עם כתובת שגויה). בודקים עם `git remote -v`, ומתקנים: `git remote set-url origin <correct-url>`.

**הטעות 4: לדחוף סודות.** קובץ עם סיסמה או מפתח API שנדחף ל-Repository **ציבורי** נחשב **דלוף**, גם אם מוחקים אותו ב-Commit הבא, כי הוא נשאר בהיסטוריה. בוטים סורקים את GitHub ומוצאים מפתחות תוך דקות. **`.gitignore` לפני ה-Commit הראשון**, וסודות לעולם לא בקוד.

**הטעות 5: Commit בלי Push.** "עשיתי Commit, אז זה ב-GitHub". לא! Commit הוא מקומי בלבד, ורק `push` מעלה.

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

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

### תרגיל 1: חיבור ל-GitHub

יצרתם ב-GitHub Repository ריק בכתובת `https://github.com/dana-cohen/calculator.git`. במחשב כבר יש Repository מקומי עם Commits. כתבו את הפקודות שמחברות אותו ל-GitHub ומעלות את הקוד בפעם הראשונה.

{{< solution >}}
```powershell
git remote add origin https://github.com/dana-cohen/calculator.git
git branch -M main
git push -u origin main
```

- `git remote add origin ...` — מגדיר את ה-Repository ב-GitHub כ-**Remote** בשם `origin`.
- `git branch -M main` — קורא לענף הראשי `main`.
- `git push -u origin main` — מעלה את ה-Commits. `-u` זוכר את החיבור, ומהפעם הבאה מספיק `git push`.
{{< /solution >}}

### תרגיל 2: Local מול Remote

דנה ביצעה שלושה Commits במחשב שלה, אבל לא הריצה `git push`. חבר שלה פותח את ה-Repository ב-GitHub.

1. האם הוא רואה את שלושת ה-Commits?
2. המחשב של דנה התקלקל לפני שהריצה push. מה אבד?

{{< solution >}}
1. **לא.** Commit נשמר רק ב-Repository **המקומי**. GitHub מתעדכן רק אחרי `git push`.
2. שלושת ה-Commits **אבדו** — הם היו רק על המחשב. זו בדיוק הסיבה ל-push: **גיבוי** מחוץ למחשב, ושיתוף עם אחרים.
{{< /solution >}}

### תרגיל 3: push, clone ו-remote

התאימו כל פקודה למה שהיא עושה:

```text
git push
git clone <url>
git remote add origin <url>
```

(א) מוריד Repository קיים מ-GitHub למחשב חדש. (ב) מגדיר לאן להעלות. (ג) מעלה Commits ל-GitHub.

{{< solution >}}
| פקודה | מה היא עושה |
|---|---|
| `git push` | (ג) — מעלה את ה-Commits המקומיים ל-Remote |
| `git clone <url>` | (א) — מוריד עותק מלא של Repository, כולל כל ההיסטוריה |
| `git remote add origin <url>` | (ב) — מגדיר את ה-Remote, פעם אחת לכל Repository |
{{< /solution >}}

### תרגיל 4: הודעות Commit טובות

לכל הודעה — טובה או לא? אם לא, כתבו גרסה טובה.

```text
1. fix
2. Add divide function to calculator
3. changes
4. asdf
5. Fix crash when dividing by zero
```

{{< solution >}}
| הודעה | טובה? | גרסה טובה |
|---|---|---|
| `fix` | לא — לא אומרת מה תוקן | `Fix rounding in VAT calculation` |
| `Add divide function to calculator` | **כן** | — |
| `changes` | לא — כל Commit הוא "changes" | `Update README with run instructions` |
| `asdf` | לא — חסרת משמעות | `Add input validation for age` |
| `Fix crash when dividing by zero` | **כן** | — |

הודעה טובה: **משפט קצר, בציווי, שמתאר מה השינוי עושה**.
{{< /solution >}}

### תרגיל 5: העבודה השוטפת

הוספתם לפרויקט פונקציה `power`. סדרו את הפקודות לפי הסדר הנכון:

```text
git push
git commit -m "Add power function"
git status
git add calculator.py
```

{{< solution >}}
```powershell
git status
git add calculator.py
git commit -m "Add power function"
git push
```

1. `git status` — לראות מה השתנה.
2. `git add` — לבחור מה נכנס.
3. `git commit` — לשמור צילום מצב מקומי.
4. `git push` — להעלות ל-GitHub.

זה המחזור של כל יום עבודה.
{{< /solution >}}

<!-- exercises:end -->

## סיכום

- **GitHub** = שרת שמאחסן Repositories בענן. Git המקומי מדבר איתו ב-HTTPS.
- **Remote** = עותק מרוחק. **origin** = הכינוי המקובל לראשי.
- חיבור ראשון: `git remote add origin <url>` → `git push -u origin main`. אחר כך: `git push`.
- **Commit = מקומי. Push = לענן.** `git status` מראה אם אתם "ahead" של ה-Remote.
- הודעת Commit: ציווי, ספציפית, קצרה, שינוי אחד, באנגלית. "If applied, this commit will ___".
- סודות לעולם לא נדחפים. `.gitignore` לפני ה-Commit הראשון.

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

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

- [GitHub Docs — Creating an account](https://docs.github.com/en/get-started/start-your-journey/creating-an-account-on-github) — פתיחת חשבון
- [Pro Git — Working with Remotes](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) — remote ו-push
- [git push](https://git-scm.com/docs/git-push) — כל האפשרויות של git push
- [GitHub Docs — About READMEs](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes) — קובץ README טוב

<!-- docs:end -->
