{"id":19170310,"url":"https://github.com/sashadev-sky/.gitignore-guide","last_synced_at":"2025-09-16T03:47:34.462Z","repository":{"id":122652629,"uuid":"159445040","full_name":"sashadev-sky/.gitignore-guide","owner":"sashadev-sky","description":"Personal notes \u0026 useful reference","archived":false,"fork":false,"pushed_at":"2022-10-15T21:45:02.000Z","size":25,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-23T00:14:46.704Z","etag":null,"topics":["git"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sashadev-sky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-28T04:46:03.000Z","updated_at":"2022-10-15T21:22:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"af77e0e8-c18c-4a95-80b5-d0b1fdd2bdaf","html_url":"https://github.com/sashadev-sky/.gitignore-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sashadev-sky/.gitignore-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sashadev-sky%2F.gitignore-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sashadev-sky%2F.gitignore-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sashadev-sky%2F.gitignore-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sashadev-sky%2F.gitignore-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sashadev-sky","download_url":"https://codeload.github.com/sashadev-sky/.gitignore-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sashadev-sky%2F.gitignore-guide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275358840,"owners_count":25450443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-16T02:00:10.229Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git"],"created_at":"2024-11-09T09:53:37.940Z","updated_at":"2025-09-16T03:47:34.252Z","avatar_url":"https://github.com/sashadev-sky.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# .gitignore\n\n**Problem:**\n\nGit doesn't automatically track files because we don't want to record generated files (logs, compiled modules, etc). \n\nBut, seeing these files under the \"Untracked files\" list in `git status` would be confusing for large repositories.\n\nAnd inconvenient because you would never be able to use `git add .`\n\n**Solution:**\n\nA `gitignore` file specifies intentionally untracked files or directories that Git should ignore when a user makes commits to their remote Git repository. \n\n  * They will be essentially invisible to Git.\n\n`gitignore` itself should be committed to the remote repo in order to share the ignore rules with any other users that may clone it.\n\n\u003cbr\u003e\n\nCommon Patterns for Node/Rails:\n\n  * _note: styled for visual convenience_\n\n```Julia\n\nIgnore NPM\n===================================================================\n\nnode_modules/       # npm install refetches modules specified in package.json \u0026 creates new node_modules/ to store them in locally\nbundle.js           # ignore compiled code \u0026 regenerates when run `webpack`\nbundle.js.map       # ignore compiled code \u0026 regenerates when run `webpack`\n\n\nFiles Generated at Runtime\n===================================================================\n\nlog/                # matches any dirs (and contents) named 'log' anywhere in path\n/tmp/               # matches any dirs (and contents) named 'tmp' only from repo root\n*.db                # matches any files (or dirs) ending in .db anywhere in path\n*.sqlite\npids                # matches any files or dirs named 'pids' anywhere in path  \n*.pid\n\n\nHidden System Files   \n==================================================================\n\n.DS_Store            # often see files starting with '.'\n\n\nEnvironment Normalization  \n==================================================================\n\n/.bundle/           # but dirs can start with '.' too\n/vendor/bundle      # chained paths are always relative to repo root, prepended '/' not neccessary but explicit\n\n\nRails\n==================================================================\n\n.byebug_history\n/public/system\n\n```\n\n---\n\n[More comprehensive .gitignore](../master/.gitignore.md)\n\n---\n## Fundamentals: \n\n- For per project configurations, `$ touch .gitignore` to set up a file in your PWD\n\n- Each line specifies a pattern for the path to ignore.\n\n\u003chr\u003e\n\n\u003e**Pattern**: a string with a special format designed to match filenames, or to check, classify or validate data strings.\n\n\u003chr\u003e\n\n\n**Globbing patterns**: `gitignore` uses **wildmatch** for pattern matching: a combination of  globbing patterns + some additioanl rules to match against file / directory names. \n\n  * We can construct the patterns using normal characters and various **metacharaters**. \n\n  * In Github, these patterns are referred to as a **`\u003cpathspec\u003e`** :a pattern used to limit paths in Git commands.\n\n    * Certain Git commands accept `\u003cpathspec\u003e`s that follow wildmatch convention, others only accept standard shell glob pattern convention  \n\n  * Usage rules for most common ones are outlined in a table below\n    \n\n\u003cbr\u003e\n\nGit commands such as `git status` and `git add` then use these constructed patterns. \n- Note the `.gitignore` file is actually 1 of multiple sources where Git checks gitignore patterns from. \n\n## Metacharacters and Common Patterns\n\n_Assumptions_:\n\n1. Directory matches include the directory at **that point** in the path and any **paths underneath** it (so any contained subdir and files)\n\n2. The table / formatting notes below assume the user's `.gitignore` is in the root directory, so top-level and \"relative to the directory containing `.gitignore`\" are interchangable.\n\n    \u003e \"The convention, and simplest approach, is to define a single `.gitignore` file in the root. However, you can choose to define multiple `.gitignore` files in different directories in your repo. Each pattern in a particular `.gitignore` is tested relative to the directory containing that file.\"\n\n\n\u003cbr\u003e\n\n\n_Pattern format:_\n\n1.  \u003ckbd\u003e#\u003c/kbd\u003e - comment\n\n2. Any path matches itself\n\n3. Standard shell **glob patterns** work, but they will be applied **recursively** throught the _entire_ working tree (see edge cases in Wildmatch section).\n\n    * Also worth noting \u003ckbd\u003e.\u003c/kbd\u003e has no special meaning (can't do \u003ckbd\u003e./\u003c/kbd\u003e for ex. and don't really need to).\n\n4. You can start patterns with a forward slash (\u003ckbd\u003e/\u003c/kbd\u003e) to avoid recursivity (pins the patterns to only match from the top of the working tree).\n\n5. You can end patterns with a forward slash (\u003ckbd\u003e/\u003c/kbd\u003e) to specify a directory. \n\n    * Patterns match directories with or without this. It's used mainly for excluding files from being matched.\n\n6. You can negate a pattern by starting it with an exclamation point (\u003ckbd\u003e!\u003c/kbd\u003e).\n\n    * But not if its parent directory has been excluded.\n  \n    * \u003e Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.\n\n--- \n\n**Glob patterns** \n\n  * Are like simplified regular expressions that shells use.\n    \n    * One use is to quickly navigate around files: for ex. from Desktop, running `$ cd **/week\\ 6/` bypasses typing the name of the folder `week 6` is in first. \n    \n    * Note that in terminal, \u003ckbd\u003e**\u003c/kbd\u003e only lets you nest 2 levels deep, but in `.gitignore` it's a little different. (see below). \n\n7. \u003ckbd\u003e*\u003c/kbd\u003e  is a wildcard that matches zero or more characters.\n\n    * Often used to ignore files with a particular extension.\n\n    * Allows partial file / directory names:\n\n      * You cannot search for partial file or directory _names_ (not paths) by default. You have to append a metacharacter that modifies this behavior (for ex. \u003ckbd\u003e*\u003c/kbd\u003e).\n\n \n      * ex: the pattern `contro` in .gitignore\n\n        * will _not_ ignore your `controllers` folder \n    \n        * but the pattern `controllers` or `contro*` will\n\n\n  8. `[abc]` matches any character inside the brackets (in this case a, b, or c).\n\n  9. (\u003ckbd\u003e?\u003c/kbd\u003e) matches a single character.\n\n  10. Brackets enclosing characters separated by a hyphen (`[0-9]`) matches any character between them (in this case 0 through 9). \n\n  --- \n\n11. You can use \u003ckbd\u003e**\u003c/kbd\u003e to match nested directories; `a/**/z` would match `a/z`, `a/b/z`, `a/b/c/z`, and so on.\n\n    * Only valid if you use them with a \u003ckbd\u003e/\u003c/kbd\u003e like above or one of 2 ways below:\n\n      a) \u003ckbd\u003e**/\u003c/kbd\u003e appended to the front: matches in all directories (it matches any arbitrary path of directories and subdir to get to the file/dir).\n\n      * You don't need to write out the entire path to a file or dir. For ex. writing `en.yml` will match the file with that name in `app/config/locales/application_controller/en.yml`.\n\n      b) \u003ckbd\u003e/**\u003c/kbd\u003e appended to the back: matches everything inside (all subdirectories / files).\n\n      * Use it to ignore entire folders.\n  \n--- \n\n**wildmatch specific**:\n\n12. A \u003ckbd\u003e/\u003c/kbd\u003e in a pattern effects how Git uses it to check for a match.\n\n  * **By default (no \u003ckbd\u003e/\u003c/kbd\u003e), patterns in `.gitignore` match files in any directory**.\n\n      * meaning `controllers` or `contro*` would match: \n        * `app/foo/bar/controllers/baz.html`.\n\n        * `app/controllers/foo`.\n    \n  \nFollowing this logic, the below pattern with \u003ckbd\u003e*\u003c/kbd\u003e appended to the front and no \u003ckbd\u003e/\u003c/kbd\u003e:\n\n  * `*comment_expand.html`, `*ent_expand.html`, `*.html` would all match `/spec/javascripts/fixures/comment_expand.html`.\n\n\n12b. If the pattern _does_ contain a \u003ckbd\u003e/\u003c/kbd\u003e , Git treats it as a standard shell glob. (even if it is just appended/prepended at the front/back).\n\n* **nested paths will be relative to root**: patterns specifying a subdir/file in a specific directory need to start from the root directory. (You can prepend a \u003ckbd\u003e/\u003c/kbd\u003e to be explicit but it wouldn't make a difference). \n\n* It will also use \u003ckbd\u003e*\u003c/kbd\u003e following std. convention:\n\n\u003e Paths relative to the directory prefix will be matched against that pattern using fnmatch(3) and the FNM_PATHNAME flag; in particular, \u003ckbd\u003e*\u003c/kbd\u003e and \u003ckbd\u003e?\u003c/kbd\u003e can match directory separators.\n\n\nFor example, \n  * `\"Documentation/*.html\"` matches `\"Documentation/git.html\"` \n  * but not `\"Documentation/ppc/ppc.html\"`\n  * also not `\"tools/perf/Documentation/perf.html\"`.\n\n---\n\n## Table for quick reference\n(non-comprehensive)\n\nSymbol | Pattern | Match exs | Description |  Path Specifcation   |\n--- | --- | --- | ---|  --- |  \n  | | `foo`  | matches:\u003col\u003e\u003cli\u003e**dir** `foo`\u003c/li\u003e\u003cli\u003e**file** `foo`\u003c/li\u003e\u003c/ol\u003e  \u003cul\u003e\u003cli\u003e*`foo`*\u003c/li\u003e\u003cli\u003e*`foo/debug.bar`*\u003c/li\u003e \u003cli\u003e*`foo/debugger/debug.bar`*\u003c/li\u003e\u003cli\u003e*`assets/foo`*\u003c/li\u003e \u003cli\u003e*`assets/foo/debug.bar`*\u003c/li\u003e\u003cli\u003e ~~*but not `foo.bar`*~~\u003c/li\u003e\u003cli\u003e~~*but not `fooing`*~~\u003c/li\u003e\u003c/ul\u003e | By default, patterns match anywhere. So w/ no \u003ckbd\u003e /\u003c/kbd\u003e , any **dir** or **file** named `foo` will be ignored. | **None** - _(matches anywhere in repo)_ |\n \u003ckbd\u003e /\u003c/kbd\u003e | `foo/` |matches: \u003col\u003e\u003cli\u003e**dir** `foo`\u003c/li\u003e\u003c/ol\u003e \u003cul\u003e\u003cli\u003e*examples will be same as above, but assuming foo must always be a dir.*\u003c/li\u003e\u003c/ul\u003e|  **Appending** \u003ckbd\u003e /\u003c/kbd\u003e  indicates to match a **dir** `foo`, ignored anywhere | **None** - _(matches anywhere in repo)_\n \u003ckbd\u003e /\u003c/kbd\u003e |   `/foo`| matches: \u003col\u003e\u003cli\u003e**dir** `foo`\u003c/li\u003e\u003cli\u003e**file** `foo`\u003c/li\u003e\u003c/ol\u003e \u003cul\u003e\u003cli\u003e*matches `foo`*\u003c/li\u003e\u003cli\u003e~~*but not `assets/foo`*~~\u003c/li\u003e | **Prepending** \u003ckbd\u003e /\u003c/kbd\u003e matches **dirs**/**files** only in **root**. (Std. shell pattern \u003ckbd\u003e /\u003c/kbd\u003e means `cwd`; should be root here.)  | **Root** - _(root of repository only)_\n \u003ckbd\u003e /\u003c/kbd\u003e |  `foo/debug.bar`  | \u003cul\u003e\u003cli\u003e*matches `foo/debug.bar`*\u003c/li\u003e \u003cli\u003e~~*but not `debug.bar`*~~\u003c/li\u003e \u003cli\u003e~~*not`assets/foo/debug.bar`*~~ \u003c/li\u003e| Patterns specifying a **subdir**/**file** **in specific** **dir** are relative to **root**. (_Can prepend \u003ckbd\u003e /\u003c/kbd\u003e to be explicit, but don't need it now_)| **Root** - _(path must begin from root of repository only)_ |\n | \u003ckbd\u003e*\u003c/kbd\u003e  |   `*.bar`  | matches: \u003col\u003e\u003cli\u003e**dir** ending in _`.bar`_ \u003c/li\u003e\u003cli\u003e**file** ending in _`.bar`_\u003c/li\u003e\u003c/ol\u003e \u003cul\u003e\u003cli\u003e*`.bar`*\u003c/li\u003e\u003cli\u003e*`debug.bar`*\u003c/li\u003e\u003cli\u003e*`foo/debug.bar`*\u003c/li\u003e | \u003ckbd\u003e*\u003c/kbd\u003e is a wildcard that matches 0 or more chars. (Anything except \u003ckbd\u003e /\u003c/kbd\u003e) No specificity for **dir** / **file**.   | **None** - _(doesn't effect path, so anywhere in repo)_\u003c/li\u003e\u003c/ul\u003e \n |  \u003ckbd\u003e*\u003c/kbd\u003e  |   `foo*`   |  matches: \u003col\u003e\u003cli\u003e**dir** beginning w/ _`foo`_ \u003c/li\u003e\u003cli\u003e**file** beginning w/ _`foo`_\u003c/li\u003e\u003c/ol\u003e \u003cul\u003e\u003cli\u003e*`fooolder/debug.bar`*\u003c/li\u003e\u003cli\u003e*`foo`*\u003c/li\u003e\u003cli\u003e*`foo.txt`*\u003c/li\u003e\u003cli\u003e*`foobar.txt`*\u003c/li\u003e\u003cli\u003e`app/assets/foobar.txt`\u003c/li\u003e\u003c/ul\u003e  |  Same description as above. When matching a pattern w/out a \u003ckbd\u003e/\u003c/kbd\u003e, can match it anywhere |   **None** - _(doesn't effect path, so anywhere in repo)_ |\n | \u003ckbd\u003e**\u003c/kbd\u003e+\u003ckbd\u003e/\u003c/kbd\u003e   | `**/foo`  | matches: \u003cul\u003e\u003cli\u003e **file** or **dir** `foo` anywhere\u003c/li\u003e\u003cli\u003e`**/foo` === `foo`\u003c/li\u003e\u003c/ul\u003e |**Leading** \u003ckbd\u003e**/\u003c/kbd\u003ematches a **dir** anywhere in repo. (same as plain `foo`, just more explicit )  | **None** - _(matches anywhere in repo)_ |\n | \u003ckbd\u003e /\u003c/kbd\u003e+\u003ckbd\u003e**\u003c/kbd\u003e  |  `foo/**`  |  matches: \u003cul\u003e\u003cli\u003eall **files** / **dirs** inside **dir** `foo` w/ infinite depth\u003c/li\u003e\u003cli\u003e`foo/**` === `foo`\u003c/li\u003e\u003c/ul\u003e | Trailing \u003ckbd\u003e/**\u003c/kbd\u003e matches everything inside a **dir**, from anywhere in repo. (same as `foo`, but more explicit )  | **None** - _(matches anywhere in repo)_ |\n\n---\n\n### Ignoring a previously committed file\n\nFiles already tracked by Git are not effected by the gitignore file. If you want to ignore a file that you've committed in the past, you'll need to remove / cache it, then add a `.gitignore` rule for it. (Simply adding it to `.gitignore` after you've committed it appears to not do anything).\n\nUse **`git rm --cached`**\n\n\u003e Using the `--cached` option with `git rm` means that the file will be deleted from your remote repository, but will remain in your working directory as an ignored file. \n\n\u003eYou can omit the `--cached` option if you want to delete the file from _both_ the remote repository and your local file system.\n\n_below:_ the bash command **`echo`** accepts a string as standard input and redirects, or echoes, it back to the terminal as standard output. If we use it with **`\u003e\u003e`(double redirection arrow)**, it appends it to the file on the right instead of the terminal. (this would be the same as just typing `debug.log` into `.gitignore`). The **`git rm --cached`** is the important part. Then commit.\n\n```bash\n\n$ echo debug.log \u003e\u003e .gitignore\n$ git rm --cached debug.log\nrm 'debug.log'\n$ git commit -m \"Start ignoring debug.log\"\n\n```\n\n- **note:** to the `rm --cached` you **need to pass the actual relative path to the file**; not the same pattern conventions as `.gitignore` file.\n\n\u003chr\u003e\n\n### Debugging .gitignore files\nTo track down why a particular file is being ignored - use **`git check-ignore `** with the **`-v`** (or **`--verbose`**) option to determine which pattern is causing a particular file / directory to be ignored:\n\n```bash\n\n$ git check-ignore -v debug.log\n.gitignore:3:*.log debug.log\n\n```\nThe output shows:\n\n```erb\n\n\u003cfile containing the pattern\u003e : \u003cline number of the pattern\u003e : \u003cpattern\u003e \u003cfile name\u003e\n\n```\n \n \u003chr\u003e\n\n### Setting up a global .gitignore\n \nTo set up a file in your home directory for global configurations:\n \n```bash\n \n $ touch ~/.gitignore\n \n ```\n \nYou’ll probably have at least two entries two entries to add:\n1. One for operating system-specific files,\n2. One for editor-specific files.\n\nOnce you update it, save and finally configure git to use it:\n \n```bash\n \n $ git config --global core.excludesfile ~/.gitignore\n \n ```\n\n\u003chr\u003e\n\n### Github Templates\n\nGithub provides us with a collection of `.gitignore` templates for specific programming languages, frameworks, tools, environments, etc. \n\nThese templates are available in the Github.com interface:\n1. When creating new repositories and files. (Dropdown at the bottom \u003ckbd\u003e`Add .gitignore: None`\u003c/kbd\u003e) \n2. On the main page of the repo, if you select \u003ckbd\u003e`Create new file`\u003c/kbd\u003e and type _.gitignore_ in the input for file name, template selector will appear again.\n3. Links below\n\n\n\u003chr\u003e\n\n### References\n\na. \u003ccite\u003e[Git Globbing Pattern reference](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository)\u003c/cite\u003e\n\nb. \u003ccite\u003e[Git Globbing Pattern reference #2](https://git-scm.com/docs/gitignore/2.19.0)\u003c/cite\u003e\n\nc. \u003ccite\u003e[Alternative Globbing Pattern reference](https://www.atlassian.com/git/tutorials/saving-changes/gitignore)\u003c/cite\u003e\n\nd. \u003ccite\u003e[Github .gitignores master repo](https://github.com/github/gitignore)\u003c/cite\u003e\n\n - \u003ccite\u003e[Github .gitignore Node](https://github.com/github/gitignore/blob/master/Node.gitignore)\u003c/cite\u003e\n  - \u003ccite\u003e[Github .gitignore Rails](https://github.com/github/gitignore/blob/master/Rails.gitignore)\u003c/cite\u003e\n  - \u003ccite\u003e[Github .gitignore Ruby](https://github.com/github/gitignore/blob/master/Ruby.gitignore)\u003c/cite\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsashadev-sky%2F.gitignore-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsashadev-sky%2F.gitignore-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsashadev-sky%2F.gitignore-guide/lists"}