# GitHub, Remote and Push — and Good Commit Messages<no value>

## What will we learn?

- What **GitHub** is.
- What a **Remote** (a remote server) is and what **origin** is.
- How to **upload** code with **`git push`**.
- How to write good **Commit messages**.

## Why do we need this?

Until now the whole history is saved **only on your computer**. GitHub gives:

- **A cloud backup** — the laptop broke? The code is safe.
- **Sharing** — you send a link to the instructor, to teammates, to an employer.
- **A portfolio** — your GitHub profile is a developer's professional CV. Recruiters **really** look at it.
- **Teamwork** — the whole team syncs code through the same Repository.

From today, every project in the course (including the OOP projects and the integration project) goes up to GitHub.

## Explanation from the basics

### GitHub

**GitHub** is a website (and service) that hosts Git Repositories **on a server**. It is a **Server** in the sense we learned in the topic on the computer, the operating system and the network: your local Git is the **Client**, and it sends the Commits to GitHub over **HTTPS**.

(There are also similar services: GitLab and Bitbucket. The idea is the same.)

### Remote and origin

**Remote** = the address of **another copy** of the Repository that is somewhere else, usually on GitHub. A Remote is given a **nickname**, and by convention, the main Remote is called **`origin`**.

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

- **`git push`** — **sends** the local Commits that are not on the Remote yet.
- **`git pull`** — **downloads** new Commits from the Remote (when someone else pushed, or when you worked from another computer). We will not go into it deeply right now.
- **`git clone <url>`** — downloads an **existing** Repository from GitHub to the computer, including the whole history.

{{< box "analogy" "Analogy: a photo album and a cloud backup" >}}
The local Repository is the photo album on your phone. **`commit`** = taking a photo (saved on the phone). **`push`** = syncing to the cloud. If the phone is lost, the photos that were synced are safe, and those that were not are lost. So: **commit often, push at the end of every unit of work.**
{{< /box >}}

### Authentication

GitHub needs to know that you are allowed to push to the Repository. On Windows and Mac, on the first push a **sign-in window opens in the browser** (Git Credential Manager), you sign in once, and the system remembers. **GitHub does not accept the account password in the Terminal**. If you are asked for a "Password" in the Terminal, you need a **Personal Access Token** (we will see it in the common mistakes).

### Good Commit messages

| Rule | ✗ Not like this | ✓ Like this |
|---|---|---|
| **Imperative, present** ("what the Commit does") | `Added login` | `Add login form` |
| **Specific** | `fix bug` | `Fix crash when cart is empty` |
| **Short** (the first line up to ~50 characters) | `I changed the function that calculates the total because...` | `Apply VAT after discount in total` |
| **One logical change** | `Add login, fix typos, update colors` | Three separate Commits |
| **In English** (the industry convention) | | |

**Test:** complete the sentence "If applied, this commit will **___**". `Add login form` ✓. `Added login` ✗.

## Syntax

**Connecting an existing local Repository to GitHub and the first push:**

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

**After that, every time:**

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

**Helper commands:**

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

## First code example

**Uploading the `calculator` project from the previous lesson to GitHub, step by step:**

**Step 1 — an account.** Go to [github.com](https://github.com) → **Sign up**. A professional username (it will appear on your CV!). It is recommended to use the same email you set in `git config`.

**Step 2 — a new Repository.** On the website: **+** (at the top) → **New repository**:

- **Repository name:** `calculator`
- **Public** (visible to everyone) or **Private**.
- **Do not** check "Add a README", ".gitignore" or "license". We already have a local Repository, and we want to start with an **empty** Remote.
- **Create repository**.

**Step 3 — connecting and pushing.** GitHub shows the commands. From the `calculator` folder:

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

**Output:**

```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'.
```

**Step 4 — checking.** Refresh the Repository page on GitHub. The files are there! Click **Commits** to see the whole history, with the messages you wrote.

## Breaking down the code line by line

| Command | Explanation |
|---|---|
| `git remote add origin <url>` | "Register a Remote named `origin`, at this address". It only registers, and sends nothing. |
| `git branch -M main` | Makes sure the current branch is called `main`. (If you set `init.defaultBranch main`, it already is, and the command does no harm.) |
| `git push -u origin main` | **Sends** the branch `main` to `origin`. `-u` (upstream) sets the link between them, so that from now on `git push` is enough. |
| `Writing objects: 100%` | The Commits and the files are sent (in compressed form) to the server. |
| `* [new branch] main -> main` | The branch `main` was created on GitHub, with your history. |

## Another example

**A full work cycle after connecting** — a change, a Commit, a Push, and a check on the website:

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

In `calculator.py`:

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

**Output of `git push`:**

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

**Output of `git status` after the push:**

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

nothing to commit, working tree clean
```

**Breakdown:**

- `b81c0f4..e2f7a90` — the branch on GitHub "moved forward" from the previous Commit to the new one.
- `Your branch is up to date with 'origin/main'` — the local and the Remote are **in sync**. Before the push, `git status` would have written `Your branch is ahead of 'origin/main' by 1 commit`, that is, "you have a Commit that has not been uploaded yet".
- On the website, in `calculator.py`, you see the new function, and in the history `Add power function`.

### README.md — the project's business card

GitHub automatically shows the file `README.md` on the Repository's main page. Write one in every project:

```text
# Calculator

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

## How to run

    python main.py

## Functions

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

The file is written in **Markdown**: `#` = a heading, `-` = a list. And then: `git add README.md`, `git commit -m "Add README"`, `git push`.

## Common mistake

**Mistake 1: GitHub asks for a password in the Terminal, and the password "doesn't work".**

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

GitHub does not accept an account password in the Terminal. The recommended solution: Git for Windows and Mac come with **Git Credential Manager**, which opens a sign-in window in the browser. If it does not open, create a **Personal Access Token**: on the website → Settings → Developer settings → Personal access tokens. Paste the Token instead of the password.

**Mistake 2: a Remote created with a README, and a push that is rejected.**

```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.
```

You checked "Add a README" when creating the Repository on the website, so GitHub has a Commit that you do not have. The simplest solution at this stage: delete the Repository on the website (Settings → Delete) and create it again **empty**. (The "real" solution is `git pull`, which we have not learned in depth yet.)

**Mistake 3: `remote origin already exists`.**

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

You already added a Remote with this name (maybe with a wrong address). Check with `git remote -v`, and fix it: `git remote set-url origin <correct-url>`.

**Mistake 4: pushing secrets.** A file with a password or an API key that was pushed to a **public** Repository is considered **leaked**, even if you delete it in the next Commit, because it stays in the history. Bots scan GitHub and find keys within minutes. **`.gitignore` before the first Commit**, and secrets never in the code.

**Mistake 5: a Commit without a Push.** "I made a Commit, so it is on GitHub". No! A Commit is local only, and only `push` uploads.

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## Practice

The exercises use only what was taught in this lesson and the lessons before it. Try on your own first, and only then open the solution.

### Exercise 1: Connecting to GitHub

You created an empty Repository on GitHub at the address `https://github.com/dana-cohen/calculator.git`. The computer already has a local Repository with Commits. Write the commands that connect it to GitHub and upload the code for the first time.

{{< 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 ...` — sets the Repository on GitHub as a **Remote** named `origin`.
- `git branch -M main` — names the main branch `main`.
- `git push -u origin main` — uploads the Commits. `-u` remembers the connection, and from the next time `git push` is enough.
{{< /solution >}}

### Exercise 2: Local versus Remote

Dana made three Commits on her computer, but did not run `git push`. A friend opens the Repository on GitHub.

1. Do they see the three Commits?
2. Dana's computer broke before she ran push. What was lost?

{{< solution >}}
1. **No.** A Commit is saved only in the **local** Repository. GitHub is updated only after `git push`.
2. The three Commits **were lost** — they were only on the computer. That is exactly the reason for push: a **backup** outside the computer, and sharing with others.
{{< /solution >}}

### Exercise 3: push, clone and remote

Match each command to what it does:

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

(a) Downloads an existing Repository from GitHub to a new computer. (b) Sets where to upload to. (c) Uploads Commits to GitHub.

{{< solution >}}
| Command | What it does |
|---|---|
| `git push` | (c) — uploads the local Commits to the Remote |
| `git clone <url>` | (a) — downloads a full copy of a Repository, including the whole history |
| `git remote add origin <url>` | (b) — sets the Remote, once per Repository |
{{< /solution >}}

### Exercise 4: Good Commit messages

For each message — good or not? If not, write a good version.

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

{{< solution >}}
| Message | Good? | A good version |
|---|---|---|
| `fix` | No — it does not say what was fixed | `Fix rounding in VAT calculation` |
| `Add divide function to calculator` | **Yes** | — |
| `changes` | No — every Commit is "changes" | `Update README with run instructions` |
| `asdf` | No — meaningless | `Add input validation for age` |
| `Fix crash when dividing by zero` | **Yes** | — |

A good message: **a short sentence, in the imperative, that describes what the change does**.
{{< /solution >}}

### Exercise 5: The daily routine

You added a function `power` to the project. Put the commands in the right order:

```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` — see what changed.
2. `git add` — choose what goes in.
3. `git commit` — save a local snapshot.
4. `git push` — upload to GitHub.

This is the cycle of every working day.
{{< /solution >}}

<!-- exercises:end -->

## Summary

- **GitHub** = a server that hosts Repositories in the cloud. The local Git talks to it over HTTPS.
- **Remote** = a remote copy. **origin** = the accepted nickname for the main one.
- First connection: `git remote add origin <url>` → `git push -u origin main`. After that: `git push`.
- **Commit = local. Push = to the cloud.** `git status` shows whether you are "ahead" of the Remote.
- A Commit message: imperative, specific, short, one change, in English. "If applied, this commit will ___".
- Secrets are never pushed. `.gitignore` before the first Commit.

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

## Official documentation

- [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)
- [git push](https://git-scm.com/docs/git-push)
- [GitHub Docs — About READMEs](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes)

<!-- docs:end -->
