2013-10-03 10 views
12

Ich weiß, Entfernen von Leerzeichen nach hinten kann mit einem Pre-Commit-Hook erfolgen. Ich bin daran interessiert, es manuell zu tun. Ich lese die Frage hier:
Make git automatically remove trailing whitespace before committing - Stack Overflow
Die Antwort am nächsten, was ich will, ist the "automatic version" from ntc2:

git entfernen Sie nachträgliche Leerzeichen in neuen Dateien vor dem Commit

(export VISUAL=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset 


Das funktioniert gut, außer es gebieten scheint nur für Änderungen an Dateien, die bereits sind im Repo keine neuen Dateien. Ich habe eine Reihe von Dateien, die neu sind, was bedeutet, dass sie noch nicht im Repo sind. Ich möchte Whitespace aus diesen Dateien entfernen, also habe ich Add-A anstelle von -u versucht, aber das hat keinen Unterschied gemacht.

+1

Meinst du "' git add -Ae' fügt keine neuen Dateien hinzu? " Oder: "Die Dateien sind hinzugefügt, aber nicht behoben"? – VonC

+0

@VonC Es funktioniert nicht für Dateien, die nicht geparkt oder neu sind (zum ersten Mal hinzugefügt, aber noch nicht festgeschrieben). Für mich zeigt es 'fatal: Leerer Patch. Abgebrochen. "Ich verwende git Version 1.8.3.msysgit.0. – loop

+0

@test: Wenn du einen Kommentar zu meiner ursprünglichen Antwort hinterlassen hättest, entweder gefragt hast, wie ich meinen Befehl ausführen soll oder auf deine Frage verlinken würde, hätte ich eine Benachrichtigung erhalten und dir von 'add -N 'erzählt. Aber, SO war schlau genug, Ihre Frage in den Abschnitt "Verwandte" zu stellen, also sah ich es, als ich meine Antwort heute redigierte. – ntc2

Antwort

30

manuell Leerzeichen aus Ihrem letzten 3 Commits aufzuräumen, können Sie dies tun:

git rebase --whitespace=fix HEAD~3

Wenn ich zu einem Thema Zweig arbeiten, ich habe den Upstream-Zweig Spur (in der Regel durch das so zu schaffen)

git checkout -b topic -t

Das erlaubt mir, das letzte Argument von git rebase fallen zu lassen. Also, wenn ich & bereit bin fertig zu fusionieren, ich das ganze Thema astrein kann schnell mit:

git ws # --whitespace rebase aliased = fix

Beachten Sie, dass im Gegensatz zu dem HEAD ~ 3 Beispiel des Ändert die Änderungen in der Upstream-Zweigstelle, wenn sie geändert wird! (Aber das ist auch das, was ich will, in meinem Workflow.)

+0

Luke, der funktioniert, aber weißt du warum Ich kann den Befehl, über den ich in meiner Frage gefragt habe, nicht verwenden. – loop

+0

Beats me, fürchte ich; Aber da whitespace = fix für die Anwendung von Patches (einschließlich Rebase) gedacht ist, überrascht es mich nicht, dass Nigger entstehen. Das Entfernen von Dateien aus nicht verfolgten Dateien ähnelt dem Bearbeiten von Dateien außerhalb des Repos: Dies ist kein Job von git. –

+2

Hey, hier ist etwas, das ich gerade erfunden habe (von grundlegenden Befehlen), um nur die abgestuften Änderungen aufzufrischen (die Auswahl der hinzugefügten Dateien bleibt intakt): 'git commit -mTemp && git stash && git rebase HEAD ~ --whitespace = fix && git reset --soft HEAD ~ && git stash pop'. –

2

Einfach fix

Der Befehl Sie

zitierte
(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset 

funktioniert, wenn Sie zuerst die Dateien hinzufügen, die Sie mit git add -N <files you want to fix> korrigieren möchten. Die add -N weist Git im Wesentlichen an, so zu tun, als hätten Sie zuvor leere Versionen der Dateien festgelegt.

Fehler hast du

Ich verstehe nicht, warum Sie fatal: Empty patch. Aborted. Fehler bekommen mit add -Ae, aber es sieht aus wie ein Fehler, da Ebene tun git add -A . && git diff --cached zeigt, dass der Patch sollte eigentlich nicht leer sein.

Bessere Leerzeichen fixe

ich vor kurzem für die Befestigung Leerzeichen my answer that you linked to mit einem besseren Git-Alias ​​aktualisiert.Hier ist ein Umschreiben der alias mit Luke's rebase trick und ein weniger redundanten Kontrollfluss:

fixws =!"\ 
    if (! git diff-index --quiet --cached HEAD); then \ 
    \ 
    git diff-files --quiet `git rev-parse --show-toplevel` ; \ 
    export NEED_TO_STASH=$? ; \ 
    \ 
    git commit -m FIXWS_SAVE_INDEX && \ 
    if [ 1 = $NEED_TO_STASH ] ; then git stash save FIXWS_SAVE_TREE; fi && \ 
    git rebase --whitespace=fix HEAD~ && \ 
    git reset --soft HEAD~ && \ 
    if [ 1 = $NEED_TO_STASH ] ; then git stash pop; fi ; \ 
    fi" 

Dies behebt Leerzeichen im Index, während die Index Erhaltung und verlassen den Baum unberührt. Mit diesem Alias ​​können Sie unversionierte Dateien im Repo-fix mit

git add --all :/ && git fixws && git reset 

Aber es ist auch für den häufigeren Fall der Festsetzung up Leerzeichen in einem begehen Sie gerade arbeiten. Es ist kompliziert, weil es auch funktioniert, wenn der Index oder der Baum sauber sind.

+0

Wenn das den Baum unberührt lässt, bedeutet das nicht, dass irgendwelche Whitespaces im Index angezeigt werden in "git diff" umgekehrt, und wird zurückgesetzt, wenn Sie betroffene Dateien zum Index hinzufügen? Ich vermute, das ist der Grund, warum du 'git reset' in deiner Pipeline hast, aber es scheint so zu sein, dass der Vorteil, den Baum unberührt zu lassen, aufgehoben wird. – jbyler

+0

@jbyler: Wenn Sie sich auf das 'reset' in der' add', 'fixws',' reset' Combo beziehen, dann ist der Punkt, die anfängliche 'add' rückgängig zu machen. Beachten Sie, dass das Standardreset '--mixed' ist, das nur den Index und nicht den Baum berührt. – ntc2

+0

Hallo, ich habe heute deinen Alias ​​hinzugefügt und habe deine bessere Whitespace-Fixierer-Befehlszeile ausprobiert. Es funktionierte ursprünglich nicht, weil ich zuvor den Pre-Commit-Hook aktiviert hatte, um Whitespaces zu erfassen. Ich habe geahnt, was passiert ist, also habe ich das deaktiviert und dann deinen Befehl ausgeführt und es hat funktioniert. Danke noch einmal! – loop

6

Ich mag Lukes Antwort, mit der Ausnahme, dass Sie entweder die Basis-Commit manuell angeben müssen, oder verwenden Sie einen Workflow im Rebase-Stil, wo Ihre Geschichte linearisiert wird. Ich schlage eine Modifikation vor, die kein zusätzliches Argument benötigt und die Topologie Ihres Commit-Graphen nicht ändert. Als Shell-Befehl:

git rebase --whitespace=fix --onto $(git merge-base HEAD @{u}) 

Oder als ~/.gitconfig alias:

ws = "!git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})" 

ich dies vorziehen, weil manchmal möchte ich meine Änderungen rebase, aber wenn ich denke, denke, es könnte eine Zusammenführung sein Konflikt Ich ziehe es vor zu verschmelzen, so dass sowohl meine ursprüngliche Änderung als auch die Konfliktlösung in der Geschichte aufgezeichnet werden. So kann ich später die Konfliktlösung nachholen und bei Bedarf wiederholen.

Da ich nicht immer rebase, ich bevorzuge nicht whitespace-fixing mit Rebasing mischen; daher diese Modifikation zu Lukas Antwort.

Zusätzlich aktiviere ich die Standard-Haken pre-commit, die auf Leerzeichen Fehler abgebrochen:

cp .git/hooks/pre-commit.sample .git/hooks/pre-commit 

Dieses den folgenden Workflow gibt, die Ich mag, weil es manuell genug ist, dass ich weiß, was los ist, aber automatisiert genug nicht in die Quere zu kommen:

  1. Hack Hack Hack, einführen Leerzeichen Fehler
  2. Versuch mit w
  3. verpflichten nicht zu begehen hitespace Fehler aufgrund von pre-commit Haken
  4. git commit --no-verify zu begehen sowieso
  5. git ws den Alias ​​verwenden

Hinweis auf die Verwendung von --onto zu beheben: Es ist hier nicht nötig, aber ich finde es einfacher, über die Vernunft wie funktioniert das Rebase? In Lukes Version HEAD~3 ist die <upstream> in der man-Seite, während in meiner Version <upstream> behält seinen Standardwert der realen upstream der Branche. Sie landen jedoch mit dem gleichen Ergebnis.

+0

Nette Verwendung der '--onto' dort. +1 – VonC