.gitignore Isn't the only way to ignore files in Git

527 points - yesterday at 10:29 AM

Source

Comments

hungryhobbit yesterday at 7:59 PM
Fun article, but it leaves out my favorite "almost ignore" feature in Git: `.gitattributes`.

This file lets you specify that git should "ignore" the diff from certain files. For instance, Node projects have a `package-lock.json` that is pure noise from a Git standpoint (it's just massive amounts of diff specifying specific versions of libraries, and the real human-readable version is in a separate `package.json` file).

With `.gitattributes` in the root of your project, you can just add a line:

`package-lock.json -diff`

Now, that file will still get staged/committed (which you want) ... but when you `git diff` you won't see the massive amounts of pointless diff in that file.

rmunn today at 9:32 AM
I have a habit of writing myself notes in various .txt files, and then not cleaning them up often enough so they end up cluttering my `git status` view. I ended up with a solution not mentioned in the article: create a `scratch` directory, and a `scratch/.gitignore` file containing just one line: `*`. This makes Git ignore everything in the scratch directory, including that same .gitignore file — so I never accidentally check it into Git, and don't end up pushing my personal .gitignore settings onto my coworkers.

Of course, I could have used .git/info/exclude for that, and not risked accidentally adding my `scratch` directory with `git add -A` or something. So I (re-)learned something (which I'd known about but forgotten) today.

But as a reminder to anyone else who had forgotten this: .gitignore files are processed throughout the repo, not just at the top level. You can sprinkle them throughout the repo structure for finer-grained control, which may come in handy in some circumstances.

kevincox yesterday at 4:02 PM
The global/user wide exclude is a feature that should be more widely known. I frequently have people submitting changes to add their IDE/OS/AI/... files to every project's .gitignore. They are almost always pleasantly surprised when I tell them that they can add them to their standard configuration and have them ignored everywhere without bothering every project and without risk of accidentally committing them on a project where they haven't updated the .gitignore yet.

My general rule is that in-repo .gitignore should only be used for repo-specific things (build outputs, dependency folders, ...) and most user tools should be in their own user config.

hk1337 yesterday at 2:30 PM
~/.config/git/ignore and ~/.config/git/config is the proper place for your global git config and ignore instead of creating a ~/.gitignore_global and changing the config. IMO.

my dotfiles are a lot smaller at the root level taking advantage of the ~/.config/ for a lot more things.

the git exclude isn't used as much because it doesn't get committed to the repository so you'd have to recreate it each time you wanted to use it. that doesn't mean they're bad just why they are not used.

judofyr yesterday at 2:34 PM
Not sure where I picked up this, but I’ve added this to my global Git ignore:

    attic
That way you can just create an attic directory in any project where you can keep random stuff that should never be committed. I’ve yet to find a repo which actually has such a directory checker in.
dofm yesterday at 4:46 PM
Re: per-user ignores:

> For example, if you’re on macOS, adding .DS_Store here would be ideal.

As long as every Mac user on your project does. If you have more than one, it may be better off taken out of everyone's hands.

wpollock yesterday at 3:36 PM
One point of clarification: with git, "global" means per-user, not "machine-wide. (I never understood why "--global" wasn't better named, maybe "--user".) That's why these pathnames are in a user's home (the "~" means the current user's home directory).

Machine-wide configuration is called "system" in git, and generally lives under "/etc".

bryancoxwell yesterday at 2:07 PM
I use the ever living hell out of .git/info/exclude. Works great for scripts/Makefiles I only want locally and collaborators wouldn’t care about or be able to use.
rlpb today at 11:50 AM
Placing various artifacts (eg. build artifacts) inside the source tree always seemed like a historical mistake to me. It leads to various accidents such as people checking in their credentials and accidentally bundling such files in source distributions, for example. These consequences are real.

Debian build tooling places build artifacts in the parent directory on the assumption that this is acceptable, but it then surprises people since it's not the norm anywhere else.

Perhaps this ship has sailed. But I think it's worth pointing out that if you have an option, don't design things that place things inside the source tree if you can avoid it.

elyobo yesterday at 10:19 PM
Relatedly, some aliases I have in place.

  assume = update-index --assume-unchanged
  unassume = update-index --no-assume-unchanged
  assumed = "!git ls-files -v | grep ^h | cut -c 3-"
  unassumeall = "!git assumed | xargs git update-index --no-assume-unchanged"
  assumeall = "!git st -s | awk {'print $2'} | xargs git assume"
lmf4lol yesterday at 7:31 PM
Wow! How did I not know this? I am a professional software dev for 20 years… and only ever used .gitignore !

I just realized that I never even „asked“ myself if there might exist a better way than to clutter .gitignore with all kinds of specific excluded only relevant to me. I just accepted the world as it appeared to me…

And Today, it got s little bit better :-)

stevage today at 7:59 AM
Wow, how did I not know about the exclude file? I've had this need so many times - working on a shared repo where I want to ignore some files locally.
leleat yesterday at 10:03 PM
There is also

  git update-index --[no]-skip-worktree
for files that are already tracked. This can be useful for some local experimentation... it's just a bit annoying to use because it's not really surfaced anywhere by git (kinda). You need to remember that you set it; otherwise other operations like checkouts may be blocked.
Hendrikto yesterday at 1:55 PM
This is just a very low-effort regurgitation of this: https://git-scm.com/docs/gitignore
supermdguy today at 1:24 AM
One trick I’ve used is creating a folder and then adding a .gitignore inside it with *. Then nothing in that folder gets tracked, without needing to add anything to the public gitignore. Didn’t know about .git/config though!
maxlin today at 4:00 PM
My first and hopefully only clash with the global ignore file was debugging why a project worked differently between machines. There was a global ignore on the machine I was working on (that I didn't place) that "smartly" tried to exclude "irrelevant" code / project files regardless of project.

I see version control somewhat similarly as I see traffic laws. Sure, they could work in entirely different ways, Germans like their autobahns, but breaks to the norm in an otherwise planar field are rarely arguable for.

adamgordonbell today at 3:57 AM

    you may have a personal notes.txt file in a repository that you don’t want to check into git but you also don’t want to add to .gitignore because it’s unique to your workflow. 

    The exclude file lives in the .git directory of every Git repository but changes to it are not checked into Git
Wtf. I've always wanted this, and it was right there.
jeremyscanvic yesterday at 3:07 PM
I knew about .git/info/exclude and ~/.config/git/ignore but not about git-check-ignore(1). Neat!
h4kunamata today at 2:53 AM
>~/.config/git/ignore

This never be considered as a solution. It only works on that PC, when working with a team, this approach is wrong in so many levels.

I host my own Forgejo server/repos, it is just me but .gitignore just makes more sense. It is on the root of the project, and I only have one file to manage. No matter that PC/device I am using, they are automatically covered.

ramijames today at 12:52 PM
I love these types of threads the most. I learn so much.
andrelaszlo yesterday at 10:49 PM
Here's how I use the excludes file to set a different config for a project directory containing multiple repos:

https://laszlo.nu/blog/project-level-git-config.html

codensolder today at 3:01 PM
something new i learned today, thanks!
nonoesp today at 6:59 AM
git update-index --assume-unchanged path/to/file

https://git-scm.com/docs/git-update-index

dalton_zk today at 1:56 AM
Nice, I didn't know the other options besides .gitignore
hmokiguess yesterday at 6:53 PM
git is so incredible, it never ceases to amaze me, what a timeless piece of software
bitvvip yesterday at 2:52 PM
I still like using gitignore very much
globular-toast yesterday at 3:41 PM
Magit has good support for these other methods. You press <i> and then select if you want the ignore to be shared (.gitignore) or private (.git/info/exclude).
antisol today at 12:59 AM
Point of pedantry:

  > The ignore file lives in your machine’s home directory in ~/.config/git/ignore. Whatever filenames are added to this file are ignored globally at a machine-level.
The wording here is slightly wrong: ~/.config/git/ignore will ignore files per-user on the machine, not "at a machine level". And it's not "your machine's home directory", it's your user's home directory on that machine. Any other users on the same machine will not see this. Git calls this "global", as in "global for the user".

Git config does also have a --system option which modifies the system-level config file, /etc/gitignore. You could probably ignore stuff at the system/machine level (hint: you don't want to), with this. I'd do something like:

  $ sudo git config --system core.excludesFile /etc/gitignore
  $ sudo touch /etc/gitignore
Note however that user config will override this, so any user who has a core.excludesFile setting will not also look at your system level excludes file. Which is a pretty big caveat.
tonymet yesterday at 5:13 PM
these are great for ignoring files by name, but you often want to ignore binary files or other files by type.

Set a global hooks dir, and then block binary files in pre-commit by using file or checking the git index

   git config --global core.hooksPath ~/.config/git/hooks
Or block large changes, because binary mods are often larger than a real diff.
yieldcrv today at 2:11 AM
but dont forget dockerignore if you use docker
PunchyHamster yesterday at 6:10 PM
another useful snippet

    [includeIf "hasconfig:remote.*.url:git@git.company.com:*/**"]
    path = /home/dir/per/company/config
allows for remote specific configs, overriding say email or other required options depending on where you send contributions - without having to have per repo config

works for dir too

    [includeIf "gitdir:/home/user/src/work1/"]
Git is REAL bitch about exact syntax here; the first snippet won't work with just :*, it needs :/* ; the second won't work without trailing slash
shinobi-apps today at 2:28 PM
[flagged]
arikrahman yesterday at 10:47 PM
[dead]
codymisc yesterday at 9:58 PM
[flagged]
uptown yesterday at 3:54 PM
Not really news. I worked with dozens of developers who have managed to ignore files in Git.
barbazoo yesterday at 3:16 PM
Exclude sounds like a recipe for sadness.