Richtiger und schneller Weg, um Git-Verzeichnis und Git-Zweig zu testen?

7

Während ich versuchte, meine neue Fischschalen- Eingabeaufforderung einzurichten, testete ich schließlich Möglichkeiten, um den Zweignamen zu erhalten, und testete auch, ob ich mich in einem Git-Repository befand. Ich habe festgestellt, dass (1) git rev-parse --abbrev-ref HEAD , (2) git symbolic-ref HEAD | sed 's/refs\/heads\///' und (3) git describe --contains --all HEAD den Trick gut machen.

Ich bin neugierig, weil ich die Einfachheit von (1) liebe , aber in einem neuen und unberührten (gerade git inited) Repository gibt es einen "fatalen:" Fehler, während (2) wie beabsichtigt funktioniert, dh mir einen gibt Default - Master als Ausgabe. Die Sache ist, dass selbst bei einem "fatalen:" Fehler der Rückkehrcode 0 ist. Ist das das beabsichtigte Verhalten?

Um zu testen, ob ich mich in einem Git-Repository befand, habe ich einfach getestet, ob das aktuelle Verzeichnis einen Ordner ".git" hat : test -d ".git". Rudimentäre Lösung, aber es funktioniert, und es scheint schneller zu sein als mit einem git-Befehl.

Meine Fragen sind also:

  1. Sollte das nicht "fatal:" mit (1) einen von 0 abweichenden Exit-Code zurückgeben? Wenn es tatsächlich ein Fehler ist, da ich nicht weiß, wie Git-Leute ihre Rückkehrcodes standardisiert haben, wo soll ich ihn melden?
  2. Ich weiß, wenn ich (1) mit umleitung (^ /dev/null für diejenigen, die es nicht wissen, ^ist es dasselbe wie 2>), werde ich den Fehler nicht erhalten, aber es wird HEADanstelle von master angezeigt, aber wenn ich cat .git/HEAD, bekomme ich : ref: refs/heads/master. Was soll es wirklich sagen? Mit masterbin ich nur unwissend und wählerisch, weil es stattdessen sagen sollte HEAD? Ich meine im Fall eines gerade git inited Repositorys.
  3. Haben Sie während Ihrer Suche nach einer netten Eingabeaufforderung tatsächlich mögliche Lösungen verglichen?

Dies ist der Code, den ich zum Benchmarking (für Fische) verwende:

set -l before (date +%s%N)
git rev-parse --abbrev-ref HEAD
set -l after (date +%s%N)
set -l elapsed_time (expr $after - $before)
echo $elapsed_time

Danke im Voraus!

PS: Die Tools sind die neuesten GNU-Versionen, meine ich sed, dateund expr. Es tut mir leid, wenn es zu viele Informationen gibt oder wenn etwas keinen Sinn ergibt. Trage es mit mir. Vielen Dank!

EDIT: Wie jemand in einer Antwort richtig erraten hat, ist der ganze Fehler:

fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
Andrés Botero
quelle
Bitte posten Sie den fatal:Fehler. Schwer zu wissen, wie es behandelt werden soll, ohne es lesen zu können. :-)
Christopher
Ich habe es einfach gemacht. :)
Andrés Botero

Antworten:

4

Beantwortet Ihre Fragen nicht vollständig, aber wahrscheinlich ein bisschen mehr als nur einen Kommentar:

  1. Basierend auf anderen Kommentaren in Ihrer Antwort denke ich, dass der Fehler, den Sie gesehen haben, darin besteht, fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.dass Sie diese Tests in einem brandneuen Git-Repository durchführen, das keine engagierte Arbeit hat. Dies ist nicht nur kein wirklich fairer Test (Ihre Leistung wird per Definition in einem größeren Repository schlechter sein), sondern in fast jeder Hinsicht ein Randfall. Zum Beispiel .git/HEADzeigt ref: refs/heads/masterdurch Konvention. Der Fehler wird ausgelöst, weil er nicht HEADeindeutig ist. Sie haben keine Historie, daher wird jeder übergebene Wert rev-parsegleich behandelt. Außerdem wird 0 für mich nicht beendet:

    $ git init /tmp/test && cd /tmp/test
    $ git rev-parse --abbrev-ref HEAD
    $ echo $?
    128
    

    In der Summe schwitzen Sie diesen Fehler nicht. Besorgen Sie sich eines der riesigen Android-Repos oder vielleicht den Linux-Kernel und testen Sie dort Ihre Eingabeaufforderung.

  2. HEADist kein Zweig. Es ist ein Zeiger auf den ausgecheckten Zustand. Wenn Sie einen Zweig ausgecheckt haben, ist dies ein symbolischer Verweis auf diesen Zweig. Wenn Sie sich im Status "Getrennter KOPF" befinden, zeigt der HEADZeiger auf ein Commit. Sie erhalten HEADdie Rückgabe mit Methode (1), da rev-parsenur der übergebene refspec-Wert im Fehler wiedergegeben wird. Versuchen Sie es mit blah; Du wirst das Gleiche sehen.

  3. Ich habe keine Benchmarking-Lösungen, aber ein paar Dinge, die Sie vielleicht ausprobieren könnten (beide werden in meiner zsh-Eingabeaufforderung verwendet, die ich nicht geschrieben habe, und beide haben eine recht gute Leistung erbracht):

    git rev-parse --is-inside-work-tree ;# avoids your 'test -d .git' call
    ref=$(git symbolic-ref HEAD 2> /dev/null) ;# grab the full refspec
    branch=$(echo ${ref#refs/heads/}) ;# extract the branch name
    
Christopher
quelle
Ich bin gerade nicht zu Hause, aber ich werde es in meiner Android-ROM-Quelle versuchen, wenn ich zurück bin. In der Tat, welcher beste Ort, um es auszuprobieren ... Danke!
Andrés Botero
--is-inside-work-tree ist eine viel bessere Option (aber nicht so schnell) als das Testen des .git-Verzeichnisses, da sich .git nur im Stammverzeichnis befindet. Für den Zweig gab mir "git help symbolic-ref" die Antwort: git symbolic-ref --short HEAD 2> / dev / null. Viel cooler, ein einziger Befehl, perfekt. Keine Ahnung, wie ich es vorher nicht gesehen habe. Vielen Dank!
Andrés Botero