2014-07-26 16 views
6

Ich versuche, einen Git-Pre-Commit-Hook hinzufügen, der alle geänderten und neuen Dateien für TODO: Text überprüfen wird.Durchsuchen von Dateien mit Vorab-Commit

Ich versuchte

#!/bin/sh 

. git-sh-setup # for die 
git-diff-index -p -M --cached HEAD -- | grep '^+' | 
grep TODO: && die Blocking commit because string TODO: detected in patch 
: 

dass ich in einer ähnlichen Frage sah, aber kein Glück.

+0

"Kein Glück" isn Es sind furchtbar hilfreiche diagnostische Informationen. Wenn etwas nicht wie erwartet funktioniert hat, erklären Sie bitte * wie * es nicht war - hat es beispielsweise eine Fehlermeldung ausgegeben? – cdhowie

+0

Ich habe es herausgefunden. Ich hatte kopiert, was in der 'pre-commit.sample'-Datei in eine reine Textdatei war, anstatt nur umzubenennen. Danke für die Hilfe @VonC – codingninja

+1

@jesusjjf OK, ich habe Ihre Schlussfolgerung in die Antwort für mehr Sichtbarkeit aufgenommen. – VonC

Antwort

8

Zunächst muss der Haken sein im .git/hook Ordner und Namen pre-commit (mit Ausführung rechts: chmod +x .git/hooks/pre-commit)

Die OP jesusjjf bestätigt in the comments, dass die Frage war:

ich kopiert hatte, was in der war pre-commit.sample Datei in eine einfache Textdatei, anstatt nur umzubenennen.

Zweitens sind hier einige Skriptbeispiele:


You have another example eine ähnliche Technik verwendet wird, unter Verwendung von git rev-parse und git diff-index und die 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 Erwähnung:

Auf meinem System if [ "grep 'debugger' $FILE" ] ergibt immer true.
Ändern Sie es zu if grep -q 'debugger' "$FILE" behebt das.


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 
+0

Versuchte den zweiten mit dem Array von verbotenem Text und hatte immer noch kein Glück.Muss meine Pre-Commit-Datei als Teil des Repos festgeschrieben werden, damit sie ausgelöst wird? – codingninja

+0

@jesusjjf no: Es muss sich im Ordner 'repo/.git/hooks' befinden,' pre-commit' genannt und ausführbar sein. Fügen Sie am Anfang ein Echo hinzu, um zu überprüfen, ob es ausgeführt wird. Hooks werden niemals festgelegt (oder sollten nicht: http://stackoverflow.com/a/3703207/6309) oder zwischen Repos (Push/Pull) geteilt werden. – VonC

+0

@jesusjjf von "kein Glück", ich nehme an, der Haken wird nicht ausgeführt, oder? Auf welchem ​​Betriebssystem bist du? Welche git-Version verwendest du? – VonC

1

Dieses Bit Schleifen über die Dateien, die in Szene gesetzt werden, ja, aber es greps dann die gesamte Datei unabhängig davon, welche Teile davon in Szene gesetzt werden!

git diff --cached --name-only | \ 
     grep -E $FILES_PATTERN | \ 
     echo 'COMMIT REJECTED Found' $i 'references. Please remove them before commiting' && exit 1 

Das ist nicht gut - nicht testen Strings, die nicht in Szene gesetzt werden.

Diese Lösung Tests einer oder mehr VERBOTEN Saiten gegen nur den Code inszeniert, nicht die gesamte Datei:

pre-commit

#!/bin/bash 

RESTORE='\033[0m' 
RED='\033[00;31m' 
YELLOW='\033[00;33m' 
BLUE='\033[00;34m' 

FORBIDDEN=('TODO:' 'DO NOT COMMIT' 'console.log' 'die') 
FOUND='' 

for j in "${FORBIDDEN[@]}" 
do 
    for i in `git diff --cached --name-only` 
    do 

    # the trick is here...use `git show :file` to output what is staged 
    # test it against each of the FORBIDDEN strings ($j) 

    if echo `git show :$i` | grep -q "$j"; then 

     FOUND+="${BLUE}$i ${RED}contains ${RESTORE}\"$j\"${RESTORE}\n" 

    fi 
    done 
done 

# if FOUND is not empty, REJECT the COMMIT 
# PRINT the results (colorful-like) 

if [[ ! -z $FOUND ]]; then 
    printf "${YELLOW}COMMIT REJECTED\n" 
    printf "$FOUND" 
    exit 1 
fi 

# nothing found? let the commit happen 
exit 0 

enter image description here

+0

Interessante Verwendung von 'Git-Show', genauer als meine Antwort. +1 – VonC