The .gitignore File

Earlier in this chapter, you saw how to use the .gitignore file to pass over main.o, an irrelevant file. As in that example, you can skip any file by adding its name to .gitignore in the same directory. Additionally, you can ignore the file everywhere by adding it to the .gitignore file in the top-most directory of your repository.

But Git also supports a much richer mechanism. A .gitignore file can contain a list of filename patterns that specify what files to ignore. The format of .gitignore is as follows:

  • Blank lines are ignored, and lines starting with a hash mark (#) can be used for comments. However, the hash mark does not represent a comment if it follows other text on the line.

  • A simple, literal filename matches a file in any directory with that name.

  • A directory name is marked by a trailing slash character (/). This matches the named directory and any subdirectory but does not match a file or a symbolic link.

  • A pattern containing shell globbing characters, such as an asterisk (*), is expanded as a shell glob pattern. Just as in standard shell globbing, the match cannot extend across directories and so an asterisk can match only a single file or directory name. But an asterisk can still be part of a pattern that includes slashes to specify directory names as part of the pattern (e.g., debug/32bit/*.o).

  • An initial exclamation point (!) inverts the sense of the pattern on the rest of the line. Additionally, any file excluded by an earlier pattern but matching an inversion rule is included. An inverted pattern overrides lower-precedence rules.

Furthermore, Git allows you to have a .gitignore file in any directory within your repository. Each file affects its directory and all subdirectories. The .gitignore rules also cascade: you can override the rules in a higher directory by including an inverted pattern (using the initial !) in one of the subdirectories.

To resolve a hierarchy with multiple .gitignore directories and to allow command-line addenda to the list of ignored files, Git honors the following precedence, from highest to lowest:

  • Patterns specified on the command line.

  • Patterns read from .gitignore in the same directory.

  • Patterns in parent directories, proceeding upward. Hence, the current directory’s patterns overrule the parents’ patterns, and parents close to the current directory take precedence over higher parents.

  • Patterns from the .git/info/exclude file.

  • Patterns from the file specified by the configuration variable core.excludefile.

Since a .gitignore is treated as a regular file within your repository, it is copied during clone operations and applies to all copies of your repository. In general, you should place entries into your version-controlled .gitignore files only if the patterns apply to all derived repositories universally.

If the exclusion pattern is somehow specific to your one repository and should not (or might not) be applicable to anyone else’s clone of your repository, the pattern should instead go into the .git/info/exclude file, because it is not propagated during clone operations. Its pattern format and treatment is the same as .gitignore files.

Here’s another scenario. It’s typical to exclude .o files, which are generated from source by the compiler. To ignore .o files, place *.o in your top level .gitignore. But what if you also had a particular *.o file that was, say, supplied by someone else and for which you couldn’t generate a replacement yourself? You’d likely want to explicitly track that particular file. You might then have a configuration like this:

$ cd my_package
$ cat .gitignore
*.o

$ cd my_package/vendor_files
$ cat .gitignore
!driver.o

The combination of rules means that Git will ignore all .o files within the repository but will track one exception, the file driver.o within the vendor_files subdirectory.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.46.131