Lesson Tuesday

Have you noticed that our projects include a ton of files when we use IntelliJ? For instance, here's what our Ping Pong directory from previous lessons this week looks like after running our tests. This is some of stuff inside our Ping Pong Directory, including hidden files, sorted by name, and then date:

-r--r--r--  1 epicodus_staff  staff  109 Jul 20 09:24 ./.git/objects/46/25b861f6663e9661307d58ebf89534a4dcd6dc
-r--r--r--  1 epicodus_staff  staff  115 Jul 20 09:24 ./.git/objects/00/b936f6f388e8b9b3c5a66e44c2069a0c8c2353
-r--r--r--  1 epicodus_staff  staff  116 Jul 20 08:44 ./.git/objects/26/09e809dfffb33985e20447752c43c35e7e1294
-r--r--r--  1 epicodus_staff  staff  116 Jul 20 09:24 ./.git/objects/1e/f1c9fea3a9f8010c51fe048470a3676d7c5605
-r--r--r--  1 epicodus_staff  staff  135 Jul 20 08:44 ./.git/objects/75/7fc49dc6d7b226e76ab84bb64d29be70c271fb
-r--r--r--  1 epicodus_staff  staff  139 Jul 20 08:44 ./.git/objects/25/4ad75d0203fd3c458ef3c0e6270f0a8535ee6b
-r--r--r--  1 epicodus_staff  staff  152 Jul 20 09:24 ./.git/objects/73/7104ca100fd8cc634a3163523e6ed5278af3ba
-r--r--r--  1 epicodus_staff  staff  155 Jul 20 08:44 ./.git/objects/94/a25f7f4cb416c083d265558da75d457237d671
-r--r--r--  1 epicodus_staff  staff  174 Jul 20 08:44 ./.git/objects/db/cc811dfe5e619f1cd780259ff6038b706eb0be
-r--r--r--  1 epicodus_staff  staff  184 Jul 20 08:44 ./.git/objects/74/ef89062d598290c8dc9ba60aed850d04904b18
-r--r--r--  1 epicodus_staff  staff  185 Jul 20 09:24 ./.git/objects/fb/f55a850e44a5cc0f4dceadcd4c502b4aae3b9f
-r--r--r--  1 epicodus_staff  staff  193 Jul 20 08:47 ./.git/objects/b8/065e42b4e8d8e198473e076887d480914a101c
-r--r--r--  1 epicodus_staff  staff  218 Jul 20 09:24 ./.git/objects/28/bd20a2d5877168073433c72da5b4ab06727a98
-r--r--r--  1 epicodus_staff  staff  546 Jul 20 08:47 ./.git/objects/d3/b7741a1a95e76a796f641982edb6dca0146ec5
-r--r--r--  1 epicodus_staff  staff  86 Jul 20 08:44 ./.git/objects/7c/3fefb6c30ad34fc532d76b4486fd23305c148f
-rw-r--r--  1 epicodus_staff  staff  537 Jul 20 08:46 ./.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xmlmsg.sample
-rwxr-xr-x  1 epicodus_staff  staff  1348 Jul 20 08:44 ./.git/hooks/pre-push.sample
-rwxr-xr-x  1 epicodus_staff  staff  1642 Jul 20 08:44 ./.git/hooks/pre-commit.sample
-rwxr-xr-x  1 epicodus_staff  staff  189 Jul 20 08:44 ./.git/hooks/post-update.sample
-rwxr-xr-x  1 epicodus_staff  staff  3610 Jul 20 08:44 ./.git/hooks/update.sample
-rwxr-xr-x  1 epicodus_staff  staff  424 Jul 20 08:44 ./.git/hooks/pre-applypatch.sample
-rwxr-xr-x  1 epicodus_staff  staff  478 Jul 20 08:44 ./.git/hooks/applypatch-msg.sample
-rwxr-xr-x  1 epicodus_staff  staff  4951 Jul 20 08:44 ./.git/hooks/pre-rebase.sample
-rwxr-xr-x  1 epicodus_staff  staff  5299 Jul 20 08:46 ./gradlew
-rwxr-xr-x  1 epicodus_staff  staff  896 Jul 20 08:44 ./.git/hooks/commit-msg.sample
[...]

You can see these files by running ls -a in a terminal window inside your project directory. Can you believe we only created 3 of those files ourselves?!

  • .git files are of course related to our Git tracking.
  • .idea files are part of how IntelliJ keeps track of things.
  • Gradle has its own files as well to keep an eye on our dependencies
  • When we build our project to Run or Test, class files are also generated.

These extra files clutter our projects' GitHub repos too - taking up unnecessary space on Github servers, making downloads slower, and then filling the harddrive of anyone downloading our apps.

The only files your GitHub repo should include, are:

  • build.gradle
  • src folder and subfolders
  • .gitignore (you may not always see this)
  • .git (you may also not always see this)
  • README.md
  • license (if applicable)

Here is an example of what your teachers are looking to see.

Let's make sure our Java project lean and mean and clean instead of a cluttered mess when we push it to GitHub.

Ignoring Files on Git - how a .gitignore works

How do we do this? We can 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. We'll need a special file called a .gitignore which contains a list of files and directories to ignore.

Setting up a .gitignore is a very common practice for projects that may contain dependencies or build files that shouldn't get pushed to GitHUb.

A .gitignore works best if it is literally the first file you create. Try and remember to always add this file first, as you have to jump through some extra hoops to get it to respect your wishes if you've already added files you now want to ignore. But if you did, don't fret, it's not that difficult to make a .gitignore kick in after the fact. See a little further down.

What belongs in a .gitignore

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
*.bat

# 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/
out/
out
.gradle
gradle
gradlew.bat
gradlew
settings.gradle

# IntelliJ #
############
.idea
.idea/

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.

  • Packages: Because Gradle locates and installs our dependencies' packages for us, we don't track them.

  • Logs and Databases: We ignore .log files because they generally contain records of events specific to particular instances of a program.

  • 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: Almost all the extra content Gradle created was in the build directory. So, we ignore that entire directory.

  • IntelliJ: As mentioned above, .idea files are generated by the IDE to keep track of things. You can safely delete these.

  • Lines that start with # are comments.

  • NOTE: Never ignore .git, .md, .sql, or .java files!

Using a .gitignore file in a Project (At Epicodus)

  • You'll need to create a .gitignore file for each Java project you create at Epicodus.
  • It should live in the directory root.
  • You can see it my running ls -a in a terminal window in your project directory.
  • See "Making a .gitignore file work in an existing project" if it is not the first file you have added and committed.

Using a .gitignore file in a Project (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.

If you have created the .gitignore as the first file, you should be able to add, commit and push as normal, and the superfluent files will be ignored. If you didn't add the .gitignore file as the first file and you are struggling with it working, please keep reading.

Making a .gitignore file work in an existing project where junk files have already been added and committed

If you have already added and committed files that should have been ignored, follow these steps:

Run the following command in the IntelliJ terminal or standalone terminal window:

$ git rm --cached -r .

This will temporarily remove all files from git tracking, resulting in an output that looks 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 'build.gradle'
rm 'build/classes/main/App.class'
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/results.bin'
rm 'src/main/java/App.java'
rm 'src/main/java/PingPong.java'
rm 'src/test/java/PingPongTest.java'
[...]
  • Make a new .gitignore file if you don't have one as instructed above. Or, update your existing .gitignore with additional file types.
  • Add that .gitignore to tracking (do not use git add ., use git add .gitignore instead!! Otherwise the junk files will be added back in) and commit the new/updated .gitignore file.
  • Try git add .
  • Run $ git status to see what files will be deleted and ignored in future commits. Confirm that the list it provides is correct. It should now ignore all the files mentioned in the .gitignore.
  • commit and push. From now on, your repo should remain clean.

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
*.bat

# 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/
out/
out
.gradle
gradle
gradlew.bat
gradlew
settings.gradle

# IntelliJ #
############
.idea
.idea/

Additional Resources