git rm --cached ./idea?
Tags: intellij, idea, android, jetbrains
Published: 2019-09-04 16:49:18

This article was originally a lightning talk presented at Droidcon NYC 2019.

---

If you work long enough with any Android project built in Android Studio, you are bound to run into the `.idea/` directory in your project files. You may not know this directory at all, or you may recognize that it contains a bunch of files that power the Android Studio Integrated Development Environment (IDE), and that it is often home to files with changes that pollute your working tree in git. In fact, many projects you come across may have the entire `.idea/` directory ignored from version control entirely to avoid constant changes showing up through the commit history.

What are this directory and it's contents? Should it be tracked under version control? How can you and your team use the power of Android Studio to your advantage to improve the efficiency and consistency of your team?

This article is not a single answer to any of these questions, but it is intended to get anyone working with Android, from newcomers to senior engineers and architects thinking about this directory and it's uses. I will not be able to provide a comprehensive list of everything in this directory, nor would this article be of much use if I could. Rather, the intent is to give a broad introduction with the hope that you will do further research around the issues you and your team face as you come to them.

# IntelliJ and Android Studio
Our story begins with the IntelliJ IDE from JetBrains. IntelliJ is a Java-centric IDE, initially released in 2001. It has long been one of the industry leaders in development tools for developers working with Java projects of all types. When Android development started to grow, most developers used some form of existing Java IDE. In 2014, Google release the first stable version of Android Studio – a new IDE purpose-built for Android development, but built on top of IntelliJ. Being a fork of the IntelliJ project, Android Studio inherits all of the underlying mechanisms used by IntelliJ, including the `.idea/` directory.

# `.idea/`?
What exactly is this directory? Any project built in an IDE like IntelliJ or Android Studio has a lot of configuration options associated with it. Unlike IDE preferences, such as editor themes and application-level behaviors that are personal preferences of the individual developer using the IDE, project settings are usually consistent across a team and are more tightly linked to the needs of the specific product and tools rather than the person writing the code. This project-specific configuration is the domain of the `.idea/` directory.

In earlier versions of IntelliJ, project configuration options were stored in a series of `.ipr`, `.iml`, and `.iws` files. This legacy project structure made it hard to determine where specific configuration options were stored, and greatly increased the chance that small configuration changes would result in merge conflicts between developers. Newer projects now use a "directory-based project structure", centered around our new friend, the `.idea/` directory. Within this directory we can find a series of sub-directories and files, mostly in the XML format, that represent our project configuration.

# git and VCS
If you are working alone on a project you may not spend much time thinking about how to onboard new developers. If you are on a team, your onboarding process may be a long list of steps in a wiki or shared document, or worse, done completely by word of mouth as issues arise for new team members. Onboarding and team collaboration, despite a wide array of tools on the market, are not solved problems. But we can use the built-in features of Android Studio to make parts of the process far faster and more efficient. What would be involved to add a new team member to your project right now? What if they could check the project out of version control and have the project configuration already done for them?

While your team might be using another VCS beside git, the ideas presented in this article are relevant to almost any form of version control. If you aren't yet using VCS, properly sharing the .idea/ directory may be another reason to consider adopting it!

# The `.gitignore` file
If you are using git for your project, you probably already have a `.gitignore` file in your project root (and maybe some sub-directories). This article was initially conceived of at a time when the default `.gitignore` left a lot of room for improvement. Since then, the default file created for new projects has been vastly improved. Check out what the ignore file in your project covers and use the ideas in this article to improve it!

The default `.gitignore` file looks like this. Notice the lines starting with `/.idea/`:
```*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
```

# What *not* to include
Let's start by taking a look at what is ignored by default, and why:

## `libraries/`
The `libraries/` directory is *mostly* self explanatory. While the directory here doesn't contain the actual library code for libraries used in the project, it does contain metadata used by the IDE to display these libraries properly. This shouldn't be in version control because the configuration of dependencies is represented in most Android projects by build tools like gradle. When a new local copy of the project repo is cloned, gradle should be responsible for downloading and configuring all the necessary dependencies for the project, and Android studio will recreate all the metadata files needed properly.

## `modules.xml`
Like the `libraries.xml` directory, project module metadata should be built from the gradle configuration for the project. No need to share this file with your teammates, as it is redundant and should be created by your local copy of Android Studio.

## `workspace.xml`
This is the first file we will look at that we actually expect *should* vary between computers. The `workspace.xml` file contains information about the current state of the IDE as it is being used: what editor tabs are currently open, where the user's cursor is in each tab, and lots more. This file is responsible for making sure your editor opens where you left it when you return to a project, and as such, has no relevance to your teammates and shouldn't be in version control.

## `assetWizardSettings.xml`
This is another IDE state file. Every time you use the asset studio in Android Studio, the setting you used when importing an asset are saved here so they can be pre-populated when you open the import window the next time. The information stored in this file has no significance to your teammates, keep it out of version control.

![Android Studio asset studio import dialog](https://thepracticaldev.s3.amazonaws.com/i/1tk729417fihtcfl6al9.png)

## `caches/`
This directory's purpose isn't entirely clear from its name. What does it cache? Currently, in Android Studio this contains a file called `build_file_checksums.ser`. This is a checksum for all of your project's gradle build files. When you update something in a build file, comparing it to the checksum here is how Android Studio knows to prompt you to re-sync your gradle files!

![Android Studio gradle sync prompt](https://thepracticaldev.s3.amazonaws.com/i/92ixdhwpa3jlejnhyhob.png)

# What should be in version control?
Now that we've looked at some of what is excluded from version control – and a lot of developers stop at this point and exclude the whole `.idea/` directory – let's look at what you might want to share with your team.

## `codeStyles/`
Did you know you can store your custom code styles and formatting directly in your project repo? This sub-directory will contain any project specific formatting preferences you select, and allows new team members to get auto-formatting that matches your project styles for free!

## `dictionaries/`
Like code styles, anyone working on a product with a vowel-free startup name knows that your code can quickly be filled with typos. Sure, you've probably found the "add to dictionary" menu option to stop those typos from being highlighted, but did you know that you can share them with your team? Inside this directory will be a file for each developer who has added custom dictionary words, and all words in those files should avoid spellcheck errors for any developer working on the project.

## `inspectionProfiles/`
Just like `codeStyles/` and `dictionaries/`, you can share custom inspection profiles (lint checks) with your team here.

## `misc.xml`
The purpose of this file isn't exactly clear from its name. This is where Android Studio keeps track of project metadata, like the Java version to use and the type of project.

## `runConfigurations.xml`
As a project grows in size and complexity, it will often need specific settings for it to run properly. Whenever you create or change a run configuration in Android Studio it is stored here. If you want to share these configurations with your team, add this file to version control!

## `navEditor.xml`
The Navigation Editor, added in Android Studio 3.3, uses this file to store the visual layout of the navigation components in the editor window. This file is actually added to the default `.gitignore` in new projects, however you may want to consider adding it to version control so that the visual editor layout matches for all developers on the project.

![Android Studio navigation editor](https://thepracticaldev.s3.amazonaws.com/i/xrw6yqzu18z4bzr9i9na.png)

# What else?
This article is far from a complete list of everything that can be found in the `.idea` directory and should serve as a starting point to research the files and directories you find inside and to make your own decision as to what should and shouldn't be shared with your team.

When you find a file that you must choose to include or ignore, there are a few criteria you can use to decide if the file should be tracked in version control:

1. Is the file *not* unique to your machine? Only commit files that should be the same on every developer's computer.
2. Is the file useful for your teammates? Personal preferences and configurations should not be shared with the team.
3. Does the file stay the same across commits? Some files in the `.idea` directory get regenerated or modified frequently. If a file changes in almost every commit, it may not be appropriate state to store in version control.
4. Does the file describe an aspect of your project? Configuration for your project should be in version control, configuration for your whole IDE across multiple projects shouldn't.

# Other ways to share settings
Some of the tweaks you may want to make to your work environment will be preferences for the whole IDE, regardless of the project you're working on, such as editor themes, plugins, and personal code snippets. Settings accessed via the Android Studio application settings are not saved into the `.idea` directory. Instead, most themes and plugins can be downloaded from the plugin repository accessed via the settings screens, and personal preferences, can be imported and exported from Android Studio, such as company-wide code style preferences that can be used regardless of the project that is opened.

![Android Studio plugins repository](https://thepracticaldev.s3.amazonaws.com/i/2kr4olbrotztbpu6remu.png)