Git Basics for Java Projects

Naveen AnamaneniUpdated · 7 min read

Imagine writing a school project report where every time you finish a section, a photocopier quietly saves a copy, labeled with the date and a note such as "added the conclusion". If you ruin a paragraph next week, you pull out last Tuesday's copy. If a friend wants to try a different ending, they work on their own copy and you combine the best parts later. Git is that photocopier for code. Every professional Java team uses it, and every interview expects you to know the basics. In this lesson, you will learn Git's three areas, set up a Java project with a proper .gitignore, and walk through a real session: commits, a branch, a diff and a merge.

What Is Git?

Git is a version control system: a tool that is used to record snapshots of a project over time, so you can see what changed, when and why, go back to any earlier version, and work on several changes in parallel on branches. Services such as GitHub, GitLab and Bitbucket host Git repositories online so teams can share them.

TermMeaning
Repository (repo)The project plus its full history, stored in a hidden .git folder
CommitA saved snapshot with a message, an author and a unique id (hash)
BranchA movable label for a line of work; main is the usual default
MergeCombining the changes from one branch into another
RemoteA copy of the repository on another computer, such as GitHub (origin)

The Three Areas

Working directory, staging area, repository
  1. You edit files in the working directory.
  2. git add puts the changes you choose into the staging area: the contents of the next commit.
  3. git commit saves the staged snapshot permanently in the repository.

The staging area lets you commit related changes together, even if you edited several unrelated things.

A .gitignore File for Java

Some files should never be committed: compiled .class files, build output, and IDE settings. They can be rebuilt, differ between computers, and cause pointless conflicts. List them in a .gitignore file at the project root:

.gitignore
# Compiled classes and build output
*.class
out/
target/
build/
 
# IDE and OS files
.idea/
*.iml
.vscode/
.DS_Store

target/ is Maven's output folder and build/ is Gradle's. Do commit the build files themselves (pom.xml, build.gradle) and the Maven or Gradle wrapper scripts.

A Real Session

Here is a real session for a small project with one source file, src/FeeReport.java, and an out/ folder with a compiled class.

Step 1: create the repository and look at its status.

Terminal
git init
git status
Terminal output
Initialized empty Git repository in ~/fee-report/.git/
On branch main
 
No commits yet
 
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .DS_Store
        out/
        src/
 
nothing added to commit but untracked files present (use "git add" to track)

Git sees the compiled out/ folder and the macOS .DS_Store file. After adding the .gitignore above, they disappear:

Terminal
git status --short
Terminal output
?? .gitignore
?? src/

Step 2: stage and commit.

Terminal
git add .
git commit -m "Add fee report skeleton"
Terminal output
[main (root-commit) b6b4bd4] Add fee report skeleton
 2 files changed, 16 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 src/FeeReport.java

Step 3: start a branch for a new feature, change the code, and look at the difference.

Terminal
git switch -c late-fine
git diff
Terminal output
Switched to a new branch 'late-fine'
diff --git a/src/FeeReport.java b/src/FeeReport.java
index c3c26b5..db2cdfc 100644
--- a/src/FeeReport.java
+++ b/src/FeeReport.java
@@ -1,5 +1,6 @@
 public class FeeReport {
     public static void main(String[] args) {
         System.out.println("Fee report");
+        System.out.println("Late fine: 500 per day");
     }
 }

Step 4: commit on the branch, then merge it into main.

Terminal
git commit -am "Show the late fine"
git switch main
git merge late-fine
git log --oneline
Terminal output
[late-fine 86ed860] Show the late fine
 1 file changed, 1 insertion(+)
Switched to branch 'main'
Updating b6b4bd4..86ed860
Fast-forward
 src/FeeReport.java | 1 +
 1 file changed, 1 insertion(+)
86ed860 Show the late fine
b6b4bd4 Add fee report skeleton

Explanation:

  1. git init created the hidden .git folder. The branch is called main.
  2. git add . staged everything not ignored, and git commit -m saved it with id b6b4bd4 (yours will differ).
  3. git switch -c late-fine created a branch and moved to it. git diff showed the new line with a +.
  4. git commit -am staged and committed the changed tracked file in one step.
  5. Because main hadn't moved since the branch started, the merge was a fast-forward: main simply moved up to the branch's commit.

Everyday Commands

CommandDescription
git statusIt is used to see what has changed and what is staged.
git add file / git add .It stages one file, or all changes.
git commit -m "message"It saves the staged changes as a commit.
git log --onelineIt lists commits, one per line.
git diff / git diff --stagedIt shows unstaged, or staged, changes.
git switch -c name / git switch nameIt creates a branch, or moves to one.
git merge nameIt merges a branch into the current one.
git restore fileIt throws away uncommitted changes to a file.
git clone urlIt copies a remote repository to your computer.
git pull / git pushIt brings in, or sends out, commits from or to the remote.

Good Commit Habits

  • One logical change per commit: "Add late fine", not "Changes".
  • Write the message in the imperative: "Fix rounding in average", as if completing "This commit will...".
  • Commit working code: it should compile and pass tests.
  • Never commit secrets such as passwords, API keys or database URLs with passwords. Use environment variables or ignored config files.
  • Pull before you push, and keep branches short-lived so merges stay small.

Common Mistakes

Committing .class files or target/. They bloat the repository and conflict constantly. Add a .gitignore before the first commit.

Huge commits with mixed changes. Reviewers can't follow them, and undoing one change undoes all of them.

Working directly on main in a team. Use a branch and a pull request so changes can be reviewed.

Panicking at a merge conflict. Git marks the conflicting lines with <<<<<<<, ======= and >>>>>>>. Edit the file to the version you want, remove the markers, then git add and git commit.

Practice

  1. Easy: Create a repository for any program from an earlier lesson, add the Java .gitignore, and make three small commits. Check them with git log --oneline.
  2. Harder: Create two branches that change the same line of FeeReport.java differently. Merge the first into main, then the second, and resolve the conflict by hand.

Quick check: Git

4 questions
1What does git add do?
2Which files should a Java .gitignore exclude?
3What is a fast-forward merge?
4A password was committed and pushed. What now?

Key Takeaways

Was this tutorial helpful?

Lesson 535 of 578