Reputation: 3414
I have a gulp task that pipes assets into a directory. I would like to include the directory in my project, but exclude the outputted files through a .gitignore
file. My gulp task looks like this:
gulp.task('styles', function() {
return sass('app/scss/styles.scss')
.pipe(cleanCSS())
.pipe(gulp.dest('public/stylesheets'))
.pipe(livereload());
});
gulp.task('scripts', function() {
gulp.src('app/js/script.js')
.pipe(webpack(require('./webpack.config.js')))
.pipe(uglify())
.pipe(gulp.dest('public/javascripts'))
.pipe(livereload());
});
Folder structure:
app
---js
---scss
public(NEED TO KEEP THIS)
---javascripts(NEED TO KEEP THIS)
-----scrpits.min.js**(NEED TO IGNORE THIS)**
---stylesheets(NEED TO KEEP THIS)
-----styles.css**(NEED TO IGNORE THIS)**
So in .gitignore
if I go:
/public
That ignores everything, which is not what I want.
I found this question: How can I add an empty directory to a Git repository? and someone suggested a "workaround" with 54 upvotes:
"Andy Lester is right, but if your directory just needs to be empty, and not empty empty, you can put an empty .gitignore file in there as a workaround..."
So now I go:
app
---js
---scss
public(NEED TO KEEP THIS)
---javascripts(NEED TO KEEP THIS)
-----scrpits.min.js**(NEED TO IGNORE THIS)**
-----.gitignore
---stylesheets(NEED TO KEEP THIS)
-----styles.css**(NEED TO IGNORE THIS)**
-----.gitignore
And took a suggestion from the accepted answer and did:
/public/!.gitignore
But still is not getting the desired result.
How can I commit an output folder to a repository for a gulp task?
Upvotes: 2
Views: 4102
Reputation: 3414
Ok I figured it out:
/public/**/*.js
/public/**/*.css
Essentially, any file in any folder below one level in /public should be ignored.
Upvotes: 4
Reputation: 489678
Git doesn't store directories (aka folders) at all, it only stores files within a commit. When Git goes to check out a commit, if some file within that commit requires that some parent directory exist, Git makes that parent directory at that point. So that's why you need to commit the file .gitignore
, or anyway some file, within the directory: so that Git has some file it's extracting, that forces it to create the directory.
Now, the problem here is that when Git is doing its "run as fast as possible even if that confuses everyone" :-) tricks, it may discover that a .gitignore
lists a directory name and that it—specifically, Git's index—has no files already within that directory, and it will then not even bother to look inside the directory for files. This is how git add
skips right over the !public/.gitignore
directive: while it was looking around, it found public
as a directory but had no files in it to be committed yet, then found public
in .gitignore
, and decided not to look inside public
at all.
If, instead of listing public
in your .gitignore
, you list public/*
, Git has to look inside public
to find all its files and sub-directories to see if they can be skipped. Having looked inside, it will check public/.gitignore
against the .gitignore
contents. The public/*
entry will say "skip it" but the later !public/.gitignore
entry will say "don't skip it". The later entry then overrides, and public/.gitignore
gets stuffed into Git's index by git add --all
or git commit --all
.
Once public/.gitignore
is in the index, it goes into the next commit. Once that's happened, it's actually safe to list public
rather than public/*
in the .gitignore
file, because now that Git has a file in the directory, Git is forced to scan the directory. The entry for public/.gitignore
will only be removed from the index again by an explicit request to remove that entry (git rm public/.gitignore
or git rm --cached public/.gitignore
), or by moving to (git checkout
-ing) an existing commit in which there is no public/.gitignore
file. Once the index entry is removed, it's no longer safe to list public
rather than public/*
, because Git can go back to its trick of noticing that public
is a directory and is ignored and Git has nothing forcing Git to look inside public
, so that it doesn't look inside and doesn't find public/.gitignore
and hence doesn't check for the exception.
There are of course other ways to do the same thing. My preference is not to list the directory at all in the top level: instead, inside the public
directory, create a .gitignore
file with the contents:
*
!.gitignore
Git will then have to scan the public
directory for files, since it's not ignored; that directory then has a .gitignore
file, and that .gitignore
file says: ignore everything here, except for .gitignore
here. Since Git has already gone inside the directory at this point, and has found a list of all files and sub-directories within that directory, it will check each such file and sub-directory individually against this .gitignore
and ignore all of them except for .gitignore
itself.
Upvotes: 2
Reputation: 521
To exclude files in a sub-directory, append the following to a .gitignore in your base directory:
/public/scrpits.min.js
/public/styles.css
/sub-directory/file.whatever
etc...
If that's the only item in the folder and you need to keep that folder active, maybe place a blank text file in it
Upvotes: 0