English ▾ Themen ▾ Neueste Version ▾ CodingGuidelines zuletzt aktualisiert in 2.52.0

Diese Informationen sind spezifisch für das Git-Projekt

Bitte beachten Sie, dass diese Informationen nur für Sie relevant sind, wenn Sie planen, selbst zum Git-Projekt beizutragen. Sie sind in keiner Weise Pflichtlektüre für reguläre Git-Benutzer.

Wie andere Projekte haben wir auch einige Richtlinien für unseren Code. Für Git im Allgemeinen, ein paar grobe Regeln sind:

  • Am wichtigsten ist, dass wir nie sagen: "Es ist in POSIX; wir ignorieren gerne Ihre Bedürfnisse, falls Ihr System nicht konform ist." Wir leben in der realen Welt.

  • Wir sagen jedoch oft: "Bleiben wir von diesem Konstrukt weg, es ist nicht einmal in POSIX."

  • Trotz der beiden oben genannten Regeln sagen wir manchmal: "Obwohl dies nicht in POSIX ist, ist es (so bequem | macht den Code viel lesbarer | hat andere gute Eigenschaften) und wird praktisch von allen Plattformen unterstützt, die uns wichtig sind, also verwenden wir es."

    Again, we live in the real world, and it is sometimes a
    judgement call, the decision based more on real world
    constraints people face than what the paper standard says.
  • Stilbrüche während der Arbeit an einer echten Änderung als vorbereitende Bereinigung sind gut, aber ansonsten vermeiden Sie nutzloses Code-Churn um des Konformität zum Stil willen.

    "Once it _is_ in the tree, it's not really worth the patch noise to
    go and fix it up."
    Cf. https://lore.kernel.org/all/20100126160632.3bdbe172.akpm@linux-foundation.org/
  • Log-Nachrichten zur Erklärung Ihrer Änderungen sind ebenso wichtig wie die Änderungen selbst. Klar geschriebener Code und Inline-Kommentare erklären, wie der Code funktioniert und was vom umgebenden Kontext erwartet wird. Die Log-Nachrichten erklären, was mit den Änderungen erreicht werden sollte und warum die Änderungen notwendig waren (mehr dazu im begleitenden Dokument SubmittingPatches).

Machen Sie Ihren Code lesbar und sinnvoll, und versuchen Sie nicht, schlau zu sein.

Was konkretere Richtlinien angeht, imitieren Sie einfach den bestehenden Code (das ist eine gute Richtlinie, egal welchem Projekt Sie beitragen). Es ist immer vorzuziehen, die lokale Konvention zu übernehmen. Neuer Code, der zur Git-Suite hinzugefügt wird, wird erwartet, den Gesamtstil des bestehenden Codes zu entsprechen. Modifikationen an bestehendem Code werden erwartet, den Stil des umgebenden Codes zu entsprechen (auch wenn er nicht dem Gesamtstil des bestehenden Codes entspricht).

Aber wenn Sie unbedingt eine Liste von Regeln haben müssen, hier sind einige sprachspezifische. Beachten Sie, dass das Dokument Documentation/ToolsForGit.adoc eine Sammlung von Tipps enthält, die Ihnen helfen, einige externe Tools zu verwenden, um diese Richtlinien einzuhalten.

Speziell für Shell-Skripte (nicht erschöpfend)

  • Wir verwenden Tabs für die Einrückung.

  • Case-Äste sind auf der gleichen Ebene wie case und esac Zeilen eingerückt, so:

    case "$variable" in
    pattern1)
    	do this
    	;;
    pattern2)
    	do that
    	;;
    esac
  • Umleitungsoperatoren sollten mit einem Leerzeichen davor, aber ohne Leerzeichen danach geschrieben werden. Mit anderen Worten, schreiben Sie echo test >"$file" statt echo test> $file oder echo test > $file. Beachten Sie, dass obwohl es von POSIX nicht verlangt wird, das Umleitungsziel in einer Variablen doppelt zu quoten (wie oben gezeigt), unser Code dies tut, da einige Versionen von bash ohne die Anführungszeichen eine Warnung ausgeben.

    (incorrect)
    cat hello > world < universe
    echo hello >$world
    (correct)
    cat hello >world <universe
    echo hello >"$world"
  • Wir bevorzugen $( …​ ) für die Befehlssubstitution; im Gegensatz zu ``, nestet es korrekt. Es hätte von Anfang an der Weg sein sollen, den Bourne geschrieben hat, aber leider ist er es nicht.

  • Wenn Sie feststellen möchten, ob ein Befehl auf dem $PATH des Benutzers verfügbar ist, sollten Sie type <command> verwenden, anstatt which <command>. Die Ausgabe von which ist nicht maschinenlesbar und sein Exit-Code ist nicht plattformübergreifend zuverlässig.

  • Wir verwenden POSIX-konforme Parameterersetzungen und vermeiden Bashismen; nämlich

  • Wir verwenden ${parameter-word} und seine [-=?+] Geschwister und ihre "unset oder null" Form mit Doppelpunkt.

  • Wir verwenden ${parameter#word} und seine [#%] Geschwister und ihre verdoppelten "längsten übereinstimmenden" Form.

  • Keine "Substring Expansion" ${parameter:offset:length}.

  • Keine Shell-Arrays.

  • Keine Musterersetzung ${parameter/pattern/string}.

  • Wir verwenden Arithmetische Expansion $…​.

  • Wir verwenden keine Prozesssubstitution <(list) oder >(list).

  • Schreiben Sie Kontrollstrukturen nicht auf einer einzigen Zeile mit Semikolon. "then" sollte bei if-Anweisungen auf der nächsten Zeile stehen, und "do" sollte bei "while" und "for" auf der nächsten Zeile stehen.

    (incorrect)
    if test -f hello; then
    	do this
    fi
    (correct)
    if test -f hello
    then
    	do this
    fi
  • Wenn eine Befehlssequenz, die mit && oder || oder | verbunden ist, sich über mehrere Zeilen erstreckt, legen Sie jeden Befehl auf eine separate Zeile und setzen Sie && und || und | Operatoren an das Ende jeder Zeile, anstatt an den Anfang. Das bedeutet, dass Sie keine \ verwenden müssen, um Zeilen zu verbinden, da die obigen Operatoren implizieren, dass die Sequenz nicht abgeschlossen ist.

    (incorrect)
    grep blob verify_pack_result \
    | awk -f print_1.awk \
    | sort >actual &&
    ...
    (correct)
    grep blob verify_pack_result |
    awk -f print_1.awk |
    sort >actual &&
    ...
  • Wir bevorzugen "test" gegenüber "[ …​ ]".

  • Wir schreiben nicht das Schlüsselwort "function" vor Shell-Funktionen.

  • Wir bevorzugen ein Leerzeichen zwischen dem Funktionsnamen und den Klammern und keine Leerzeichen innerhalb der Klammern. Die öffnende "{" sollte ebenfalls auf derselben Zeile stehen.

    (incorrect)
    my_function(){
    	...
    (correct)
    my_function () {
    	...
  • Was die Verwendung von grep angeht, halten Sie sich an eine Teilmenge von BRE (nämlich keine \{m,n\}, [::], [==] oder [..]) für Portabilität.

  • Wir verwenden nicht \{m,n\};

  • Wir verwenden nicht ? oder + (was in BRE \{0,1\} bzw. \{1,\} entspricht), aber das versteht sich von selbst, da dies ERE-Elemente und keine BRE-Elemente sind (beachten Sie, dass \? und \+ nicht einmal Teil von BRE sind - sie aus BRE zugänglich zu machen, ist eine GNU-Erweiterung).

  • Verwenden Sie Git's gettext Wrapper in git-sh-i18n, um die Benutzeroberfläche übersetzbar zu machen. Siehe "Marking strings for translation" in po/README.

  • Wir schreiben unseren "test"-Befehl nicht mit "-a" und "-o" und verwenden stattdessen "&&" oder "||", um mehrere "test"-Befehle zu verketten, da die Verwendung von "-a/-o" oft fehleranfällig ist. Z.B.

    test -n "$x" -a "$a" = "$b"
    is buggy and breaks when $x is "=", but
    test -n "$x" && test "$a" = "$b"
    does not have such a problem.
  • Obwohl "local" nicht Teil von POSIX ist, verwenden wir es in unserer Testsuite intensiv. Wir verwenden es nicht in geskripteten Porcelains und hoffentlich fängt niemand an, "local" zu verwenden, bevor alle wichtigen Shells es unterstützen (insbesondere ksh von AT&T Research unterstützt es noch nicht).

  • Einige Versionen von Shell verstehen "export variable=value" nicht, daher schreiben wir "variable=value" und dann "export variable" auf zwei separaten Zeilen.

  • Einige Versionen von dash haben fehlerhafte Zuweisungen von Variablen, wenn sie mit "local", "export" und "readonly" präfigiert sind, so dass der zuzuweisende Wert an IFS geteilt wird, wenn er nicht gequotet ist.

    (incorrect)
    local variable=$value
    local variable=$(command args)
    (correct)
    local variable="$value"
    local variable="$(command args)"
  • Das übliche Konstrukt

    VAR=VAL command args
    to temporarily set and export environment variable VAR only while
    "command args" is running is handy, but this triggers an
    unspecified behaviour according to POSIX when used for a command
    that is not an external command (like shell functions).  Indeed,
    dash 0.5.10.2-6 on Ubuntu 20.04, /bin/sh on FreeBSD 13, and AT&T
    ksh all make a temporary assignment without exporting the variable,
    in such a case.  As it does not work portably across shells, do not
    use this syntax for shell functions.  A common workaround is to do
    an explicit export in a subshell, like so:
    (incorrect)
    VAR=VAL func args
    (correct)
    (
    	VAR=VAL &&
    	export VAR &&
    	func args
    )
    but be careful that the effect "func" makes to the variables in the
    current shell will be lost across the subshell boundary.
  • Verwenden Sie Oktal-Escape-Sequenzen (z.B. "\302\242"), nicht Hexadezimal (z.B. "\xc2\xa2") in printf-Formatzeichenketten, da Hexadezimal-Escape-Sequenzen nicht portabel sind.

Für C-Programme

  • Wir verwenden Tabs zur Einrückung und interpretieren Tabs so, dass sie bis zu 8 Leerzeichen einnehmen.

  • Verschachtelte C-Präprozessordirektiven sind nach dem Hash um einen Leerzeichen pro Verschachtelungsebene eingerückt.

    #if FOO
    # include <foo.h>
    # if BAR
    #  include <bar.h>
    # endif
    #endif
  • Wir versuchen, maximal 80 Zeichen pro Zeile einzuhalten.

  • Als Git-Entwickler gehen wir davon aus, dass Sie einen einigermaßen modernen Compiler haben, und empfehlen Ihnen, den DEVELOPER Makefileschalter zu aktivieren, um sicherzustellen, dass Ihr Patch frei von allen Compiler-Warnungen ist, die uns wichtig sind, z.B. durch "echo DEVELOPER=1 >>config.mak".

  • Wenn Sie den Modus DEVELOPER=1 verwenden, sehen Sie möglicherweise Warnungen vom Compiler wie "error: unused parameter foo [-Werror=unused-parameter]", die darauf hinweisen, dass eine Funktion ihr Argument ignoriert. Wenn der ungenutzte Parameter nicht entfernt werden kann (z.B. weil die Funktion als Callback verwendet wird und einer bestimmten Schnittstelle entsprechen muss), können Sie die einzelnen Parameter mit dem Schlüsselwort UNUSED (oder MAYBE_UNUSED) annotieren, z.B. "int foo UNUSED".

  • Wir versuchen, eine breite Palette von C-Compilern zum Kompilieren von Git zu unterstützen, auch alte. Ab Git v2.35.0 benötigt Git C99 (wir prüfen "STDC_VERSION"). Sie sollten keine Funktionen aus einem neueren C-Standard verwenden, auch wenn Ihr Compiler sie versteht.

    New C99 features have been phased in gradually, if something's new
    in C99 but not used yet don't assume that it's safe to use, some
    compilers we target have only partial support for it. These are
    considered safe to use:
    1. Seit etwa 2007 mit 2b6854c863a verwenden wir Initialisiererelemente, die zur Ladezeit nicht berechenbar sind. Z.B.

      const char *args[] = { "constant", variable, NULL };
    2. Seit Anfang 2012 mit e1327023ea verwenden wir eine Enum-Definition, deren letztes Element durch ein Komma gefolgt wird. Dies kann, ähnlich wie ein Array-Initialisierer, der mit einem nachgestellten Komma endet, verwendet werden, um die Patch-Geräusche zu reduzieren, wenn ein neuer Bezeichner am Ende hinzugefügt wird.

    3. Seit Mitte 2017 mit cbc0f81d verwenden wir benannte Initialisierer für structs (z.B. "struct t v = { .val = a };").

    4. Seit Mitte 2017 mit 512f41cf verwenden wir benannte Initialisierer für Arrays (z.B. "int array[10] = { [5] = 2 }").

    5. Seit Anfang 2021 mit 765dc168882 verwenden wir variadische Makros, hauptsächlich für printf-ähnliche Trace- und Debug-Makros.

    6. Seit Ende 2021 mit 44ba10d6 deklarieren wir Variablen in der for-Schleife "for (int i = 0; i < 10; i++)".

    7. Seit Ende 2023 mit 8277dbe987 verwenden wir den bool-Typ aus <stdbool.h>.

      C99 features we have test balloons for:
    8. Seit Ende 2024 mit v2.48.0-rc0~20 haben wir Testballons für zusammengesetzte Literalsyntax, z.B. (struct foo){ .member = value }; unsere Hoffnung ist, dass keine Plattformen, die uns wichtig sind, Probleme bei der Verwendung haben, und wir werden deren breitere Verwendung offiziell Mitte 2026 einführen. Fügen Sie bis dahin keine weitere Verwendung der Syntax hinzu.

      New C99 features that we cannot use yet:
    9. %z und %zu als printf()-Argument für eine size_t (das %z ist für den POSIX-spezifischen ssize_t). Stattdessen sollten Sie printf("%"PRIuMAX, (uintmax_t)v) verwenden. Heutzutage unterstützt die MSVC-Version, auf die wir uns verlassen, %z, aber die C-Bibliothek, die von MinGW verwendet wird, tut dies nicht.

    10. Kurzschreibweisen wie ".a.b = *c" in struct-Initialisierungen sind bekannt dafür, eine ältere IBM XLC-Version zu verärgern. Verwenden Sie stattdessen ".a = { .b = *c }". Siehe 33665d98 (reftable: make assignments portable to AIX xlc v12.01, 2022-03-28).

  • Variablen müssen am Anfang des Blocks deklariert werden, vor der ersten Anweisung (d.h. -Wdeclaration-after-statement). Es wird empfohlen, eine Leerzeile zwischen dem Ende der Deklarationen und der ersten Anweisung im Block einzufügen.

  • Initialisieren Sie globale Variablen nicht explizit mit 0 oder NULL; lassen Sie stattdessen BSS die Nullinitialisierung übernehmen.

  • NULL-Zeiger werden als NULL geschrieben, nicht als 0.

  • Beim Deklarieren von Zeigern steht der Stern neben dem Variablennamen, d.h. "char string", nicht "char string" oder "char * string". Das erleichtert das Verständnis von Code wie "char *string, c;".

  • Verwenden Sie Leerzeichen um Operatoren und Schlüsselwörter, aber nicht innerhalb von Klammern und nicht um Funktionen herum. Also

          while (condition)
    func(bar + 1);
    and not:
          while( condition )
    func (bar+1);
  • Ein binärer Operator (außer ",") und ternärer bedingter Operator "?:" haben auf jeder Seite des Operators ein Leerzeichen, um ihn von seinen Operanden zu trennen. Z.B. "A + 1", nicht "A+1".

  • Ein unärer Operator (außer "." und "→") hat kein Leerzeichen zwischen sich und seinem Operanden. Z.B. "(char *)ptr", nicht "(char *) ptr".

  • Vergleichen Sie einen ganzzahligen Wert nicht explizit mit der Konstante 0 oder \0, oder einen Zeigerwert mit der Konstante NULL. Zum Beispiel, um zu validieren, dass ein gezählter Array <ptr, cnt> initialisiert ist, aber keine Elemente hat, schreiben Sie

    if (!ptr || cnt)
    	BUG("empty array expected");
    and not:
    if (ptr == NULL || cnt != 0);
    	BUG("empty array expected");
  • Wir vermeiden die unnötige Verwendung von geschweiften Klammern. D.h.

    if (bla) {
    	x = 1;
    }
    is frowned upon. But there are a few exceptions:
  • Wenn sich die Anweisung über mehrere Zeilen erstreckt (z.B. eine while-Schleife mit einer eingebetteten Bedingung oder ein Kommentar). Z.B.

    while (foo) {
    	if (x)
    		one();
    	else
    		two();
    }
    if (foo) {
    	/*
    	 * This one requires some explanation,
    	 * so we're better off with braces to make
    	 * it obvious that the indentation is correct.
    	 */
    	doit();
    }
  • Wenn es mehrere Zweige für eine Bedingung gibt und einige davon geschweifte Klammern erfordern, schließen Sie auch einen einzeiligen Block zur Konsistenz in geschweifte Klammern ein. Z.B.

    if (foo) {
    	doit();
    } else {
    	one();
    	two();
    	three();
    }
  • Wir versuchen, Zuweisungen in der Bedingung einer "if"-Anweisung zu vermeiden.

  • Versuchen Sie, Ihren Code verständlich zu machen. Sie können Kommentare einfügen, aber Kommentare neigen unweigerlich dazu, veraltet zu sein, wenn sich der Code, den sie beschrieben, ändert. Oft macht die Aufteilung einer Funktion in zwei Teile die Absicht des Codes viel klarer.

  • Mehrzeilige Kommentare schließen ihre Begrenzer in separaten Zeilen vom Text ein. Z.B.

    /*
     * A very long
     * multi-line comment.
     */
    Note however that a comment that explains a translatable string to
    translators uses a convention of starting with a magic token
    "TRANSLATORS: ", e.g.
    /*
     * TRANSLATORS: here is a comment that explains the string to
     * be translated, that follows immediately after it.
     */
    _("Here is a translatable string explained by the above.");
  • Doppelte Verneinung ist oft schwerer zu verstehen als gar keine Verneinung.

  • Es gibt zwei Denkrichtungen, wenn es um Vergleiche geht, besonders innerhalb einer Schleife. Einige Leute ziehen es vor, den weniger stabilen Wert auf der linken Seite und den stabileren Wert auf der rechten Seite zu haben, z.B. wenn Sie eine Schleife haben, die die Variable i nach unten bis zur unteren Grenze zählt,

    while (i > lower_bound) {
    	do something;
    	i--;
    }
    Other people prefer to have the textual order of values match the
    actual order of values in their comparison, so that they can
    mentally draw a number line from left to right and place these
    values in order, i.e.
    while (lower_bound < i) {
    	do something;
    	i--;
    }
    Both are valid, and we use both.  However, the more "stable" the
    stable side becomes, the more we tend to prefer the former
    (comparison with a constant, "i > 0", is an extreme example).
    Just do not mix styles in the same part of the code and mimic
    existing styles in the neighbourhood.
  • Es gibt zwei Denkrichtungen, wenn es darum geht, eine lange logische Zeile in mehrere Zeilen aufzuteilen. Einige Leute schieben die zweite und nachfolgende Zeilen so weit nach rechts mit Tabs und richten sie aus

          if (the_beginning_of_a_very_long_expression_that_has_to ||
    span_more_than_a_single_line_of ||
    the_source_text) {
                  ...
    while other people prefer to align the second and the subsequent
    lines with the column immediately inside the opening parenthesis,
    with tabs and spaces, following our "tabstop is always a multiple
    of 8" convention:
       if (the_beginning_of_a_very_long_expression_that_has_to ||
    span_more_than_a_single_line_of ||
    the_source_text) {
               ...
    Both are valid, and we use both.  Again, just do not mix styles in
    the same part of the code and mimic existing styles in the
    neighbourhood.
  • Beim Aufteilen einer langen logischen Zeile drehen einige Leute die Zeile vor einem binären Operator, so dass das Ergebnis wie ein Parse-Baum aussieht, wenn man den Kopf um 90 Grad gegen den Uhrzeigersinn dreht

       if (the_beginning_of_a_very_long_expression_that_has_to
    || span_more_than_a_single_line_of_the_source_text) {
    while other people prefer to leave the operator at the end of the
    line:
       if (the_beginning_of_a_very_long_expression_that_has_to ||
    span_more_than_a_single_line_of_the_source_text) {
    Both are valid, but we tend to use the latter more, unless the
    expression gets fairly complex, in which case the former tends to
    be easier to read.  Again, just do not mix styles in the same part
    of the code and mimic existing styles in the neighbourhood.
  • Beim Aufteilen einer langen logischen Zeile ist es, wenn alles andere gleich ist, vorzuziehen, nach dem Operator auf höherer Ebene im Parse-Baum zu teilen. Das heißt, das ist vorzuziehen

    if (a_very_long_variable * that_is_used_in +
        a_very_long_expression) {
    	...
    than
    if (a_very_long_variable *
        that_is_used_in + a_very_long_expression) {
    	...
  • Einige clevere Tricks, wie die Verwendung des !! Operators mit arithmetischen Konstrukten, können für andere extrem verwirrend sein. Vermeiden Sie sie, es sei denn, es gibt einen zwingenden Grund, sie zu verwenden.

  • Verwenden Sie die API. Nein, wirklich. Wir haben einen strbuf (variable Stringlänge), mehrere Arrays mit dem ALLOC_GROW()-Makro, eine string_list für sortierte String-Listen, eine Hash-Map (die struct-Objekte abbildet) namens "struct decorate", unter anderem.

  • Wenn Sie eine API entwickeln, dokumentieren Sie ihre Funktionen und Strukturen in der Header-Datei, die die API für ihre Aufrufer verfügbar macht. Verwenden Sie das, was in "strbuf.h" steht, als Modell für den geeigneten Ton und Detaillierungsgrad.

  • Die erste #include-Datei in C-Dateien, außer in plattformspezifischen compat/ Implementierungen und sha1dc/, muss <git-compat-util.h> sein. Diese Header-Datei isoliert andere Header-Dateien und Quelldateien von plattformabhängigen Unterschieden, wie z.B. welche System-Header-Dateien in welcher Reihenfolge eingeschlossen werden müssen und welche C-Präprozessor-Feature-Makros definiert werden müssen, um bestimmte Features auszulösen, die wir vom System erwarten. Eine Konsequenz daraus ist, dass C-Dateien selbst keine System-Header-Dateien direkt einschließen sollten.

    There are some exceptions, because certain group of files that
    implement an API all have to include the same header file that
    defines the API and it is convenient to include <git-compat-util.h>
    there.  Namely:
  • die Implementierung der integrierten Befehle im Verzeichnis "builtin/", die "builtin.h" für die cmd_foo()-Prototypdefinition einschließen,

  • die Test-Hilfsprogramme im Verzeichnis "t/helper/", die "t/helper/test-tool.h" für die cmd__foo()-Prototypdefinition einschließen,

  • die xdiff-Implementierung im Verzeichnis "xdiff/", die "xdiff/xinclude.h" für die internen Abläufe von xdiff einschließen,

  • die Unit-Test-Programme im Verzeichnis "t/unit-tests/", die "t/unit-tests/test-lib.h" einschließen, die ihnen das Unit-Tests-Framework bietet, und

  • die Quelldateien, die reftable im Verzeichnis "reftable/" implementieren, die "reftable/system.h" für die internen Abläufe von reftable einschließen,

    are allowed to assume that they do not have to include
    <git-compat-util.h> themselves, as it is included as the first
    '#include' in these header files.  These headers must be the first
    header file to be "#include"d in them, though.
  • Eine C-Datei muss direkt die Header-Dateien einschließen, die die von ihr verwendeten Funktionen und Typen deklarieren, mit Ausnahme der Funktionen und Typen, die ihr durch das Einschließen einer der Header-Dateien, die sie gemäß der vorherigen Regel einschließen muss, zur Verfügung gestellt werden.

  • Wenn Sie einen neuen Befehl planen, ziehen Sie in Erwägung, ihn zuerst in Shell oder Perl zu schreiben, damit Semantikänderungen leicht vorgenommen und diskutiert werden können. Viele Git-Befehle haben so begonnen, und einige sind immer noch Skripte.

  • Vermeiden Sie es, neue Abhängigkeiten in Git einzuführen. Das bedeutet, Sie sollten normalerweise von Skriptsprachen Abstand nehmen, die nicht bereits im Git-Kernbefehlssatz verwendet werden (es sei denn, Ihr Befehl ist klar davon getrennt, wie z.B. ein Importeur zur Konvertierung von random-scm-X-Repositorys nach Git).

  • Wenn wir ein <string, length>-Paar an Funktionen übergeben, sollten wir versuchen, sie in dieser Reihenfolge zu übergeben.

  • Verwenden Sie Git's gettext Wrapper, um die Benutzeroberfläche übersetzbar zu machen. Siehe "Marking strings for translation" in po/README.

  • Variablen und Funktionen, die auf eine bestimmte Quelldatei beschränkt sind, sollten mit "static" markiert werden. Variablen, die für andere Quelldateien sichtbar sind, müssen in Header-Dateien mit "extern" deklariert werden. Funktionsdeklarationen sollten jedoch nicht "extern" verwenden, da dies bereits der Standard ist.

  • Sie können gdb um Ihr Programm mit der Kurzform GIT_DEBUGGER starten. Führen Sie GIT_DEBUGGER=1 ./bin-wrappers/git foo aus, um gdb einfach so zu verwenden, wie es ist, oder führen Sie GIT_DEBUGGER="<debugger> <debugger-args>" ./bin-wrappers/git foo aus, um Ihren eigenen Debugger und Argumente zu verwenden. Beispiel: GIT_DEBUGGER="ddd --gdb" ./bin-wrappers/git log (Siehe bin-wrappers/wrap-for-bin.sh.)

  • Die primäre Datenstruktur, mit der ein Subsystem S umgeht, wird als struct S bezeichnet. Funktionen, die mit struct S arbeiten, werden als S_<verb>() benannt und sollten im Allgemeinen einen Zeiger auf struct S als ersten Parameter erhalten. Z.B.

    struct strbuf;
    void strbuf_add(struct strbuf *buf, ...);
    void strbuf_reset(struct strbuf *buf);
    is preferred over:
    struct strbuf;
    void add_string(struct strbuf *buf, ...);
    void reset_strbuf(struct strbuf *buf);
  • Es gibt mehrere gängige idiomatische Namen für Funktionen, die bestimmte Aufgaben für eine Struktur S ausführen.

  • S_init() initialisiert eine Struktur, ohne die Struktur selbst zu allozieren.

  • S_release() gibt den Inhalt einer Struktur frei, ohne die Struktur neu zu initialisieren zur sofortigen Wiederverwendung und ohne die Struktur selbst freizugeben.

  • S_clear() ist äquivalent zu S_release() gefolgt von S_init(), so dass die Struktur nach dem Löschen direkt verwendbar ist. Wenn S_clear() bereitgestellt wird, darf S_init() keine Ressourcen allozieren, die wieder freigegeben werden müssen.

  • S_free() gibt den Inhalt einer Struktur frei und gibt die Struktur frei.

  • Funktionsnamen sollten klar und beschreibend sein und ihren Zweck oder ihr Verhalten genau widerspiegeln. Beliebige Suffixe, die keinen sinnvollen Kontext hinzufügen, können zu Verwirrung führen, insbesondere für Neulinge im Codebestand.

    Historically, the '_1' suffix has been used in situations where:
  • Eine Funktion verarbeitet ein Element aus einer Gruppe, die eine ähnliche Verarbeitung erfordert.

  • Eine rekursive Funktion wurde von ihrer Einrichtungsphase getrennt.

    The '_1' suffix can be used as a concise way to indicate these specific
    cases. However, it is recommended to find a more descriptive name wherever
    possible to improve the readability and maintainability of the code.
  • Bitfelder sollten ohne Leerzeichen um den Doppelpunkt definiert werden. Z.B.

    unsigned my_field:1;
    unsigned other_field:1;
    unsigned field_with_longer_name:1;

Für Perl-Programme

  • Die meisten der oben genannten C-Richtlinien gelten.

  • Wir versuchen, Perl 5.8.1 und neuer zu unterstützen ("use Perl 5.008001").

  • use strict und use warnings werden dringend bevorzugt.

  • Überbeanspruchen Sie keine Statement-Modifikatoren, es sei denn, ihre Verwendung erleichtert das Befolgen des Ergebnisses.

    1. do something …​ do_this() unless (condition);

    2. do something else …​

      is more readable than:
    3. do something …​ unless (condition) { do_this(); }

    4. do something else …​

      *only* when the condition is so rare that do_this() will be almost
      always called.
  • Wir versuchen, Zuweisungen in "if ()"-Bedingungen zu vermeiden.

  • Lernen und verwenden Sie Git.pm, wenn Sie diese Funktionalität benötigen.

Für Python-Skripte

  • Wir folgen PEP-8 (https://peps.pythonlang.de/pep-0008/).

  • Als Minimum streben wir Kompatibilität mit Python 2.7 an.

  • Wo erforderliche Bibliotheken uns nicht auf Python 2 beschränken, versuchen wir auch, mit Python 3.1 und neuer kompatibel zu sein.

Programmausgabe

We make a distinction between a Git command's primary output and
output which is merely chatty feedback (for instance, status
messages, running transcript, or progress display), as well as error
messages. Roughly speaking, a Git command's primary output is that
which one might want to capture to a file or send down a pipe; its
chatty output should not interfere with these use-cases.
As such, primary output should be sent to the standard output stream
(stdout), and chatty output should be sent to the standard error
stream (stderr). Examples of commands which produce primary output
include `git log`, `git show`, and `git branch --list` which generate
output on the stdout stream.
Not all Git commands have primary output; this is often true of
commands whose main function is to perform an action. Some action
commands are silent, whereas others are chatty. An example of a
chatty action commands is `git clone` with its "Cloning into
'<path>'..." and "Checking connectivity..." status messages which it
sends to the stderr stream.
Error messages from Git commands should always be sent to the stderr
stream.

Fehlermeldungen

  • Beenden Sie eine einzeilige Fehlermeldung nicht mit einem Punkt.

  • Kapitalisieren Sie das erste Wort nicht nur, weil es das erste Wort in der Meldung ist ("unable to open %s", nicht "Unable to open %s"). Aber "SHA-3 not supported" ist in Ordnung, denn der Grund, warum das erste Wort großgeschrieben ist, ist nicht, weil es am Anfang des Satzes steht, sondern weil das Wort auch in Großbuchstaben geschrieben würde, wenn es mitten im Satz vorkäme.

  • Geben Sie zuerst an, was der Fehler ist ("cannot open %s", nicht "%s: cannot open").

  • Fassen Sie das Subjekt eines Fehlers in ein Paar einfache Anführungszeichen ein, z.B. die(_("unable to open %s'"), path).

  • Sofern kein zwingender Grund dagegen spricht, sollten Fehlermeldungen von Porcelain-Befehlen für die Übersetzung markiert werden, z.B. die(_("bad revision %s"), revision).

  • Fehlermeldungen von Plumbing-Befehlen sind manchmal für die maschinelle Verarbeitung bestimmt und sollten nicht für die Übersetzung markiert werden, z.B. die("bad revision %s", revision).

  • BUG("message") dient der Kommunikation spezifischer Fehler an Entwickler und sollte daher nicht übersetzt werden.

Extern sichtbare Namen

  • Für Konfigurationsvariablennamen folgen Sie der bestehenden Konvention.

    1. Der Abschnittsname gibt das betroffene Subsystem an.

    2. Der Unterabschnittsname, falls vorhanden, gibt an, welche von einer unbegrenzten Menge von Dingen eingestellt werden soll.

    3. Der Variablenname beschreibt die Auswirkung des Anpassens dieses Schalters.

      The section and variable names that consist of multiple words are
      formed by concatenating the words without punctuation marks (e.g. `-`),
      and are broken using bumpyCaps in documentation as a hint to the
      reader.
      When choosing the variable namespace, do not use variable name for
      specifying possibly unbounded set of things, most notably anything
      an end user can freely come up with (e.g. branch names).  Instead,
      use subsection names or variable values, like the existing variable
      branch.<name>.description does.

Dokumentation schreiben

Most (if not all) of the documentation pages are written in the
AsciiDoc format in *.adoc files (e.g. Documentation/git.adoc), and
processed into HTML and manpages (e.g. git.html and git.1 in the
same directory).
The documentation liberally mixes US and UK English (en_US/UK)
norms for spelling and grammar, which is somewhat unfortunate.
In an ideal world, it would have been better if it consistently
used only one and not the other, and we would have picked en_US
(if you wish to correct the English of some of the existing
documentation, please see the documentation-related advice in the
Documentation/SubmittingPatches file).
In order to ensure the documentation is inclusive, avoid assuming
that an unspecified example person is male or female, and think
twice before using "he", "him", "she", or "her".  Here are some
tips to avoid use of gendered pronouns:
  • Bevorzugen Sie Kürze und sachliche Beschreibung der Funktionalität im Abstrakten. Z.B.

    --short

    Gibt die Ausgabe im Kurzformat aus.

    and avoid something like these overly verbose alternatives:
    --short

    Verwenden Sie dies, um die Ausgabe im Kurzformat auszugeben.

    --short

    Sie können dies verwenden, um die Ausgabe im Kurzformat zu erhalten.

    --short

    Ein Benutzer, der kürzere Ausgaben bevorzugt, könnte…​.

    --short

    Sollte eine Person und/oder ein Programm eine kürzere Ausgabe wünschen, kann sie/er/sie/es…​

    This practice often eliminates the need to involve human actors in
    your description, but it is a good practice regardless of the
    avoidance of gendered pronouns.
  • Wenn es umständlich wird, sich an diesen Stil zu halten, bevorzugen Sie "Sie", wenn Sie sich an den hypothetischen Benutzer wenden, und möglicherweise "wir", wenn Sie besprechen, wie das Programm auf den Benutzer reagieren könnte. Z.B.

    You can use this option instead of `--xyz`, but we might remove
    support for it in future versions.
    while keeping in mind that you can probably be less verbose, e.g.
    Use this instead of `--xyz`. This option might be removed in future
    versions.
  • Wenn Sie sich immer noch auf eine Beispielperson beziehen müssen, die in der dritten Person Singular ist, können Sie auf "singular they" zurückgreifen, um "er/sie/ihn/sie" zu vermeiden, z.B.

    A contributor asks their upstream to pull from them.
    Note that this sounds ungrammatical and unnatural to those who
    learned that "they" is only used for third-person plural, e.g.
    those who learn English as a second language in some parts of the
    world.
    Every user-visible change should be reflected in the documentation.
    The same general rule as for code applies -- imitate the existing
    conventions.

Markup

Literal parts (e.g. use of command-line options, command names,
branch names, URLs, pathnames (files and directories), configuration and
environment variables) must be typeset as verbatim (i.e. wrapped with
backticks):
  `--pretty=oneline`
  `git rev-list`
  `remote.pushDefault`
  `http://git.example.com`
  `.git/config`
  `GIT_DIR`
  `HEAD`
  `umask`(2)
An environment variable must be prefixed with "$" only when referring to its
value and not when referring to the variable itself, in this case there is
nothing to add except the backticks:
  `GIT_DIR` is specified
  `$GIT_DIR/hooks/pre-receive`
Word phrases enclosed in `backtick characters` are rendered literally
and will not be further expanded. The use of `backticks` to achieve the
previous rule means that literal examples should not use AsciiDoc
escapes.
  Correct:
     `--pretty=oneline`
  Incorrect:
     `\--pretty=oneline`
Placeholders are spelled in lowercase and enclosed in
angle brackets surrounded by underscores:
  _<file>_
  _<commit>_
If a placeholder has multiple words, they are separated by dashes:
  _<new-branch-name>_
  _<template-directory>_
When needed, use a distinctive identifier for placeholders, usually
made of a qualification and a type:
  _<git-dir>_
  _<key-id>_

Zeichen sind ebenfalls von Unterstrichen umgeben: LF, CR, CR/LF, NUL, EOF

Git's Asciidoc processor has been tailored to treat backticked text
as complex synopsis. When literal and placeholders are mixed, you can
use the backtick notation which will take care of correctly typesetting
the content.
  `--jobs <n>`
  `--sort=<key>`
  `<directory>/.git`
  `remote.<name>.mirror`
  `ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>`

Als Nebeneffekt werden mit Backticks versehene Platzhalter korrekt gesetzt, aber dieser Stil wird nicht empfohlen.

When documenting multiple related `git config` variables, place them on
a separate line instead of separating them by commas.  For example, do
not write this:
  `core.var1`, `core.var2`::
Description common to `core.var1` and `core.var2`.

Schreiben Sie stattdessen: core.var1:: core.var2:: Beschreibung, die für core.var1 und core.var2 gemeinsam ist.

Synopsis Syntax

The synopsis (a paragraph with [synopsis] attribute) is automatically
formatted by the toolchain and does not need typesetting.
A few commented examples follow to provide reference when writing or
modifying command usage strings and synopsis sections in the manual
pages:
Possibility of multiple occurrences is indicated by three dots:
  <file>...
  (One or more of <file>.)
Optional parts are enclosed in square brackets:
  [<file>...]
  (Zero or more of <file>.)
An optional parameter needs to be typeset with unconstrained pairs
  [<repository>]
--exec-path[=<path>]
(Option with an optional argument.  Note that the "=" is inside the
brackets.)
[<patch>...]
(Zero or more of <patch>.  Note that the dots are inside, not
outside the brackets.)
Multiple alternatives are indicated with vertical bars:
  [-q | --quiet]
  [--utf8 | --no-utf8]
Use spacing around "|" token(s), but not immediately after opening or
before closing a [] or () pair:
  Do: [-q | --quiet]
  Don't: [-q|--quiet]
Don't use spacing around "|" tokens when they're used to separate the
alternate arguments of an option:
   Do: --track[=(direct|inherit)]
   Don't: --track[=(direct | inherit)]
Parentheses are used for grouping:
  [(<rev>|<range>)...]
  (Any number of either <rev> or <range>.  Parens are needed to make
  it clear that "..." pertains to both <rev> and <range>.)
[(-p <parent>)...]
(Any number of option -p, each with one <parent> argument.)
git remote set-head <name> (-a|-d|<branch>)
(One and only one of "-a", "-d" or "<branch>" _must_ (no square
brackets) be provided.)
And a somewhat more contrived example:
  --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
  Here "=" is outside the brackets, because "--diff-filter=" is a
  valid usage.  "*" has its own pair of brackets, because it can
  (optionally) be specified only when one or more of the letters is
  also provided.
A note on notation:
 Use 'git' (all lowercase) when talking about commands i.e. something
 the user would type into a shell and use 'Git' (uppercase first letter)
 when talking about the version control system and its properties.
If some place in the documentation needs to typeset a command usage
example with inline substitutions, it is fine to use +monospaced and
inline substituted text+ instead of `monospaced literal text`, and with
the former, the part that should not get substituted must be
quoted/escaped.