2

I am currently trying to exclude all contents of those 3 folders but keep the folders themselfs:

enter image description here

  • files/*
  • files/private/*
  • files/tmp/*

But for now just the files directory gets included. This is what my .gitignore looks like:

default-export/files/*
default-export/files/private/*
default-export/files/tmp/*

!default-export/files/.gitkeep
!default-export/files/private/.gitkeep
!default-export/files/tmp/.gitkeep
Basti
  • 666
  • 2
  • 11
  • 29
  • 1
    I see. So, you are trying to Preserve the Directory Structure while keeping the Files hidden? So that the other developer could have the same directory structure, right? – SNikhill May 31 '21 at 08:14
  • Yes exactly, I need this for a automated test setup. – Basti May 31 '21 at 08:15
  • Per git docs, "It is not possible to re-include a file if a parent directory of that file is excluded." Once you exclude `default-export/files/*`, which will exclude `default-export/files/private` and `default-export/files/tmp` directories, you cannot re-include `default-export/files/private/.gitkeep` and `default-export/files/tmp/.gitkeep`. EDIT: [more here](https://stackoverflow.com/a/9227991/240443). – Amadan May 31 '21 at 08:18
  • Does this answer your question? [How can I add an empty directory to a Git repository?](https://stackoverflow.com/questions/115983/how-can-i-add-an-empty-directory-to-a-git-repository) – Zeta May 31 '21 at 08:20
  • Alternately, just ignore the whole `files` directory, and force-add (`git add -f`) the `.gitkeep` files. Once the files are added, `.gitignore` has no power over them. – Amadan May 31 '21 at 08:20
  • @amadan, Tried that, sadly didnt work :) – Basti May 31 '21 at 08:21
  • @Zeta: Hm isnt that exactly what I have described within my question? – Basti May 31 '21 at 08:22
  • @Basti You only have a top-level `.gitignore`, if I'm not mistaken. The linked question suggests a `.gitignore` *per directory* that shall be left empty. – Zeta May 31 '21 at 08:23
  • `/default-export/files` in `.gitignore` and `git add -f **/.gitkeep && git commit` definitely works, I just tested it. – Amadan May 31 '21 at 08:29

2 Answers2

1

You are missing the explicit un-excludes of the directories private and tmp. Without them, Git does not further process the directory structure at all.

This should work according to your described requirements:

default-export/files/*
!default-export/files/.gitkeep
!default-export/files/private/
!default-export/files/tmp/

default-export/files/private/*
!default-export/files/private/.gitkeep

default-export/files/tmp/*
!default-export/files/tmp/.gitkeep
Matt
  • 12,848
  • 2
  • 31
  • 53
  • That does not work; files without extension still get listed due to `*.*`. Are you sure about that pattern? (Note that it might work for OP, if all their files have an extension) – Zeta May 31 '21 at 08:30
  • @Zeta I edited my answer which now works as expected. – Matt May 31 '21 at 08:53
0

Description

I shall like to clarify that the Folders don't hold great significance for Git. Simply speaking, they are just considered as "Links" to the files inside it.

Hence, an empty directory can't be staged.

In some cases, in order to preserve the directory structure, the directory needs to be added. The same can be achieved by placing a dummy file inside it.

Over the years, the dummy file has received the name .gitkeep (You can name it anything you want to. . is for hiding the same in a LINUX/UNIX System).

Solution to your Problem

You need to create the .gitkeep file and then, add the following lines to your .gitignore.

theEmptyDirectory/*

!.gitkeep

Here is the directory structure I used to test the same enter image description here

thisIsAPrivateFile represents the content I want to keep private while maintaining the directory structure.

And the git status (After staging) result. enter image description here

As you can clearly see, thisIsAPrivateFile has not been staged.

UPDATE

After Matt's comment, I shall like to inform a certain limitation of git. enter image description here

Basically, if the parent directory has been excluded, no matter what, any files inside the same can't be included. Since, in the above example, I have excluded everything (even nested directories) using * then, everything inside those nested directories won't be included.

We can bypass this limitation by specifying the types of files we want to exclude.

Here is the new directory structure

enter image description here

Updated .gitignore

theEmptyDirectory/**/*.js
theEmptyDirectory/**/*.jsx
theEmptyDirectory/**/*.ts

!.gitkeep

And the git status result (After Staging) enter image description here

Clearly, the directory structured has been preserved but, the private files have been exluded.

References

SNikhill
  • 446
  • 2
  • 8
  • 1
    The question is not just about a single folder but a nested folder structure where all contents of the parent folder of two subfolders should be excluded as well. – Matt May 31 '21 at 08:39
  • @Matt Yes, thank you for pointing out the same. I have updated the answer to include a workaround for the same. – SNikhill May 31 '21 at 09:04
  • The workaround does not handle files without extension, even when specifying `*.*`. – Matt May 31 '21 at 09:07
  • The mentioned limitation actually is the underlying problem why it did not work for @Basti. But this limitation does not apply when you explicitly un-exclude the parent directory as I do in my answer. – Matt May 31 '21 at 09:11
  • I see. `*.*` won't work as the pattern clearly has a `.` so, it will only work on `abc.` and not `abc`. – SNikhill May 31 '21 at 09:25
  • So, now Basti has two solutions: Either to explicitly include and exclude directories or, specify a type for even for extensionless files. E.G: `_IamExtensionLess`. – SNikhill May 31 '21 at 09:26