0

The question

How do I generally .gitignore Log/log folders, but include my specific NetTerminal/Log/ folder and contents below it?


Background

We're using Azure DevOps and have a repository with the .gitignore template file "VisualStudio".

The .gitignore file has by default this line:

[Ll]og/

It happens that we have a Visual Studio project with a log class in: NetTerminal/Log/Log.cs. The folder and the file is being ignored by git because of the default line above. The NetTerminal folder is not below another Log folder, so that's not the reason.

I have tried adding any of the below, but they doesn't do anything, the file doesn't show up in Sourcetree's Uncommitted Changes list.

!NetTerminal/Log/
!NetTerminal/Log/*
!NetTerminal/Log/Log.cs

If I add a * to the default, as follows, now my custom file is found - but if I create a new Log folder somewhere else and add a file into it, it is also showing up, so the [Ll]og/* line is kind of ignored?

[Ll]og/*

Please advice? :-)

Answer

As this question has been closed, I'm writing the answer to my question here. Maybe the question can be reopened, then I'll move this to a real answer.

The answer to this problem lies in one line of the manual for gitignore files:

If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.

I knew about /zyx being (relative to the .gitignore file, so file or folder "zyx" is located in the same folder as the .gitignore file. I also knew about zyx/ meaning zyx IS a folder, not a file. So I made the mistake to put !NetTerminal/Log believing it could unignore my Log folder located in NetTerminal folder somewhere in the folder structure. But no can do, specifing a folder structure to match against automatically makes it relative to the .gitignore file. I find this sad. Prefixing with / clearly states that this is located in relation to the .gitignore file.

So first I thought I had to put the full path relative to the .gitignore file, making it volunerable if we would change our folder structure.

BUT, "**/" to the rescue! From the manual:

A leading "" followed by a slash means match in all directories. For example, "/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".

So, the solution is:

[Ll]og/
!**/NetTerminal/Log/

With this, new Log folders (with files inside) is ignored and my NetTerminal/Log file is included.

YEAY!

SvendK
  • 465
  • 3
  • 17
  • Ignore `[Ll]og/*` but force-add the file: `git add --force NetTerminal/Log/Log.cs` See https://stackoverflow.com/a/11126391/7976758 Found in https://stackoverflow.com/search?q=%5Bgitignore%5D+track+ignored+file – phd Apr 27 '22 at 11:31
  • @phd Will this automatically track any later changes or is it only my current change/adding of the file? – SvendK May 01 '22 at 14:11
  • To whoever duplicated my question (@phd?): My folder NetTerminal/Log/ is not located below another Log/ folder, which I already wrote in the question? Is the linked question still relevant here? I also noted that putting [Ll]og/* (asterisk) makes changes to any Log/ file not being ignored. Somwthing is rotten... :-) Please advice. – SvendK May 01 '22 at 14:18
  • "*Will this automatically track any later changes or is it only my current change/adding of the file?*" Only for added files. Untracked files are still ignored by `[Ll]og/` – phd May 01 '22 at 14:55
  • "*(To whoever duplicated my question (@phd?)*". Not me. The nickname is clearly written up in the box. – phd May 01 '22 at 14:55
  • @phd - Sorry for late (!) reply. Okay, it's not a real option then, as later added file will unknowingly be forgotten if e.g. we change the folder structure and move the folder. – SvendK Jun 09 '22 at 12:47
  • Ah, sorry, it's not stated in the box on the question, but visible under the activity history. @torek - You closed the question, could you please elaborate on [my comment](https://stackoverflow.com/questions/72026953/gitignore-general-log-but-track-specific-log-folder?noredirect=1#comment127354769_72026953) and advice further? Thanks :-) – SvendK Jun 09 '22 at 12:47
  • As the answers to the duplicate say, you must always white-list any *folder* that must show up in the search if some earlier rule will exclude it. That includes parent folders of sub-folders that might become excluded. While it's quite crude (and CPU-intensive), one simple solution is to add `!*/` as the final line in a `.gitignore` so that *all* folders are *always* searched. Then any earlier `!foo/Log/` can be applied for any `foo`. – torek Jun 09 '22 at 15:39
  • @torek Thank you for quick reply. My claim was that my NetTerminal folder was not below another Log folder, but what you're saying is, that it doesn't matter, the pattern matches. I just don't understand why this doesn't work: `[Ll]og/` `!NetTerminal/Log/` And why does it stop working (stop ignoring) new files in new log folders, when I have `Log/*` ? I guess the best thing would be to rename our log class folder to, well, LogClass... :) – SvendK Jun 09 '22 at 19:18
  • It's either an order problem, or a scan problem, but in all cases you can run `git check-ignore -v` to find out *why* (what `.gitignore` file and line) some path is not going to be auto-added-or-complained-about. – torek Jun 09 '22 at 19:28
  • Thanks for the `git check-ignore -v` command. It's golden! And, well, I thought I had read the manual, but now I read it again (after typing `git check-ignore --help` and it opened in a browser), and one line stands out: `If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.`. I new about `first` and `last`, but it's also relative to the .gitignore file if there is a / in the middle! That's the error! – SvendK Jun 09 '22 at 20:13
  • I have to state the full relative path if I need to unignore a folder previously ignored. That's the answer! It was right there, in the manual, all along? Who would have known. Thanks for getting back to me... – SvendK Jun 09 '22 at 20:14
  • I just found the real answer. `!**/NetTerminal/Log/`! Updated my question as I cannot put an answer. – SvendK Jun 09 '22 at 20:58

0 Answers0