Quiz: Version Control with Git

Test your understanding before moving on. Target: 70% or higher to proceed confidently.


Section 1: Multiple Choice (1 point each)

1. What does git init do?

  • A) Downloads a repository from GitHub
  • B) Creates a new empty Git repository in the current directory
  • C) Installs Git on your computer
  • D) Creates a new branch called init
Answer **B)** Creates a new empty Git repository in the current directory *Why B:* `git init` creates the hidden `.git` directory that stores all version control data, turning a regular directory into a Git repository. *Why not A:* That's `git clone`. *Why not C:* Git installation is done through a separate installer or package manager. *Why not D:* There is no relationship between `git init` and branch names. *Reference:* Section 25.3.1

2. What is the correct order of the basic Git workflow?

  • A) commit → add → push
  • B) add → commit → push
  • C) push → add → commit
  • D) commit → push → add
Answer **B)** add → commit → push *Why B:* You first stage changes with `git add`, then record them permanently with `git commit`, then share them with `git push`. *Why not A:* You must stage before committing. *Why not C:* Push comes last — it uploads existing commits. *Why not D:* You can't push commits that haven't been created yet. *Reference:* Section 25.3.3, 25.7

3. What does the staging area allow you to do?

  • A) Run Python code before saving it
  • B) Select exactly which changes to include in the next commit
  • C) Preview what your code will look like on GitHub
  • D) Automatically fix merge conflicts
Answer **B)** Select exactly which changes to include in the next commit *Why B:* The staging area (index) sits between your working directory and the repository, letting you choose which changes go into each commit. *Why not A:* The staging area has nothing to do with running code. *Why not C:* Previewing GitHub appearance is not related to staging. *Why not D:* Merge conflicts must be resolved manually. *Reference:* Section 25.4

4. You've modified three files but only want to commit changes to app.py. Which command do you use?

  • A) git commit -m "update" app.py
  • B) git add . && git commit -m "update"
  • C) git add app.py && git commit -m "update"
  • D) git commit --only app.py -m "update"
Answer **C)** `git add app.py && git commit -m "update"` *Why C:* You stage only the file you want (`git add app.py`) and then commit. Only staged changes are included. *Why not A:* `git commit` doesn't take filenames after the message this way (without the add step, the changes aren't staged). *Why not B:* `git add .` stages ALL modified files, including the ones you don't want. *Why not D:* `--only` is not a standard `git commit` flag for this purpose. *Reference:* Section 25.4.2

5. What does git switch -c new-feature do?

  • A) Switches to an existing branch called new-feature
  • B) Creates a new branch called new-feature and switches to it
  • C) Creates a new commit called new-feature
  • D) Copies all files to a new directory called new-feature
Answer **B)** Creates a new branch called `new-feature` and switches to it *Why B:* The `-c` flag means "create." `git switch -c new-feature` combines `git branch new-feature` and `git switch new-feature` into one command. *Why not A:* Without `-c`, `git switch new-feature` would switch to an existing branch (and fail if it doesn't exist). *Why not C:* Branches and commits are different concepts. *Why not D:* Branches don't create directories. *Reference:* Section 25.5.2

6. When does a merge conflict occur?

  • A) Whenever you merge any two branches
  • B) When two branches modify the same lines in the same file
  • C) When you forget to use git add before merging
  • D) When the remote repository is out of date
Answer **B)** When two branches modify the same lines in the same file *Why B:* Git can automatically merge changes to different files or different parts of the same file. It only needs human help when both branches changed the exact same lines. *Why not A:* Most merges succeed automatically without conflicts. *Why not C:* `git add` is not required before merging; you merge entire branches. *Why not D:* Remote status doesn't directly cause merge conflicts during a local merge. *Reference:* Section 25.6.3

7. What are the three conflict markers Git places in a file during a merge conflict?

  • A) <<<, ===, >>>
  • B) <<<<<<< HEAD, =======, >>>>>>> branch-name
  • C) CONFLICT START, DIVIDER, CONFLICT END
  • D) {{{, |||, }}}
Answer **B)** `<<<<<<< HEAD`, `=======`, `>>>>>>> branch-name` *Why B:* Git uses seven characters each (`<<<<<<<`, `=======`, `>>>>>>>`) followed by the branch names to clearly mark the conflicting versions. *Why not A, C, D:* These are not the markers Git uses. *Reference:* Section 25.6.3

8. What does git clone do?

  • A) Creates a new empty repository
  • B) Copies a remote repository to your local machine, including all history
  • C) Makes a copy of a single file from another branch
  • D) Creates a branch that's a copy of main
Answer **B)** Copies a remote repository to your local machine, including all history *Why B:* `git clone` downloads the entire repository (all branches, all commits, all history) and sets up the remote tracking automatically. *Why not A:* That's `git init`. *Why not C:* Cloning operates on entire repositories, not individual files. *Why not D:* That's closer to `git branch`, but still not what `git clone` does. *Reference:* Section 25.7.4

9. Which file should NEVER be committed to a Git repository?

  • A) README.md
  • B) .gitignore
  • C) .env containing API keys
  • D) requirements.txt
Answer **C)** `.env` containing API keys *Why C:* Files containing secrets (API keys, passwords, tokens) should never be committed. Once pushed, secrets are exposed in the repository's history even if later deleted. *Why not A:* READMEs should always be committed — they document the project. *Why not B:* `.gitignore` should be committed so all contributors ignore the same files. *Why not D:* `requirements.txt` should be committed so others can install dependencies. *Reference:* Section 25.8, 25.9.5

10. What is a "fast-forward" merge?

  • A) A merge that skips the staging area
  • B) A merge where the target branch has no new commits since the feature branched off, so Git just moves the pointer forward
  • C) A merge that automatically resolves all conflicts
  • D) A merge that happens instantly without downloading changes
Answer **B)** A merge where the target branch has no new commits since the feature branched off, so Git just moves the pointer forward *Why B:* When `main` hasn't changed since the feature branch was created, Git can simply fast-forward the `main` pointer to the latest feature commit. No merge commit is needed. *Why not A:* Fast-forward merges have nothing to do with the staging area. *Why not C:* Fast-forward merges don't involve conflicts because only one branch has new work. *Why not D:* Speed of execution isn't what "fast-forward" refers to. *Reference:* Section 25.6.1

Section 2: Short Answer (2 points each)

11. Explain the difference between git add and git commit in your own words. Why are they two separate steps instead of one?

Answer `git add` moves changes to the staging area — it selects which changes you want to include. `git commit` takes a snapshot of everything in the staging area and records it permanently in the repository history. They're separate because you often want to commit only some of your changes. If you fixed a bug in one file and started a new feature in another, you can stage and commit the bug fix alone, then stage and commit the new feature separately. This creates a clean, meaningful history. *Reference:* Section 25.4

12. You run git status and see the following output. Explain what each section means.

On branch main
Changes to be committed:
        modified:   storage.py

Changes not staged for commit:
        modified:   display.py

Untracked files:
        new_feature.py
Answer - **"Changes to be committed: modified: storage.py"** — `storage.py` has been modified and staged with `git add`. It will be included in the next commit. - **"Changes not staged for commit: modified: display.py"** — `display.py` has been modified but NOT staged. It will NOT be included in the next commit unless you run `git add display.py`. - **"Untracked files: new_feature.py"** — `new_feature.py` is a new file that Git has never seen before. Git isn't tracking it at all. You need to `git add` it to start tracking. *Reference:* Section 25.3, 25.4

13. What is the purpose of a .gitignore file? Give three examples of files or directories that should typically be ignored in a Python project, and explain why.

Answer A `.gitignore` file tells Git which files and directories to not track. Any file matching a pattern in `.gitignore` won't appear in `git status` and won't be accidentally committed. Three examples: 1. **`__pycache__/`** — contains compiled bytecode files that Python generates automatically. They're machine-specific and regenerated every time you run the code. 2. **`venv/`** — virtual environment directories contain installed packages and Python binaries that are large, machine-specific, and reproducible from `requirements.txt`. 3. **`.env`** — contains environment variables like API keys and database passwords. Committing secrets is a serious security risk. *Reference:* Section 25.8

14. Explain the difference between a fork and a clone. When would you use each?

Answer - A **clone** (`git clone`) creates a local copy of a repository on your computer. You clone when you want to work on a project locally — either your own repo or someone else's that you have access to. - A **fork** is a server-side copy of someone else's repository into your own GitHub account. You fork when you want to contribute to a project you don't have write access to. After forking, you clone your fork, make changes, and submit a pull request to propose your changes back to the original. Use **clone** when you have write access to the repo (your own project, or a team project). Use **fork + clone** when contributing to someone else's project (especially open source). *Reference:* Section 25.7.4, 25.7.5

Section 3: Scenario Questions (3 points each)

15. Elena and Marcus are both working on the same project. Elena pushes changes to main on GitHub. Marcus, unaware of Elena's push, also has new commits on his local main. When Marcus runs git push, it's rejected. What should Marcus do to resolve this situation?

Answer Marcus should run `git pull` first to download Elena's changes and merge them with his local commits. If there are no conflicts (they changed different files or different parts of the same file), Git will merge automatically and Marcus can then `git push` successfully. If there are conflicts, Marcus will need to resolve them manually (edit the conflicted files, remove the conflict markers, choose the correct code), then `git add` the resolved files, `git commit` to complete the merge, and finally `git push`. The key principle: always `git pull` before `git push` when collaborating. *Reference:* Section 25.7.3, 25.9.4

16. You're working on a feature branch called new-search. Halfway through, you realize your main branch has a critical bug that needs fixing immediately. Describe the steps you'd take to fix the bug without losing your feature work.

Answer 1. **Commit (or stash) your current work** on `new-search` so nothing is lost: ```bash git add . git commit -m "WIP: search feature in progress" ``` 2. **Switch to `main`:** ```bash git switch main ``` 3. **Create a hotfix branch:** ```bash git switch -c fix-critical-bug ``` 4. **Fix the bug, commit:** ```bash git add git commit -m "Fix critical bug in ..." ``` 5. **Merge the fix into `main`:** ```bash git switch main git merge fix-critical-bug ``` 6. **Go back to your feature:** ```bash git switch new-search ``` Your feature work is safe on its branch, and the bug is fixed on `main`. *Reference:* Section 25.5, 25.6

17. A teammate asks you to review the following .gitignore file for a Python web project. Identify any problems or missing entries.

# .gitignore
*.py
venv/
.env
Answer **Critical problem:** `*.py` ignores ALL Python files. This would prevent any Python source code from being committed, which defeats the entire purpose of version control. This line must be removed. (The teammate probably meant `*.pyc` to ignore compiled bytecode files.) **Missing entries that should be added:** - `__pycache__/` — compiled bytecode directories - `*.py[cod]` — compiled Python files (`.pyc`, `.pyo`, `.pyd`) - `.pytest_cache/` — if using pytest - `.coverage` and `htmlcov/` — if using coverage testing - IDE settings like `.vscode/` or `.idea/` - OS files like `.DS_Store` or `Thumbs.db` The corrected first line should be `*.pyc` (or `*.py[cod]`), not `*.py`. *Reference:* Section 25.8

Section 4: True or False (1 point each)

18. True or False: Deleting the .git directory from a project removes all version control history.

Answer **True.** The `.git` directory contains the entire history of the repository — every commit, every branch, all metadata. Deleting it turns the project back into a regular directory with no version control. This is irreversible (unless you have a remote copy on GitHub or another server). *Reference:* Section 25.3.1

19. True or False: Once you commit a file containing a password and push it to GitHub, adding the file to .gitignore will remove it from the repository's history.

Answer **False.** Adding a file to `.gitignore` only prevents *future* tracking. The file still exists in the commit history. Anyone with access to the repository can find it by looking at past commits. If you accidentally commit a secret, consider it compromised — change the password or rotate the API key immediately. *Reference:* Section 25.8, 25.9.5

20. True or False: You must have a GitHub account to use Git.

Answer **False.** Git is a local version control tool that works entirely on your own computer. You can `init`, `add`, `commit`, `branch`, and `merge` without ever connecting to the internet. GitHub (and GitLab, Bitbucket, etc.) are optional *remote hosting services* that add collaboration and backup capabilities, but Git itself doesn't require them. *Reference:* Section 25.1, 25.3, 25.7