Lesson Wednesday

Have you noticed that our projects include a ton of files when we use Gradle? For instance, here's what our Ping Pong directory from previous lessons this week looks like after running $ gradle test:

ping-pong
├── build
│   ├── classes
│   │   ├── main
│   │   │   ├── App.class
│   │   │   └── PingPong.class
│   │   └── test
│   │       └── PingPongTest.class
│   ├── dependency-cache
│   ├── reports
│   │   └── tests
│   │       └── test
│   │           ├── classes
│   │           │   └── PingPongTest.html
│   │           ├── css
│   │           │   ├── base-style.css
│   │           │   └── style.css
│   │           ├── index.html
│   │           ├── js
│   │           │   └── report.js
│   │           └── packages
│   │               └── default-package.html
│   ├── test-results
│   │   └── test
│   │       ├── TEST-PingPongTest.xml
│   │       └── binary
│   │           ├── output.bin
│   │           ├── output.bin.idx
│   │           └── results.bin
│   └── tmp
│       ├── compileJava
│       └── compileTestJava
│           └── emptySourcePathRef
├── build.gradle
└── src
    ├── main
    │   └── java
    │       ├── App.java
    │       └── PingPong.java
    └── test
        └── java
            └── PingPongTest.java

Can you believe we only created 4 of those files ourselves?! These extra files clutter our projects' GitHub repos too. Take a look at this commit that was made after running $ gradle test.

gitignore-demo

There were 18 files with 819 additions in that single commit! That's a lot of extra content cluttering our repos. Thankfully, there are a several ways to keep our repos tidy.

$ gradle clean

First off, there's the $ gradle clean command. This command removes build and temporary files from the project directory. Running this command in the huge ping-pong directory from the example above results in this:

ping-pong
├── build.gradle
└── src
    ├── main
    │   └── java
    │       ├── App.java
    │       └── PingPong.java
    └── test
        └── java
            └── PingPongTest.java

$ gradle clean is great for tidying up projects during development. But we don't want to run $ gradle clean before every single commit we make.

Ignoring Files on Git

We can also tell Git to entirely ignore certain types of files for us! They will remain in your local project, but will not be tracked by Git or pushed to GitHub. This process looks a little different at Epicodus, versus on a personal machine. In this lesson, we'll address how to ignore files on both.

Ignoring Files in a Project (At Epicodus)

To ignore files in a project, create a file called .gitignore in the top level of the project directory. Within this file, include the following:

.gitignore
# Compiled source #
############
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
############
*.log

# OS generated files #
############
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Java and Gradle #
############
build/
.gradle/

This is essentially just a big list of the file types we're telling Git to ignore. Most of this file is taken directly from GitHub's recommended .gitignore configuration. Let's briefly address what each section is ignoring:

  • Compiled Source: This refers to compiled source code. We don't track compiled code because it's just the bytecode version of our source code. If someone cloned our project, they can simply compile our source code on their own machine. We don't need to include our copies of the compiled code.

  • Packages: Because Gradle locates and installs our dependencies' packages for us, we don't track them. Again, if someone cloned our project, the build.gradle file is all they need. With that information Gradle will locate and install all necessary dependencies and packages.

  • Logs and Databases: We ignore .log files because they generally contain records of events specific to particular instances of a program, not the program's source code. You may notice that GitHub's recommended .gitignore configuration includes .sql and .sqlite files in this section too. However, we'll use these files to create databases in weeks 3 and 4, so do not ignore them.

  • OS Generated Files: Hidden files created by operating systems. For instance, Macs have hidden files called .DS_Store, and Windows has Thumbs.db. We simply don't need these.

  • Java and Gradle: Take a look at the file tree at the beginning of this lesson. Almost all the extra content Gradle created was in the build directory. So, we ignore that entire directory. We also ignore the .gradle/ directory that contains additional temporary files.

You'll need to create a .gitignore file for each Java project you create at Epicodus.

Ignoring Files Globally (On Your Personal Machine)

On your personal machine, it's a little easier. You can set global .gitignore configurations, instead of creating a .gitignore file in every project.

To do this, create a file in your home directory called .gitignore_global. Place the same contents from the .gitignore file above within it.

Then, instruct Git to use these rules for all projects created on your computer:

$ git config --global core.excludesfile ~/.gitignore_global

You can later alter the contents of your .gitignore_global file, if necessary.

Removing Ignored Files from a Project

Sometimes you might forget to include a .gitignore file before committing. Or, maybe you forgot to include certain file types in .gitingore and accidentally committed files you want to ignore. Good news is, it's fairly easy to remove unwanted files using the following steps:

  1. Make a new .gitignore file if you don't have one. Or, update your existing .gitignore with additional file types.

  2. Commit the new/updated .gitignore file.

  3. Run the following command. It will locate previously-committed files that fall under one of your .gitignore categories, and stage them for removal:

$ git rm --cached -r .

Resulting in something like this:

$ git rm --cached -r .

rm '.gitignore'
rm '.gradle/3.0/taskArtifacts/cache.properties'
rm '.gradle/3.0/taskArtifacts/cache.properties.lock'
rm '.gradle/3.0/taskArtifacts/fileHashes.bin'
rm '.gradle/3.0/taskArtifacts/fileSnapshots.bin'
rm '.gradle/3.0/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin'
rm '.gradle/3.0/taskArtifacts/taskArtifacts.bin'
rm 'build.gradle'
rm 'build/classes/main/App.class'
rm 'build/classes/main/PingPong.class'
rm 'build/classes/test/PingPongTest.class'
rm 'build/reports/tests/test/classes/PingPongTest.html'
rm 'build/reports/tests/test/css/base-style.css'
rm 'build/reports/tests/test/css/style.css'
rm 'build/reports/tests/test/index.html'
rm 'build/reports/tests/test/js/report.js'
rm 'build/reports/tests/test/packages/default-package.html'
rm 'build/test-results/test/TEST-PingPongTest.xml'
rm 'build/test-results/test/binary/output.bin'
rm 'build/test-results/test/binary/output.bin.idx'
rm 'build/test-results/test/binary/results.bin'
rm 'src/main/java/App.java'
rm 'src/main/java/PingPong.java'
rm 'src/test/java/PingPongTest.java'

  1. Run $ git add . to stage these changes for commit.

  2. Run $ git status to see what files will be deleted and ignored in future commits. Confirm that the list it provides is correct.

$ git status

On branch 1.3_gitignore_demonstration
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    .gradle/3.0/taskArtifacts/cache.properties
    deleted:    .gradle/3.0/taskArtifacts/cache.properties.lock
    deleted:    .gradle/3.0/taskArtifacts/fileHashes.bin
    deleted:    .gradle/3.0/taskArtifacts/fileSnapshots.bin
    deleted:    .gradle/3.0/taskArtifacts/fileSnapshotsToTreeSnapshotsIndex.bin
    deleted:    .gradle/3.0/taskArtifacts/taskArtifacts.bin
    deleted:    build/classes/main/App.class
    deleted:    build/classes/main/PingPong.class
    deleted:    build/classes/test/PingPongTest.class
    deleted:    build/reports/tests/test/classes/PingPongTest.html
    deleted:    build/reports/tests/test/css/base-style.css
    deleted:    build/reports/tests/test/css/style.css
    deleted:    build/reports/tests/test/index.html
    deleted:    build/reports/tests/test/js/report.js
    deleted:    build/reports/tests/test/packages/default-package.html
    deleted:    build/test-results/test/TEST-PingPongTest.xml
    deleted:    build/test-results/test/binary/output.bin
    deleted:    build/test-results/test/binary/output.bin.idx
    deleted:    build/test-results/test/binary/results.bin
  1. Commit the changes. This will remove these files from your GitHub repo, like this. Thanks to your new .gitignore file, they will also be ignored in future commits.

For more information on $ git rm --cached -r . and similar commands, check out the Git documentation.

Overview


  • Gradle adds a ton of extra build and temporary files to our projects, which clutter our GitHub repos. Since they're not necessary to run the program, we can disclude them from our repos with a .gitignore file.

Example


.gitignore
# Compiled source #
############
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
############
*.log

# OS generated files #
############
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Java and Gradle #
############
build/
.gradle/

Additional Resources