Git Gud

From zero to your first pull request.

01What you'll walk out with

  • A repo on your machine — cloned, not downloaded
  • Commits you wrote yourself — with messages that make sense
  • A branch pushed to GitHub — your name on it
  • A merged pull request — reviewed by the person next to you
  • A merge conflict you fixed — on purpose, calmly

02Setup check

Run these now. Raise a hand if anything errors.

git --version
java -version     # JDK 17 or newer
javac -version

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global core.editor "code --wait"  # if you use VS Code

The email should match your GitHub account.

03Why bother

Git is a save-point system for your work — and the only sane way for several people to write on the same project without overwriting each other.

  • No more final.html, final2.html, final_FINAL_v3.html
  • Every change is reversible and you can see who did what, when, and why
  • Try risky things safely on a branch, throw it away if it fails

04The only diagram that matters

Working directory
your edits
papers on your desk
Staging area
git add
the envelope you're filling
Repository
git commit
sealed and labeled
Remote
git push
the shared cabinet

git status tells you where everything currently sits. Run it after every command today.

05The demo repo: Booko

Just something to practice on — a tiny buko juice ordering app that runs in the terminal. Plain Java — no Maven, no Gradle, nothing to install beyond a JDK.

booko/
└── src/
    ├── Main.java           # menu loop
    ├── Drink.java
    └── BookingService.java
├── team.md                 # you'll add your name here
├── ISSUES.md               # mirrors the GitHub issues
└── .gitignore

Run it:

javac -d out src/*.java
java -cp out Main
Lab 1 · 15 min

Clone and commit

git clone https://github.com/JanDexter/booko.git
cd booko
git status
git log --oneline

Now open team.md, add a line with your name and your favorite place in Davao. Then:

git status        # look at this output
git diff
git add team.md
git status        # now look again — what moved?
git commit -m "Add <name> to team list"

06Writing a commit message

Finish this sentence: "This commit will…"

  • Add quantity prompt to the order — good
  • Reject delivery dates in the past — good
  • update — useless in three weeks
  • asdfgh — we've all done it

Imperative mood, under ~50 characters, one logical change per commit.

07Branches

A branch is just a movable label pointing at a commit. Creating one is instant and costs nothing.

main       A───B───C
                    \
feat/quantity        D───E   # your work, isolated

The rule: main always works. All new work happens on a branch.

git branch                    # where am I?
git switch -c feat/my-thing   # create and move
git switch main               # go back
Lab 2 · 13 min

Your own feature branch

Claim an issue on GitHub (comment "taking this"), then:

git switch main
git pull
git switch -c feat/<short-name>

# edit your files, save

git add .
git commit -m "Add quantity to booking"
git push -u origin feat/<short-name>

-u is only needed on the first push. After that, plain git push.

08Heads up: GitHub login

GitHub will not accept your account password from the terminal. When it asks for a password, it wants a personal access token.

  • GitHub → Settings → Developer settings
  • Personal access tokens → Tokens (classic) → Generate new
  • Tick the repo scope — copy it, it's shown once
  • Paste it as the password when the terminal prompts you

09Issues

An issue is a to-do item that lives in the repo instead of in someone's head. That's all it is.

  • A title, a description, a number — #1, #2, #3…
  • Anyone can open one — bug reports, feature ideas, questions
  • Claim one by commenting so two people don't do the same task
  • Write "Closes #3" in your PR — GitHub closes it automatically on merge

Our repo has six open issues, all labeled good first issue. Pick one.

Lab 3 · 10 min

Open a pull request

  • Refresh the repo on GitHub — click the "Compare & pull request" banner
  • Write a title and two lines — what changed, and why
  • Add "Closes #<your issue number>" — links the PR to the issue
  • Create pull request
  • Then review your neighbor's PR — open Files changed and leave one comment

A PR is a proposal, not a delivery. It's where the conversation happens before code reaches main.

09Merge conflicts

A conflict happens when two branches change the same lines of the same file. Git refuses to guess which one you meant.

<<<<<<< HEAD
String HEADER = "Booko — fresh buko, booked";
=======
String HEADER = "Booko — 20% off all buko!";
>>>>>>> origin/promo-banner

Top is yours, bottom is theirs. These are plain text. Delete the markers, keep the version the file should end up with, save.

Lab 4 · 16 min

Break it on purpose

git switch feat/<short-name>
git fetch origin
git merge origin/promo-banner   # this WILL conflict

Open src/Main.java, resolve the markers, then:

git add src/Main.java
git commit                       # message is pre-filled, just save
git push

A conflict is not an error. You did not break anything. If you panic: git merge --abort puts everything back.

10Undo, by situation

Throw away edits to a filegit restore <file>
Unstage something you addedgit restore --staged <file>
Fix the last commit messagegit commit --amend
Undo a commit already pushedgit revert <hash>
Bail out of a mergegit merge --abort
See what you didgit log --oneline --graph

11.gitignore

Some things must never reach a repo. List them once and Git stops seeing them.

out/
*.class           # compiled output, never commit this
.env              # API keys, passwords — the big one
*.log
.DS_Store
.idea/

A secret pushed once is a secret leaked forever. Rotating the key is the only real fix — deleting the commit is not enough.

12Your loop from now on

git switch main && git pull      # start from the latest
git switch -c feat/thing         # branch

# ... work ...

git add .
git commit -m "Do the thing (closes #3)"
git push -u origin feat/thing    # push

# open a PR, get it reviewed, merge

That's 90% of professional Git. Everything else is a lookup.

That's it

You now use Git.

Next things worth learning, in order:

  • git stash — park unfinished work
  • git rebase — tidy history before a PR
  • GitHub Actions — run checks on every push
  • learngitbranching.js.org — visual practice, genuinely good

Questions → open an issue on the workshop repo.