Git-Mastery: Lessons

T2L6. Omitting Files from Revision Control


Git allows you to specify which files should be omitted from revision control.

This lesson covers that part.

You can specify which files Git should ignore when deciding what to track. While you can always omit files from revision control simply by not staging them, an 'ignore-list' is more convenient, especially when the working directory contains files that are not suitable for revision control (e.g., temporary log files) or files you want to avoid accidentally committing (e.g., files containing confidential information).

A repo-specific ignore-list of files can be specified in a .gitignore file, stored in the root of the repo folder.

The .gitignore file itself can either be tracked by Git or ignored.

  • To keep it under version control (the more common choice, which allows you to track how the .gitignore file changes over time), simply commit it as you would commit any other file.
  • To ignore it, simply add its name to the .gitignore file itself.

The .gitignore file supports file patterns; e.g., adding temp/*.tmp to the .gitignore file prevents Git from tracking any .tmp files in the temp directory.

SIDEBAR: .gitignore File Syntax

  • Blank lines: Ignored and can be used for spacing.

  • Comments: Begin with # (lines starting with # are ignored).

     # This is a comment
    
  • Write the name or pattern for each file/directory to ignore.

    log.txt          # Ignores a file named log.txt
    
  • Wildcards:

    • * matches any number of characters, except / (i.e., for matching a string within a single directory level):
      abc/*.tmp     # Ignores all .tmp files in abc directory
      
    • ** matches any number of characters (including /)
      **/foo.tmp    # Ignores all foo.tmp files in any directory
      
    • ? matches a single character
      config?.yml   # Ignores config1.yml, configA.yml, etc.
      
    • [abc] matches a single character (a, b, or c)
      file[123].txt # Ignores file1.txt, file2.txt, file3.txt
      
  • Directories:

    • Add a trailing / to match directories only.

      logs/          # Ignores the logs directory (and everything under it)
      
    • Patterns without / are not anchored and are matched at any directory level.

      *.bak          # Ignores all .bak files anywhere in the repository
      
    • Patterns starting with / are relative to the location of the .gitignore file.

      /secret.txt    # Only ignores secret.txt in the repository root
      
  • Negation: Use ! at the start of a line to stop ignoring something.

    *.log           # Ignores all .log files
    !important.log  # Except important.log
    

Example:

.gitignore
# Ignore all log files
*.log

# Ignore node_modules folder
node_modules/

# Don’t ignore main.log
!main.log

.gitignore is a 'hidden' file!

Files with a name starting with . (such as .gitignore) are considered hidden files by macOS and Linux. Git tools on Windows are also likely to mark the .gitignore file as a hidden file. Therefore, if the .gitignore file is not visible to you, you'll need to look for it among 'hidden' files.
How to do that in: Windows | macOS | Linux

HANDS-ON: Adding files to the ignore-list

Target Get Git to ignore some files in a repo.

Preparation

Option 1: Create a fresh sandbox using the Git-Mastery app

  • Navigate inside the gitmastery-exercises folder.
  • Run the gitmastery download hp-ignore-file command.

The sandbox will be set up inside the gitmastery-exercises/hp-ignore-file folder.


Option 2: Manually set up a sandbox

Create a temp.txt file and a few .tmp files in a repo. These are presumably files we do not want to include in our revision history. For example, as follows:

echo "good stuff" > keep.txt
echo "temp stuff" > temp.txt
echo "more temp stuff" > file1.tmp
echo "even more temp stuff" > file2.tmp

1 Configure Git to ignore those files:

 CLI

Create a file named .gitignore in the working directory root and add the text temp.txt into it.

echo "temp.txt" >> .gitignore
.gitignore
temp.txt

Observe how temp.txt is no longer detected as 'untracked' by running the git status command (but now it will detect the .gitignore file as 'untracked').

Update the .gitignore file as follows:

.gitignore
temp.txt
*.tmp

Observe how .tmp files are no longer detected as 'untracked' by running the git status command.

Sourcetree

The file should currently be listed under Unstaged files. Right-click it and choose Ignore.... Choose Ignore exact filename(s) and click OK.
Also note the other options available, e.g., Ignore all files with this extension. They may be useful in future.

Note how temp.txt is no longer listed under Unstaged files. Observe that a file named .gitignore has been created in the working directory root and has the following line in it. This new file is now listed under Unstaged files.

.gitignore
temp.txt

Right-click on any of the .tmp files you added, and choose Ignore... as you did previously. This time, choose the option Ignore files with this extension.

Note how .tmp files are no longer shown as unstaged files, and the .gitignore file has been updated as given below:

.gitignore
temp.txt
*.tmp

2 Optionally, stage and commit the .gitignore file.

done!

Files recommended to be omitted from version control

  • Binary files generated when building your project, e.g., *.class, *.jar, *.exe
    Reasons:
    1. There is no need to version control these files, as they can be generated again from the source code.
    2. Revision control systems are optimized for tracking text-based files, not binary files.
  • Temporary files e.g., log files generated while testing the product
  • Local files, i.e., files specific to your own computer e.g., local settings of your IDE (.idea/)
  • Auto-fetched files, i.e., files automatically downloaded by build tools and package managers e.g., node_modules/ for Node.js projects
  • Sensitive content, i.e., files containing sensitive or personal information e.g., credential files, personal identification data (especially if there is a risk of those files leaking through the revision control system).
EXERCISE: ignoring-somethings

DETOUR: Ignoring Previously-Tracked Files

Adding a file to the .gitignore file is not enough if the file was already being tracked by Git in previous commits. In such cases, you need to do both of the following:

  1. Untrack the file (i.e., remove the file from the staging area and stop tracking it in the future), using the git rm --cached <file(s)> command.
    git rm --cached data/ic.txt
    
  2. Add it to the .gitignore file, as usual.

The above steps will remove the file from the staging area but will not delete it from the working directory. If this file was included in previous commits, the next commit will show it as 'deleted' (because it is no longer visible to Git).