From zero to your first pull request.
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.
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.
git status tells you where everything currently sits. Run it after every command today.
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
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"
Finish this sentence: "This commit will…"
Imperative mood, under ~50 characters, one logical change per commit.
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
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.
GitHub will not accept your account password from the terminal. When it asks for a password, it wants a personal access token.
repo scope — copy it, it's shown onceAn issue is a to-do item that lives in the repo instead of in someone's head. That's all it is.
Our repo has six open issues, all labeled good first issue. Pick one.
A PR is a proposal, not a delivery. It's where the conversation happens before code reaches main.
A conflict happens when two branches change the same lines of the same file. Git refuses to guess which one you meant.
Top is yours, bottom is theirs. These are plain text. Delete the markers, keep the version the file should end up with, save.
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.
| Throw away edits to a file | git restore <file> |
| Unstage something you added | git restore --staged <file> |
| Fix the last commit message | git commit --amend |
| Undo a commit already pushed | git revert <hash> |
| Bail out of a merge | git merge --abort |
| See what you did | git log --oneline --graph |
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.
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.
Next things worth learning, in order:
Questions → open an issue on the workshop repo.