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
preversion
script. We remove thedist
entry from.gitignore
.2 - npm bumps the version number and runs the
version
script. We build the project and add the files to git. - npm commits the files and tags the release, then runs the
postversion
script. We add thedist
entry back to.gitignore
and 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
sed
requires a file extension after the-i
flag because it saves a backup file with the given extension (Source). Since.gitignore
doesn’t have one, we provide the empty string. ↩︎Technically you could also prepend this to the
verison
script. Using all three version hooks makes it a bit more readable. ↩︎