lassen sie uns zunächst answe r die Frage, die du tatsächlich gestellt hast, weil du das sowieso wissen musst:
Wie kann ich nur den Code für das aktuelle Commit überprüfen, das committed werden soll?
Der Inhalt des commit-that-will-gemacht wird, was auch immer im Index ist.
Dies ist jede Datei, nicht nur Dateien Sie vor kurzem git add
Ed. Zum Beispiel, wenn Ihre Arbeitsbaum mit acht quellenkontrollierten *.py
Python-Dateien hat, und Sie geändert und git add
-ed zwei von ihnen, gibt es acht*.py
Dateien, die dieses Mal begangen werden. Jedes Commit hat jede Datei, und nicht eine Reihe von Änderungen von einigen früheren Datei (en).
Um diese acht Dateien (und nicht den aktuellen Inhalt des Arbeitsbaums) zu überprüfen, müssen Sie den Inhalt des Index irgendwo extrahieren.
Natürlich, das ist nicht das, was Sie eigentlich wollen:
überprüft er tatsächlich die gesamte Branche und wenn es irgendetwas in Zweig findet, die nicht PEP8 folgen wird, wird es beenden (das Repository ist ein bisschen alt und einige Code nicht folgen PEP8 von Anfang an, damit ich weiß, es Refactoring werden könnte, aber ich brauche nicht vorge Haken, mir zu sagen, dass über bereits engagierten Code)
Auch hier ist es nicht wirklich überprüfen die Verzweigung; es überprüft die Arbeitsstruktur. Dies hilft zwar nicht sofort, dorthin zu gelangen, wo es nötig ist, aber es ist wichtig.
Was wir hier brauchen, ist, vielleicht aus dem Index die Dateien zu extrahieren, die sich vom aktuellen Commit unterscheiden.
Der Weg, dies zu tun, ist ein neues Commit zu machen. Im Idealfall könnten wir dieses Commit irgendwo anders als auf dem aktuellen Zweig machen, denn wenn wir es auf dem Zweig machen, müssen wir es später wieder machen.
Es gibt einen Befehl, der das tut - das macht Commits vom Index, aber nicht auf einem Zweig - und dieser Befehl ist git stash
. Leider, there is a bug in git stash
wenn Sie es auf diese Weise verwenden. Anstatt die Umgehungslösungen zu verwenden, die ich in dieser Antwort beschreibe, können wir etwas anderes tun: Wir können unseren eigenen Baum in einem temporären Verzeichnis erstellen, nachdem wir den aktuellen Index mit dem HEAD
Commit verglichen haben.
Das Skript dafür (tatsächlich getestet, sogar!) Ist unten.
Hierher könnte man einwenden, dass git log -p
oder git show
zeigt Ihnen die Änderungen. Sie sind richtig, dass es Änderungen zeigt, aber es geschieht, indem Sie git diff
gegen eine vorherige commit ausführen, die auch jede Datei enthält. Durch den Vergleich der vorherigen Version von "everything" mit der nächsten Version von "everything" entdeckt git, was sich geändert hat.
#! /bin/sh
# run-checks: run some checking command(s) on a proposed commit.
#
# Optionally, run it only on files that differ from those in
# the current commit (added or modified, treating rename as
# modify), and/or do not run it at all if there are
# no such files (e.g., if the commit consists only of file
# removals).
usage()
{
echo "usage: $0 [-d] checkcmd [args ...]" 1>&2
exit 1
}
# probably should use git rev-parse feature now, oh well
diffmode=false
skipempty=true
while true; do
case "$1" in
-d|--diff) diffmode=true; shift;;
-z|--run-even-if-empty) skipempty=false; shift;;
-dz) diffmode=true; skipempty=false; shift;;
*) break;;
esac
done
case "$#" in
0) usage;;
esac
# from here on, exit on error
set -e
# get temporary directory and arrange to clean it up
tdir=$(mktemp -d -t run-checks)
trap "rm -rf $tdir" 0 1 2 3 15
# Get list of changed files (whether or not we are using
# only the changed files). This includes deleted files.
# For efficiency, we treat renames as delete/add pairs here.
# Require that new commit not match current commit.
if test $(git diff --cached --name-only --no-renames HEAD | wc -l) -eq 0; then
echo "no changes to test before committing"
exit 1
fi
# Populate work tree in temp dir. If we only want changed
# files, limit the checkout to files added or modified. Note
# that this list might be empty.
if $diffmode; then
git diff --cached --name-only --no-renames --diff-filter=AM -z HEAD |
xargs -0 git --work-tree=$tdir checkout -f --
else
git --work-tree=$tdir checkout -f -- .
fi
# Now run checker in temp work tree. Our exit status is
# its exit status. Do not use exec since we must still clean
# up the temp dir, and optionally skip checker if work tree is empty.
cd $tdir
if test $(ls -A | wc -l) -eq 0; then
is_empty=true
else
is_empty=false
fi
if $skipempty && $is_empty; then exit 0; fi
if $is_empty; then
[email protected]
else
[email protected] *
fi
Ist diese Frage nicht ganz beantworten, aber dies in http://pre-commit.com behandelt wird. Dieses Projekt verwendet eine Kombination von 'git diff --gestaged --name-only' und' git-checkout' + 'git apply' (im Wesentlichen ein Stash). –