Skip to content
Ameen Abozaid
PublishedBEG-046-L07

Demo: putting Bank Accounts under Git

  • Lesson 7 of 8
  • 10 min read
  • Beginner
On This Lesson 11 topics

Lesson Overview

This is a hands-on lesson. You will take an existing Java project, the Bank Accounts project you have been growing, and put it under Git from scratch, with a clean history. Along the way you will make one planned mistake on purpose, the most common mistake beginners make with Git, and fix it. Everything from lessons L02 to L06 comes together here, and the steps are the first half of the module lab (BEG-046-LAB1).

Your Bank Accounts folder will look different from the one below: your classes, packages, and IDE will differ. Follow the steps, not the exact file names. Menu names and folder names depend on your IDE and operating system, so commands here are given for a terminal. The demo uses a small version of the project with two classes. All commands were run in a scratch folder with Git 2.44 and JDK 21; your hashes will differ.

Learning Objectives

By the end of this lesson you will be able to:

  • Turn an existing project folder into a repository.
  • Recognise from git status when git add . is about to stage files that do not belong.
  • Undo an accidental staging before the first commit.
  • Create a .gitignore before the first commit and confirm it works.
  • Commit a project in small, meaningful steps with clear messages.
  • Review the result with git log --oneline, git ls-files, and git status.

Written Explanation

The starting point

Here is the demo project after you compiled it (your IDE may put compiled files elsewhere):

text
bank-accounts/
  src/
    Account.java
    Main.java
  out/              <- compiled .class files
  .idea/            <- IDE settings

Account.java has an owner, a balance, and getters. Main.java creates one account and prints it. Running it gives:

text
Sara: 100.0

A good first commit contains only the files a teammate needs to rebuild the project: the source. The out/ and .idea/ folders are generated by tools and must stay out.

Step 1: Initialise the repository

Open a terminal in the project's top folder and check you are in the right place (pwd, ls or dir; BEG-006):

bash
git init -b main
git status -s
text
Initialized empty Git repository in .../bank-accounts/.git/
?? .idea/
?? out/
?? src/

Three untracked folders. Two of them should never be committed.

Step 2: The planned mistake

Without a .gitignore, a beginner types the shortcut:

bash
git add .
git status -s
text
A  .idea/misc.xml
A  out/Account.class
A  out/Main.class
A  src/Account.java
A  src/Main.java

Look closely: compiled .class files and the IDE folder are now staged. This is exactly the habit lesson L06 warned about. Nothing has been committed yet, so it is easy to undo. This is why you read git status before you commit.

Step 3: Undo the staging

You might expect the usual unstaging command, git restore --staged .. In a repository that has no commits yet, it fails:

text
fatal: could not resolve HEAD

git restore --staged copies the staged files back from HEAD, the latest commit, and there is no commit yet. (The official page says --staged restores from HEAD by default; I found the failing message by running it.) In a repository with at least one commit, git restore --staged . is the right command. Before the first commit, use:

bash
git rm -r --cached .
git status -s
text
?? .idea/
?? out/
?? src/

--cached removes the files from the staging area only; your files on disk are untouched (lesson L06). Everything is untracked again.

Step 4: Create .gitignore first

Create a file named .gitignore in the top folder with these lines (use a text editor, or printf in a Bash-style terminal; the right way differs by shell):

text
*.class
out/
.idea/
.env
bash
git status -s
text
?? .gitignore
?? src/

out/ and .idea/ are gone from the list. The .env line costs nothing and protects you later. Adjust for your project: if your IDE writes compiled files to another folder, ignore that folder.

Step 5: Commit in small steps

Resist git add . even now, and name what you stage. First commit: the ignore file and the first class.

bash
git add .gitignore src/Account.java
git commit -m "Add Account class with owner and balance"
text
[main (root-commit) 833d77b] Add Account class with owner and balance
 2 files changed, 21 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 src/Account.java

Second commit: the program that uses it.

bash
git add src/Main.java
git commit -m "Add Main that creates one account"

Now you add deposit and withdraw to Account. Compile and run to be sure it works (javac -d out src/*.java, as in your earlier modules), then review before staging:

bash
git diff --stat
text
 src/Account.java | 8 ++++++++
 1 file changed, 8 insertions(+)
bash
git add src/Account.java
git commit -m "Add deposit and withdraw"

Step 6: Check the result

bash
git log --oneline
text
ab0fa5e Add deposit and withdraw
2948ea1 Add Main that creates one account
833d77b Add Account class with owner and balance
bash
git ls-files
text
.gitignore
src/Account.java
src/Main.java
bash
git status
text
On branch main
nothing to commit, working tree clean

Three commits, each with one purpose; only source and .gitignore tracked; nothing pending. That is the shape your lab history should have, with at least five commits for the full lab.

If a command fails with a message about your name or email, set them as in lesson L02 (git config --global user.name and user.email) and repeat the commit. If your own project already has a few classes, do not commit them all at once: group them by purpose, such as the model classes first and the Main wiring last, so that each commit still compiles on its own. That is easy to check and makes the history far more useful later.

What good looks like (checklist)

CheckCommand
No .class, out/, .idea/ trackedgit ls-files
Every message says what changedgit log --oneline
Nothing left uncommittedgit status
.gitignore is committedgit ls-files shows it

Examples

Example 1: The simplest safe start (simple)

For a brand-new project with one file:

bash
git init -b main
git add Hello.java
git commit -m "Add Hello program"

Naming the file instead of using . is a safe habit until you have a .gitignore.

Example 2: Good and bad histories of the same work (practical)

Bad: one commit, git commit -m "bank", with out/ and .idea/ inside. Good:

text
ab0fa5e Add deposit and withdraw
2948ea1 Add Main that creates one account
833d77b Add Account class with owner and balance

The second can be read like a story, and each step can be compared or undone separately. Both contain the same code; only one is useful.

Example 3: A new file arrives later (realistic)

A week later you add Customer.java. Because .gitignore already hides compiled files, git status -s shows just:

text
?? src/Customer.java

You stage it by name, commit "Add Customer class with name and email", and the history grows cleanly. A .gitignore is a one-time investment that keeps every later status short and honest.

Backend Insight

Every backend project starts like this: a folder, a first commit, an ignore file. The first commit sets the tone. If it holds build output and IDE settings, every teammate's git status is noisy and their IDE settings overwrite each other. A clean first commit also makes later reviews faster, since reviewers only read source.

The demo's discipline (status before add, naming files, small commits) is what teams call a clean history. When something fails in production, a reviewer, an auditor, or you in six months can read the story. Real projects also carry a README and build files, and you will add those in later modules; the rule remains: commit what a teammate needs to rebuild the project, and nothing generated.

Common Mistakes

Mistake 1: git add . before .gitignore

  • Incorrect: git init, git add ., git commit.
  • Correct: git init, create .gitignore, git status, then stage by name or with git add . once the status looks right.

Mistake 2: Using git restore --staged . before the first commit

It fails with fatal: could not resolve HEAD. Use git rm -r --cached . in a repository without commits.

Mistake 3: Running git init in the wrong folder

If you run it in your home folder or in a folder that holds many projects, Git tries to track everything there. Use pwd first, and run git init only in the project's top folder. If it happened, delete the .git folder in that place (and only that one) and start again.

Mistake 4: Putting everything in one first commit

A single "Initial commit" with everything is hard to review. Split by purpose, as in Step 5.

Exercises

Level A: Foundation

A1. Why is it risky to type git add . in a project that has no .gitignore?

Show solution A1

A1. It stages everything in the folder, including compiled files, IDE settings, and files with secrets, which then enter history.

A2. Which command shows which files are tracked?

Show solution A2

A2. git ls-files.

A3. Where must .gitignore live to apply to the whole project?

Show solution A3

A3. In the repository's top folder (it can also exist in subfolders for local rules).

Level B: Application

B1. Take any small Java project of yours. Put it under Git with a .gitignore and at least three commits. Write the commands you ran in order.

Show solution B1

B1. Example:

bash
git init -b main
# create .gitignore with *.class, out/, .idea/, .env
git add .gitignore src/Account.java
git commit -m "Add Account class"
git add src/Main.java
git commit -m "Add Main that uses Account"
git add src/Account.java
git commit -m "Add deposit and withdraw"

B2. You staged files with git add . before creating .gitignore and before the first commit. Write the commands to undo it, and explain why you cannot use git restore --staged ..

Show solution B2

B2. git rm -r --cached . removes everything from the staging area (the files stay on disk). git restore --staged . restores the index from HEAD, and a new repository has no HEAD yet, so it fails with fatal: could not resolve HEAD.

B3. Suggest three commit messages for adding an Account class, a Customer class, and a bug fix for a negative balance.

Show solution B3

B3. For example: Add Account class with owner and balance; Add Customer class with name and email; Fix negative balance after withdraw.

Level C: Challenge

C1. In the middle of the project you realise you committed out/Main.class in your second commit. Write the commands that stop tracking it and prevent it from returning. What remains in the second commit?

Show solution C1

C1.

bash
git rm --cached out/Main.class
# make sure .gitignore contains out/ or *.class
git add .gitignore
git commit -m "Stop tracking compiled output"

The second commit still contains the file; only later commits stop tracking it.

C2. A teammate's first commit is called "initial" and contains src/, out/, .idea/, and .env. Write a short review comment listing what to change, in order of importance.

Show solution C2

C2. First: remove .env from tracking and treat any password in it as leaked (change it). Then: remove out/ and .idea/ from tracking and add them to .gitignore. Then: split the history into commits that each have a purpose, and replace "initial" with messages that say what was added.

Mini Challenge

Put your own Bank Accounts project under Git, following the steps. Aim for at least four commits that tell a story, a committed .gitignore, and an empty git status at the end. Include the planned mistake: run git add . first, read git status, undo it, and write the ignore file. Save the output of git log --oneline and git ls-files in a text file.

Check your work: no .class files or IDE folders in git ls-files; each message begins with a verb; nothing is left uncommitted.

Summary & Next Lesson

Key takeaways

  • Create .gitignore before the first git add ., then check git status.
  • Before the first commit, undo staging with git rm -r --cached .; git restore --staged . needs a commit to restore from.
  • Stage by name when unsure; commit in small, labelled steps.
  • Review with git log --oneline, git ls-files, and git status.

Next lesson

Next is "Demo: creating and resolving a merge conflict", where you create a conflict in this same project on purpose and resolve it.

Self-check

  1. Why does git restore --staged . fail in a new repository?
  2. What does git rm -r --cached . do to your files on disk?
  3. What should exist before your first git add .?
  4. Which command lists the tracked files?
  5. What is a sign of a clean first history?
Show answers
  1. There is no HEAD commit yet to restore from.
  2. Nothing; it only removes them from the staging area.
  3. A .gitignore that excludes build output, IDE folders, and secrets.
  4. git ls-files.
  5. Small commits with clear messages, only source files tracked, and a clean git status.

References

  • Git documentation, git restore. It supports that --staged restores only the index, and that the source defaults to HEAD. It does not mention the no-commit case; the fatal: could not resolve HEAD failure was observed by running Git 2.44.
  • Pro Git book, "Recording Changes to the Repository". It supports git rm --cached keeping the file on disk and the role of .gitignore.
  • Git documentation, git init. It supports git init -b for the initial branch name.
  • The demo project, commands, and outputs were run in a scratch folder with Git 2.44 and JDK 21 (javac 21.0.10).

Practice

Apply this lesson with the module's lab, exercises and quiz.

Lab and exercises Quiz

Marking a lesson complete is optional and you can undo it any time. Your progress stays in this browser.

Continue to next lesson

Type to search levels, phases, modules and lessons.