How to print all the staged file names using ruby git pre-commit hook?
One possible command is (from "Git pre-commit hook : changed/added files"):
git diff --cached --name-only --diff-filter=ACM
That is what I recommended for that other ruby pre-commit hook"
And you could use it with "jish/pre-commit
".
Git pre-commit hook
You should rather grep on indexed (cached) files, instead of your working tree.
Otherwise, your grep could find debug instructions in files (or part of files) which aren't part of the next commit.
See "Git pre-commit hook : changed/added files":
git diff --cached --name-only --diff-filter=ACM
As explained in "Why You Need a Git Pre-Commit Hook and Why Most Are Wrong":
Most test against whatever files are currently on disk, not what is in the staging area (the files actually being committed).
The approach if that hook is a bit different: it stashes every work in progress before searching the files.
def main(all_files):
# Stash any changes to the working tree that are not going to be committed
subprocess.call(['git', 'stash', '-u', '--keep-index'], stdout=subprocess.PIPE)
pre-commit hook doesn't check if saved changes are staged before running
If I understood your problem correctly, you need to have files as they are in index at hand.
To do so, you can do git stash -k
(keeping index) before running your utility and git stash pop
afterwards assuming it won't change anything so that no conflicts would appear.
Searching files with pre-commit
First, the hook must be in the .git/hook
folder and name pre-commit
(with execution right: chmod +x .git/hooks/pre-commit
)
The OP jesusjjf confirms in the comments that was the issue:
I had copied what was in the
pre-commit.sample
file onto a plain text file, instead of just renaming.
Second, here are some script examples:
You have another example using a similar technique, using git rev-parse
and git diff-index
, and the empty tree I mentioned before:
#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
for FILE in `git diff-index --name-status $against -- | cut -c3-` ; do
# Check if the file contains 'debugger'
if [ "grep 'debugger' $FILE" ]
then
echo $FILE ' contains debugger!'
exit 1
fi
done
exit
The comments on this gist mention:
On my system, if [ "grep 'debugger' $FILE" ]
always evaluates to true
.
Changing it to if grep -q 'debugger' "$FILE"
fixes that.
A more recent example:
#!/bin/bash
# Pre commit hook that prevents FORBIDDEN code from being commited.
# Add unwanted code to the FORBIDDEN array as necessary
FILES_PATTERN='\.(rb|js|coffee)(\..+)?$'
FORBIDDEN=( debugger ruby-debug )
for i in "${FORBIDDEN[@]}"
do
git diff --cached --name-only| grep ".js" |xargs sed 's/ //g'|grep "ha_mobile.debug=true" && \
echo 'COMMIT REJECTED Found ha_mobile.debug=true references. Please remove them before commiting' && exit 1
git diff --cached --name-only | \
grep -E $FILES_PATTERN | \
GREP_COLOR='4;5;37;41' xargs grep --color --with-filename -n $i && \
echo 'COMMIT REJECTED Found' $i 'references. Please remove them before commiting' && exit 1
done
exit 0
Git pre-commit hook issue
Judging by other git hooks (like "pre-commit/utils/staged_files.rb
" or "i-wind/gpc/pre-commit.rb
", you don't need to prepend with the root folder of the repo.
file_text = File.read(File.join(file))
How to write an update hook for git submodules?
The update
hook is only run when someone has pushed into the current repository, which doesn't sound like what you want. You could use the post-commit
hook, if you want to copy these files into place every time you create a commit in your repository. (That should be sufficient, because you'd need to commit the new version of any submodule in the main project when you change the commit that the submodule is meant to be at. This would be a natural point to update the files in public/assets
.)
You say that your test hook isn't being run - that may be simply because you have the name wrong. The update hook must be an executable file called .git/hooks/update
(n.b. without a .rb
suffix). Similarly, a post-commit hook must be .git/hooks/post-commit
.
You shouldn't create hooks in any particular submodule for this task, since the action the hook will be taking is specific to the main project. Because of that, it doesn't really matter whether the change you're worried about it due to committing a new version of the submodules or just updating any random file.
For writing hooks, you'll find the official githooks documentation useful, and possibly these additional tips.
Understanding git commit --only and pre-commit hooks
The precise details vary from one version of Git to another, and some people—I'm not saying the JetBrains folks are among them, as I have no idea—have tried to bypass the way Git does things and in the process, screwed things up such that either they can't be worked-around, or the work-around is Git-version-dependent. However, the main idea in these Git hooks is all the same:
- the index contains the commit-to-make, and
- the work-tree contains the work-tree.
These two need not be in sync when you first run git commit
, and if you add files to the git commit
command, with either --only
or --include
, Git must then make a new index, which may differ from the regular ordinary index. So now we wind up with an environment variable, GIT_INDEX_FILE
, set to the path of a new, temporary index.1 Since all Git commands automatically respect the environment variables, the pre-commit hook will use the temporary index's files, and git write-tree
will use the temporary index's files.
Of course, anything that fails to respect the temporary index—or, potentially, depending on --include
vs --only
, just uses the contents of the work-tree—will get the wrong answer.
There is still a problem, though, even with programs that do respect the environment variables. Suppose we have a file—let's call it test
since that's its purpose—that initially contains "headvers", and matches the current (HEAD
) commit. Now we modify it in the work-tree to contain "indexvers" and run git add test
. The index version of test
thus reads "indexvers". Now we modify it again in the work-tree, to contain "workvers", and run either git commit --only test
or git commit --include test
.
We know for sure what should go into the new commit: it should be the version of test containing workvers
, because we specifically told Git to commit the work-tree version. But what should be left in the index and work-tree afterward? Does this depend on whether we used --include
vs --only
? I don't know what to consider the "right" answer here! All I can tell you is that when I experimented with Git before, it tended to contain workvers
afterward (both in the index, and in the work-tree). That is, the temporary index's version became the normal index's version, and the work-tree file was untouched.
(If you have Git hooks that manipulate the index and/or work-tree, you will be able to pry open the difference between "copying index to saved-index, then copying back" vs "copying index to temp-index, then using temp-index".)
1This was the actual implementation at one time, when I was testing various behaviors, but it's possible that the actual implementation has changed a bit. For instance, Git could save the "normal" index in a temporary file and then replace the normal index, so that GIT_INDEX_FILE
is not set after all. And, again, it may depend on --include
vs --only
.
Note that git commit -a
may also use a temporary index, or not. I believe this behavior has changed between Git 1.7 and Git 2.10, based on the result of running git status
in another window while still editing the commit message in the window that was running git commit -a
.
Related Topics
Import CSV in Batches of Lines in Rails
How to Create Two Routes in One Block in Grape
Rails Object Based Permission/Authorization Engine
Rails Adding Multiple Objects to an Empty Array
Why Can't We Override '||' and '&&'
How to Efficiently Extract Repeated Elements in a Ruby Array
How to Collapse Double Splat Arguments into Nothing
Gem Install Debugger -V '1.5.0' Fails
Override a Method Inside a Gem from Another Gem
How to Use String Methods on Utf-8 Characters
Any Standard Guide for Ruby Win32Ole API
Where Does Rails Store Data Created by Saving Activerecord Objects During Tests
Bundle Install Is Using a Different Ruby Version
Spring Doesn't Work. [ Uninitialized Constant Spring::Sid::Dl ]