In this chapter we will review:
- 040 - Fork Maintenance
- 041 - Complex Git Flows
- 042 - Ignoring Files
- 043 - Time Travel: Rewriting the Past
When you fork a repository, you create a snapshot of that project at that exact moment in time.
- However, open-source projects and team repositories move fast, your fork on GitHub and your local machine will fall behind.
To fix this, you must configure your local Git CLI to track the original repository.
In a forking workflow, your local machine needs to talk to two different remote servers:
origin: Your personal fork on GitHub (You have read & write access).upstream: The original repository you forked from (You have read-only access).
┌────────────────────────────────────────────────────────┐
│ Original Repository (upstream) │
└───────────────────────────┬────────────────────────────┘
│ (Fork via Web)
▼
┌────────────────────────────────────────────────────────┐
│ Your Personal Fork (origin) │
└───────────────────────────▲────────────────────────────┘
(Push changes)│ │ (Clone & Pull)
│ ▼
┌────────────────────────────────────────────────────────┐
│ Your Local Machine (CLI) │
└────────────────────────────────────────────────────────┘
Open your terminal inside your cloned repository. Let's check your current remote connections:
git remote -vYou will only see your own fork listed as origin.
Now, copy the HTTPS URL of the upstream repository and add it as your upstream remote:
git remote add upstream <PASTE-ORIGINAL-REPOSITORY-URL-HERE>Verify it again with git remote -v. You should now see both origin and upstream.
Whenever you want to update your computer with the latest changes made in the Upstream repo, run this sequence in your terminal:
- Switch to your local main branch:
git checkout main
- Download all metadata from the original project:
git fetch upstream
- Merge the original changes into your local main branch:
(Since you haven't touched your local main branch, this will usually be a clean, fast-forward merge).
git merge upstream/main
Right now, your local machine is perfectly updated, but your fork on GitHub (origin) is still old. Let's push the fresh code back to your personal GitHub page:
git push origin mainNow, if you visit your GitHub fork page in the browser, it will proudly say: "This branch is up to date with [original-owner]/main". You are ready to start a new feature!
GitHub Flow is intentionally easy to implement, which GitHub developers use themselves. However, large projects may require more complex approaches, such as Git Flow:
When you run git status, Git tracks every single change in your folder. However, certain files might never uploaded to GitHub:
- System junk: Cache files (like macOS
.DS_Storeor WindowsThumbs.db). - Dependencies: External packages and virtual environments (like
node_modules/or.venv/). - Large Data: Huge datasets (like
.csv,.json, or.sqlitefiles) that slow down Git. - Secrets: Configuration files containing passwords, API keys, or credentials (like
.env).
To tell Git to completely ignore these files, we use a special file named .gitignore.
filename.txt→ Ignores a specific file anywhere in the project.folder/→ Ignores a whole directory and everything inside it.*.csv→ The asterisk is a wildcard. This ignores any file ending with.csv.# Comment→ Lines starting with#are ignored by Git and used for notes.
# Be sure to be placed under the repo's root path
touch .gitignoreNote: The dot at the beginning is mandatory. It tells the system it is a hidden configuration file.
Open the .gitignore file in VS Code and add the following lines:
# Ignore sensitive credential files
.env
# Ignore large data CSV files
*.csv
Let's verify that the CLI is successfully blocking unwanted files.
- Create a dummy data file and a dummy secret file:
echo "1,2,3,4" > dataset.csv echo "PASSWORD=1234" > .env
- Check the status via CLI:
git status
- Neither
dataset.csvnor.envwill appear in the "Untracked files" list! Git is completely blind to them, preventing you from accidentally staging or committing them.
Earlier, we learned how to use git commit --amend to fix the very last commit, but Git is more powerful than that.
The CLI gives you a surgical tool to rewrite history interactively:
git rebase -i HEAD~3This tells Git: "I want to interactively look at the last 3 commits".
Your terminal will open your default editor showing a list of your last 3 commits, with words like pick next to them.
What can you do here?
- Change
picktoreword: To change the commit message of an old commit. - Change
picktosquash: To merge that commit into the previous one. - Rearrange lines: To physically change the chronological order of your past commits.
- Keep your code, delete the last commit: If you want to undo the last commit but keep all the files you edited so you can change them, run:
git reset --soft HEAD~1
- Nuke everything: If you want to completely erase the last commit AND throw away all the code modifications you did (dangerous!), run:
git reset --hard HEAD~1
Imagine you ran a git reset --hard by mistake and lost a week of work. You think it's gone forever. It isn't.
Git keeps a secret diary of every single move your repository has ever made, even things you deleted. Run:
git reflogYou will see a list of every action (commit, checkout, reset). Locate the commit ID right before you made the mistake, and restore your project back to life:
git reset --hard <that-ghost-commit-id>