Wie man ‘git diff’ dazu bringt, Kommentare zu ignorieren

Lesezeit: 9 Minuten

Wie man git diff dazu bringt Kommentare zu ignorieren
Benuvogel

Ich versuche, eine Liste der Dateien zu erstellen, die in einem bestimmten Commit geändert wurden. Das Problem ist, dass jede Datei die Versionsnummer in einem Kommentar am Anfang der Datei hat – und da dieser Commit eine neue Version einführt, bedeutet das das Jede Datei hat sich geändert.

Die geänderten Kommentare sind mir egal, also hätte ich sie gerne git diff Ignorieren Sie alle übereinstimmenden Zeilen ^s**.*$da dies alles Kommentare sind (Teil von /* */).

Ich kann keine Möglichkeit finden, das zu sagen git diff bestimmte Zeilen zu ignorieren.

Ich habe bereits versucht, ein textconv-Attribut zu setzen, um Git dazu zu bringen, die Dateien an sed zu übergeben, bevor es sie unterscheidet, damit sed die anstößigen Zeilen entfernen kann – das Problem dabei ist das git diff --name-status unterscheidet die Dateien nicht wirklich, sondern vergleicht nur die Hashes, und natürlich haben sich alle Hashes geändert.

Gibt es eine Möglichkeit, dies zu tun?

  • Eine wilde Vermutung … Hast du es versucht? git diff --name-status --textconv? Oder vielleicht git diff --name-only?

    – rodrigo

    13. Mai ’13 um 16:55 Uhr


  • Ja, ich verwende –name-only, aber es gibt (wie gesagt) jede Datei zurück, weil bei jeder Datei die Kommentare geändert wurden. –textconv funktioniert nicht, weil, wie ich auch im Beitrag sagte, git es ignoriert, wenn es kein vollständiges Diff erzeugt.

    – Benuvogel

    13. Mai 13 um 17:04 Uhr

  • mögliches Duplikat des Ignorierens von Änderungen, die mit einer Zeichenfolge in git diff übereinstimmen

    – richvdh

    23. Juni 15 um 14:08 Uhr

  • @richvdh Ich denke, die Fragen sind ähnlich genug, um als Duplikat betrachtet zu werden, ABER sie haben unterschiedliche richtige Antworten, und diese Frage enthält zusätzliche Antworten, die Vorschläge machen, die das andere Q nicht hat, daher glaube ich, dass es sinnvoll ist, beide zu behalten.

    – Benuvogel

    23. Juni 15 um 15:23 Uhr

  • Verwandte: Git 2.30 (Q1 2021) wird vorschlagen git diff -I<regex>.

    – VonC

    9. November 20 um 20:16 Uhr

Wie man git diff dazu bringt Kommentare zu ignorieren
phyatt

Hier ist eine Lösung, die für mich gut funktioniert. Ich habe die Lösung und einige zusätzliche fehlende Dokumentationen aufgeschrieben git (log|diff) -G<regex> Möglichkeit.

Es wird im Grunde dieselbe Lösung wie in den vorherigen Antworten verwendet, jedoch speziell für Kommentare, die mit a beginnen * oder ein #und manchmal ein Leerzeichen vor dem *… Aber es muss noch zulassen #ifdef, #includeetc. Änderungen.

Der Blick nach vorn und der Blick nach hinten scheinen von dem nicht unterstützt zu werden -G Option noch die ? im Allgemeinen, und ich hatte Probleme mit der Verwendung *auch. + scheint aber gut zu funktionieren.

(Hinweis, getestet auf Git v2.7.0)

Mehrzeilige Kommentarversion

git diff -w -G'(^[^*# /])|(^#w)|(^s+[^*#/])'
  • -w Leerzeichen ignorieren
  • -G nur Diff-Zeilen anzeigen, die mit der folgenden Regex übereinstimmen
  • (^[^*# /]) jede Zeile, die nicht mit einem Stern, einer Raute oder einem Leerzeichen beginnt
  • (^#w) jede Zeile, die mit beginnt # gefolgt von einem Buchstaben
  • (^s+[^*#/]) jede Zeile, die mit einem Leerzeichen beginnt, gefolgt von einem Kommentarzeichen

Grundsätzlich ändert ein SVN-Hook jetzt jede Datei ein und aus und modifiziert mehrzeilige Kommentarblöcke in jeder Datei. Jetzt kann ich meine Änderungen mit SVN ohne die FYI-Informationen vergleichen, die SVN in den Kommentaren ablegt.

Technisch ermöglicht dies Python- und Bash-Kommentare wie #TODO im Diff angezeigt werden, und wenn ein Divisionsoperator in C++ in einer neuen Zeile beginnt, kann er ignoriert werden:

a = b
    / c;

Auch die Dokumentation auf -G in Git schien ziemlich mangelhaft zu sein, daher sollten die Informationen hier helfen:

git diff -G<regex>

-G<regex>

Suchen Sie nach Unterschieden, deren Patch-Text hinzugefügte/entfernte Zeilen enthält, die übereinstimmen <regex>.

Um den Unterschied zwischen zu veranschaulichen -S<regex> --pickaxe-regex und -G<regex>betrachten Sie einen Commit mit dem folgenden Unterschied in derselben Datei:

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

Während git log -G"regexec(regexp" wird dieses Commit zeigen,
git log -S"regexec(regexp" --pickaxe-regex nicht (da sich die Anzahl der Vorkommen dieser Zeichenfolge nicht geändert hat).

Siehe die Spitzhacke Eintrag ein gitdiffcore(7) für mehr Informationen.

(Hinweis, getestet auf Git v2.7.0)

  • -G verwendet einen einfachen regulären Ausdruck.
  • Keine Unterstützung für ?, *, !, {, } Syntax regulärer Ausdrücke.
  • Gruppieren mit () und ODER-Gruppen arbeitet mit |.
  • Platzhalterzeichen wie z s, Wusw. werden unterstützt.
  • Look-Ahead und Look-Behind sind nicht unterstützt.
  • Anfangs- und Endlinienanker ^$ arbeiten.
  • Feature ist seit Git 1.7.4 verfügbar.

Ausgeschlossene Dateien v Ausgeschlossene Unterschiede

Notiere dass der -G Option filtert die Dateien, die verglichen werden.

Aber wenn eine Datei “verschieden” wird, werden die Zeilen, die vorher “ausgeschlossen/eingeschlossen” waren, auch alle im Diff angezeigt werden.

Beispiele

Zeige nur Dateiunterschiede mit mindestens einer Zeile, die erwähnt foo.

git diff -G'foo'

Dateiunterschiede für alles außer Zeilen anzeigen, die mit a beginnen #

git diff -G'^[^#]'

Dateien anzeigen, die Unterschiede aufweisen FIXME oder TODO

git diff -G`(FIXME)|(TODO)`

Siehe auch git log -G, git grep, git log -S, --pickaxe-regexund --pickaxe-all

UPDATE: Welches Tool für reguläre Ausdrücke wird von der Option -G verwendet?

https://github.com/git/git/search?utf8=%E2%9C%93&q=regcomp&type=

https://github.com/git/git/blob/master/diffcore-pickaxe.c

if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) {
    int cflags = REG_EXTENDED | REG_NEWLINE;
    if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE))
        cflags |= REG_ICASE;
    regcomp_or_die(&regex, needle, cflags);
    regexp = &regex;

// and in the regcom_or_die function
regcomp(regex, needle, cflags);

http://man7.org/linux/man-pages/man3/regexec.3.html

   REG_EXTENDED
          Use POSIX Extended Regular Expression syntax when interpreting
          regex.  If not set, POSIX Basic Regular Expression syntax is
          used.

// …

   REG_NEWLINE
          Match-any-character operators don't match a newline.

          A nonmatching list ([^...])  not containing a newline does not
          match a newline.

          Match-beginning-of-line operator (^) matches the empty string
          immediately after a newline, regardless of whether eflags, the
          execution flags of regexec(), contains REG_NOTBOL.

          Match-end-of-line operator ($) matches the empty string
          immediately before a newline, regardless of whether eflags
          contains REG_NOTEOL.

  • Es sieht so aus, als ob es “Simple Regular Expression” ähnlich ist. en.wikibooks.org/wiki/Regular_Expressions/…

    – phyatt

    24. April 17 um 12:52 Uhr

  • Das kann nicht ganz richtig sein, da es eine nicht einfache Syntax akzeptiert, wie z + (Habe ich gerade getestet).

    – Emadpres

    24. April 17 um 13:18 Uhr


  • Siehe Update am Ende meiner Antwort. Ich habe die “POSIX erweiterten regulären Ausdrücke” nicht erfolgreich getestet. Meine empirischen Tests haben gezeigt, dass es nicht ganz gleich funktioniert.

    – phyatt

    24. April 17 um 13:51 Uhr

  • @phyatt – das scheint nicht zu funktionieren: git diff -G'^[^#]'. Es zeigt immer noch Zeilen, die mit beginnen #.

    – Martin Vegetar

    24. August 19 um 5:54 Uhr

  • @MartinVegter Die Syntax wird weiterhin angezeigt, wenn die Datei mindestens einen weiteren Unterschied aufweist. Wenn eine Datei nur Kommentarunterschiede aufweist, wird die Datei in den Ergebnissen ausgeschlossen.

    – phyatt

    24. August 19 um 12:17 Uhr


1644321010 775 Wie man git diff dazu bringt Kommentare zu ignorieren
Riezebosch

git diff -G <regex>

Und geben Sie einen regulären Ausdruck an, der dies tut nicht mit Ihrer Versionsnummernzeile übereinstimmen.

Wie man git diff dazu bringt Kommentare zu ignorieren
richvdh

Ich fand es am einfachsten zu bedienen git difftool So starten Sie ein externes Diff-Tool:

git difftool -y -x "diff -I '<regex>'"

Wie man git diff dazu bringt Kommentare zu ignorieren
Benuvogel

Ich habe eine Lösung gefunden. Ich kann diesen Befehl verwenden:

git diff --numstat --minimal <commit> <commit> | sed '/^[1-]s+[1-]s+.*/d'

Um die Dateien anzuzeigen, bei denen sich zwischen Commits mehr als eine Zeile geändert hat, wodurch Dateien eliminiert werden, deren einzige Änderung die Versionsnummer in den Kommentaren war.

1644321012 45 Wie man git diff dazu bringt Kommentare zu ignorieren
Saravanan Palanisamy

Verwenden von ‘grep’ für die ‘git diff’-Ausgabe,

git diff -w | grep -c -E "(^[+-]s*(/)?*)|(^[+-]s*//)"

Nur Kommentarzeilenänderungen können berechnet werden. (EIN)

Verwenden der Ausgabe von ‘git diff –stat’,

git diff -w --stat

alle Linienänderungen können berechnet werden. (B)

Um die Anzahl der nicht kommentierten Quellzeilenänderungen (NCSL) zu erhalten, subtrahieren Sie (A) von (B).

Erläuterung:

In der ‘git diff’-Ausgabe (in der Leerzeichenänderungen ignoriert werden),

  • Achten Sie auf eine Zeile, die entweder mit „+“ oder „-“ beginnt, was eine geänderte Zeile bedeutet.
  • Darauf können optionale Leerzeichen folgen. ‘S*’
  • Suchen Sie dann nach dem Kommentarzeilenmuster ‘/*’ (oder) einfach ‘*’ (oder) ‘//’.
  • Da die Option ‘-c’ mit grep angegeben wird, geben Sie einfach die Anzahl aus. Entfernen Sie die Option ‘-c’, um nur die Kommentare in den Diffs zu sehen.

HINWEIS: Aufgrund der folgenden Annahmen kann es zu geringfügigen Fehlern bei der Anzahl der Kommentarzeilen kommen, und das Ergebnis sollte als Richtwert angesehen werden.

  • 1.) Quelldateien basieren auf der C-Sprache. Makefile- und Shell-Skriptdateien haben eine andere Konvention, ‘#’, um die Kommentarzeilen zu kennzeichnen, und wenn sie Teil von diffset sind, werden ihre Kommentarzeilen nicht gezählt.

  • 2.) Die Git-Konvention der Zeilenänderung: Wenn eine Zeile geändert wird, sieht Git dies so, als ob diese bestimmte Zeile gelöscht und dort eine neue Zeile eingefügt wird, und es kann so aussehen, als würden zwei Zeilen geändert, während in Wirklichkeit eine Zeile geändert wird.

     In the below example, the new definition of 'FOO' looks like a two-line change.
    
     $  git diff --stat -w abc.h
     ...
     -#define FOO 7
     +#define FOO 105
     ...
     1 files changed, 1 insertions(+), 1 deletions(-)
     $
    
  • 3.) Gültige Kommentarzeilen, die nicht mit dem Muster übereinstimmen (oder) Gültige Quellcodezeilen, die mit dem Muster übereinstimmen, können zu Fehlern bei der Berechnung führen.

Im folgenden Beispiel wird die Zeile „+ blah blah“, die nicht mit „*“ beginnt, nicht als Kommentarzeile erkannt.

           + /*
           +  blah blah
           + *
           + */

Im folgenden Beispiel wird die Zeile “+ *ptr” als Kommentarzeile gezählt, da sie mit * beginnt, obwohl es sich um eine gültige Quellcodezeile handelt.

            + printf("n %p",
            +         *ptr);

1644321012 124 Wie man git diff dazu bringt Kommentare zu ignorieren
Erik Aronesty

Für die meisten Sprachen müssen Sie, um es richtig zu machen, die ursprüngliche Quelldatei/ast parsen und Kommentare auf diese Weise ausschließen.

Ein Grund dafür ist, dass der Beginn von mehrzeiligen Kommentaren möglicherweise nicht vom Diff abgedeckt wird. Ein weiterer Grund ist, dass das Parsing von Sprachen nicht trivial ist und es oft Dinge gibt, die einen naiven Parser ins Stolpern bringen können.

Ich wollte das für Python machen, aber String-Hacking war gut genug für meine Bedürfnisse.

Für Python können Sie Kommentare ignorieren und versuchen, Dokumentzeichenfolgen zu ignorieren, indem Sie einen benutzerdefinierten Filter verwenden, z. B. diesen:

https://gist.github.com/earonesty/f76dec337ee64c5ae23c2be1557535a4

Dieser Code kann trivial geändert werden, um Dateinamen anstelle von Zählwerten zu erzeugen.

Aber es kann natürlich fälschlicherweise Teile von Docstrings als “Code” zählen (was nicht für Dinge wie Abdeckung usw. gilt).

1644321012 32 Wie man git diff dazu bringt Kommentare zu ignorieren
Peter Mortensen

Vielleicht ein Bash-Skript wie dieses:

#!/bin/bash
git diff --name-only "$@" | while read FPATH ; do
    LINES_COUNT=`git diff --textconv "$FPATH" "$@" | sed '/^[1-]s+[1-]s+.*/d' | wc -l`
    if [ $LINES_COUNT -gt 0 ] ; then
        echo -e "$LINES_COUNTt$FPATH"
    fi
done | sort -n

.

822280cookie-checkWie man ‘git diff’ dazu bringt, Kommentare zu ignorieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy