Git-Schuld mit optionaler Ignorerevs-Datei

Lesezeit: 5 Minuten

Benutzeravatar von anol
anol

Ich habe ungefähr 40 Git-Repositories, von denen die meisten eine haben .git-blame-ignore-revs Datei zur Verwendung mit git blame. Anstatt also jeden von ihnen lokal mit zu konfigurieren blame.ignorerevsfile=.git-blame-ignore-revsIch habe es auf meine angewendet global git-Konfiguration.

Allerdings sind die wenigen Repositories, die dies tun nicht eine solche Datei haben, sind davon betroffen: läuft git blame auf ihnen ergibt sich fatal: could not open object name list: .git-blame-ignore-revs.

Gibt es eine Möglichkeit, Git anzuweisen, eine solche Datei zu lesen? wenn es existiert, sonst ignorieren? Das wäre ideal: einfach einzurichten, aber unauffällig, wenn eine solche Datei nicht vorhanden ist.

Hinweis: Ein weiterer Grund, warum Sie eine haben Optional .git-blame-ignore-revs nützlich ist, dass praktisch alle Git-Repositories erstellt werden ohne eine solche Datei, und erst später wird sie hinzugefügt. Wenn wir jedoch alte Commits halbieren, kehren wir möglicherweise zu einem Punkt zurück Vor die Datei existiert, und dann müssen wir touch beenden Sie die Halbierung und entfernen Sie sie dann erneut, um zum HEAD-Commit zurückkehren zu können. Auch wenn ich a verwende lokal config für die Datei, wird diese äußerst ärgerliche Situation immer noch auftreten. Aus diesem Grund glaube ich, dass das Standardverhalten darin bestehen sollte, die Datei zu ignorieren, wenn sie nicht existiert.

Benutzeravatar von phd
promov

Gibt es eine Möglichkeit, Git anzuweisen, eine solche Datei zu lesen, falls sie existiert, und sie ansonsten zu ignorieren?

Es gibt kein. Entweder verwenden

git config --local blame.ignoreRevsFile .git-blame-ignore-revs

anstatt --global. Oder verwenden

git config --local blame.ignoreRevsFile ""

in den Repositorys, in denen die Datei nicht existiert. Leerer Dateiname bedeutet “keine Datei verwenden”.

Oder leer erstellen .git-blame-ignore-revs Dateien.

Aktualisiert. Testen Sie mit einem neuen temporären Repository:

git init test-git
cd test-git

git config --global blame.ignoreRevsFile test
git config --show-origin blame.ignoreRevsFile
file:/home/phd/.gitconfig       test

git config --local blame.ignoreRevsFile ""
git config --show-origin blame.ignoreRevsFile
file:.git/config

Update2

git blame testfile
fatal: could not open object name list: test

Autsch!

  • Es wäre großartig, wenn die lokale Konfiguration die globale übernehmen würde, sodass erstere ignoriert werden könnte. Allerdings, obwohl Ihr Link das sagt Leere Dateinamen setzen die Liste der ignorierten Revisionen zurückUnd diese Seite sagen: “Die Dateien werden in der oben angegebenen Reihenfolge gelesen [global before local]wobei der zuletzt gefundene Wert Vorrang vor früher gelesenen Werten hat”, funktioniert es immer noch nicht, wahrscheinlich aufgrund dieses Verhaltens: “Wenn mehrere Werte verwendet werden, werden alle Werte eines Schlüssels aus allen Dateien verwendet.”

    – anol

    21. Dezember 2021 um 14:42 Uhr

  • @anol Bitte zeige das Ergebnis von git config --show-origin blame.ignoreRevsFile in einem Repo ohne die Datei.

    – promov

    21. Dezember 2021 um 14:50 Uhr


  • Es zeigt file:$HOME/.gitconfig .git-blame-ignore-revswie erwartet, da ich es über eingestellt habe --global bisher. Es scheint mir, dass es eine leichte Verhaltensabweichung von der Dokumentation gibt. Auch beim Hinzufügen von Optionen --ignore-revs-file ""welches ist dokumentiert als Ein leerer Dateiname, “”, löscht die Liste der Umdrehungen aus zuvor verarbeiteten Dateienscheint es bei mir nicht der Fall zu sein: git sucht immer noch nach dem .git-blame-ignore-revs Datei und der Befehl schlägt fehl.

    – anol

    21. Dezember 2021 um 15:00 Uhr

  • @anol Hoppla, du hast recht! Sehen Update2. Ich würde sagen, das ist ein Bug-in git blame.

    – promov

    21. Dezember 2021 um 15:44 Uhr

  • Offenbar A zugehöriger Patch wurde vorgeschlagen, im August zu starten, aber ich denke, dass es seitdem nicht viel vorangekommen ist. Aber etwas Ähnliches könnte in einer zukünftigen Git-Version landen.

    – anol

    21. Dezember 2021 um 16:16 Uhr

Benutzeravatar von Ryan Ulch
Ryan Ulch

Nun, das ist keine perfekte Lösung, da es nicht auf eine rohe Git-Schuld zutrifft, aber ich habe einen Shell-Befehlsalias verwendet. Ändern Sie den Befehl natürlich nach Bedarf, aber FWIW Ich habe viel bessere Ergebnisse für meine Anwendungsfälle mit ‘-w’ (Leerzeichen ignorieren) erhalten:

git config --global alias.bl "!myGitBlame.sh"

Und das entsprechende Shell-Skript (von dem angenommen wird, dass es sich auf dem PATH für den vorherigen Befehl git config befindet):

#!/usr/bin/env bash
if [[ -z $GIT_PREFIX ]]; then
    GIT_PREFIX=./
fi

# Assume (and impose limitation) that the last argument to this script is the
# file being blamed. Pull it out of the args list and make it relative to the
# root of the git repo to match the execution context of git shell aliases
LAST_ARG="${@: -1}"
set -- "${@:1:$(($#-1))}"
FILE_PATH=$GIT_PREFIX$LAST_ARG

# optional ignore revs file, specified relative to the root of the git repo
OPTIONAL_GIT_BLAME_REVS_FILE=.git-blame-ignore-revs

# if the revs file does not exist, ignore-revs-file accepts empty values
# without issue
if [[ ! -f $OPTIONAL_GIT_BLAME_REVS_FILE ]]; then
    OPTIONAL_GIT_BLAME_REVS_FILE=""
fi

git blame -w --ignore-revs-file=$OPTIONAL_GIT_BLAME_REVS_FILE "$@" $FILE_PATH

Und als Einzeiler, wenn Sie es einfach an Kollegen weitergeben möchten:

git config --global alias.bl '!if [[ -z $GIT_PREFIX ]]; then GIT_PREFIX=./; fi; f() { LAST_ARG="${@: -1}"; set -- "${@:1:$(($#-1))}"; FILE_PATH=$GIT_PREFIX$LAST_ARG; GIT_BLAME_REVS_FILE=.git-blame-ignore-revs; if [[ ! -f $GIT_BLAME_REVS_FILE ]]; then GIT_BLAME_REVS_FILE=""; fi; git blame -w --ignore-revs-file=$GIT_BLAME_REVS_FILE "$@" $FILE_PATH; }; f'

ANMERKUNG: Dies macht die Annahme, dass das letzte Argument für Git-Schuld die Datei ist; Das bedeutet, dass dies nicht 1: 1 mit dem übereinstimmt, was eine normale Git-Schuld-Befehlszeile akzeptiert, da Sie dies technisch können git blame <commit_hash> <file> oder git blame <file> <commit_hash> in einfachen Fällen.

Ich verwende dies definitiv in der Shell-Skriptform, aber ich bin mir der Vorteile der 1-Zeilen-Konfiguration bewusst, um dies an Kollegen weiterzugeben und den PATH im Allgemeinen zu vermeiden.

Ich gehe hier auch von einer bash-verfügbaren Umgebung aus.

Ich hatte ursprünglich versucht, nur eine lokale Konfiguration zu erstellen, die direkt auf die Datei verweist, aber das führt zu allen möglichen Problemen, die Sie skizziert haben, und es interagiert auch sehr schlecht mit Worktree-Setups. Dies sollte allgemein funktionieren, wenn auch nicht ganz perfekt.

1445890cookie-checkGit-Schuld mit optionaler Ignorerevs-Datei

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

Privacy policy