Skip to content

Commit 3573728

Browse files
committed
Add an option to stash changes before running hooks
In order to ensure any pre-commit tests are run against the files as they will appear in the commit, this commit adds an option to run `git stash` to save any changes to the working tree before running the scripts, then restore any changes after the scripts finish. The save/restore procedure is based on Chris Torek's StackOverflow answer to a question asking how to do exactly this.[1] This implementation does not do a hard reset before restoring the stash by default, since it assumes that if scripts modify tracked files the changes should be kept. But it does provide this behavior, and `git clean`, as configurable options. It follows the convention requested in observing#4 by making the new stash option default to off. Although there are no known implementation issues (with the exception of the git bug noted in Torek's SO answer), current scripts may expect modified/untracked files to exist or modify untracked files in a way which prevents applying the stash, making default-on behavior backwards-incompatible. The tests are split into a separate file. Since each stash option is tested against a project repository and a clean/reset is done between each test, the tests are somewhat slow. By splitting the tests into a separate file, we can avoid running them by default. They can instead be run as test-stash, as part of test-all, and as part of test-travis. This commit is based off of the work of Christopher Hiller in observing#47, although the implementation differs significantly due to the use of Promises in place of async, which I found to be significantly clearer, more flexible, and they make the tests significantly more concise. Fixes: observing#4 1. https://stackoverflow.com/a/20480591 Signed-off-by: Christopher Hiller <boneskull@boneskull.com> [kevin@kevinlocke.name: Reimplement using Promises and Torek's method] Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
1 parent 8ab4d7c commit 3573728

File tree

5 files changed

+817
-26
lines changed

5 files changed

+817
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
npm-debug.log
33
coverage
44
.tern-port
5+
test-repo/

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ should be ran you can also configure the following options:
100100
- **colors** Don't output colors when we write messages. Should be a boolean.
101101
- **template** Path to a file who's content should be used as template for the
102102
git commit body.
103+
- **stash** Run `git stash` to stash changes to the working directory prior to
104+
run and restore changes after. This can be useful for checking files as they
105+
will appear in the commit without uncommitted changes and files. It can also
106+
cause rebuilds or reloads due to file changes for editors and watch scripts
107+
and has some ([known issues](https://stackoverflow.com/a/20480591/503410)).
108+
The value can be a boolean or an options object with the following properties:
109+
- **clean** Run `git clean` before re-applying the stashed changes.
110+
When combined with `includeUntracked`/`includeAll`, this would delete
111+
any files files created by the scripts. In particular ones which would
112+
prevent applying the stash if they exist in the working dir and stash.
113+
- **includeAll** Include all files (both untracked and ignored) in stash
114+
(and clean, if run). This is almost never what you want, since it will
115+
stash `node_modules` among other things.
116+
- **includeUntracked** Include untracked files in stash. This is useful to
117+
exclude untracked js files from linting, but carries some risk of losing
118+
[untracked files](http://article.gmane.org/gmane.comp.version-control.git/263385/)
119+
or [directories which become
120+
empty](http://thread.gmane.org/gmane.comp.version-control.git/254037)
121+
or [files/directories changing ignore
122+
status](http://thread.gmane.org/gmane.comp.version-control.git/282324)
123+
or creating a stash which [requiring manual intervention to
124+
apply](http://article.gmane.org/gmane.comp.version-control.git/285403).
125+
Also, it takes extra effort to [view untracked files in the
126+
stash](https://stackoverflow.com/a/22819771).
127+
- **reset** Run `git reset --hard` before re-applying the stashed changes.
128+
This would revert any changes to tracked files made by the scripts.
103129

104130
These options can either be added in the `pre-commit`/`precommit` object as keys
105131
or as `"pre-commit.{key}` key properties in the `package.json`:

0 commit comments

Comments
 (0)