How to Include Certain Files Only in Tagged Commits
Certain situations and tools require that we check-in build artifacts into a git repository, maybe even on the master branch. This is bad practice for a variety of reasons, but sometimes we can’t avoid it.
Certain situations and tools (cough, bower, cough) require that we check-in build artifacts into a git repository, maybe even on the master branch. This is bad practice for a variety of reasons, but sometimes we can’t avoid it.
However, we can hack our way around cluttering the history too much, using a few quick-and-dirty npm scripts.
For this post we assume that we want to check-in the dist folder only on tagged commits, which we create with the npm version command.
First, we add /dist to our .gitignore file, which tells git to ignore the top-level dist folder.
In package.json we add the following scripts:
{
"scripts": {
"preversion": "sed -i '' 's:/dist:#/dist:' .gitignore",
"version": "npm run build && git add .",
"postversion": "sed -i '' 's:#/dist:/dist:' .gitignore && git rm --cached -r dist && git add . && git commit -m 'restore pre-version .gitignore'"
}
}
The sed command allows us to run a quick regex search-and-replace on a file.1 I used : as a delimiter (instead of /) to make writing regexes that involve file paths easier.
The first regex looks for the dist entry and replaces it with something we can find later (we prepend a # so the file remains a valid .gitignore). The second regex does the reverse.
The execution order is as follows:
- npm runs the
preversionscript. We remove thedistentry from.gitignore.2 - npm bumps the version number and runs the
versionscript. We build the project and add the files to git. - npm commits the files and tags the release, then runs the
postversionscript. We add thedistentry back to.gitignoreand remove the build files from git in a follow-up commit.
The git history for every tagged release will look like this:
* ac58cf4 2018-04-06 | restore pre-version .gitignore (HEAD -> master)
* a8989f1 2018-04-06 | 1.2.3 (tag: v1.2.3)
This procedure still adds a lot of clutter to to the git history, but at least it is limited to tagged commits, and we aren’t at risk of checking in (development-) artifacts by accident.
BSD
sedrequires a file extension after the-iflag because it saves a backup file with the given extension (Source). Since.gitignoredoesn’t have one, we provide the empty string. ↩︎Technically you could also prepend this to the
verisonscript. Using all three version hooks makes it a bit more readable. ↩︎