Drücken Sie standardmäßig --force-with-lease

130

Ich habe gerade davon erfahren git push --force-with-lease. Es ist ziemlich großartig. Aber natürlich wende ich nicht so oft Gewalt an, und deshalb mache ich mir Sorgen, dass ich diese raffinierte Funktion vergessen könnte, wenn ich sie das nächste Mal brauche.

Gibt es eine Möglichkeit, git so zu konfigurieren, dass git push -fes automatisch verwendet wird, es --force-with-leasesei denn, ich überschreibe es absichtlich mit --no-force-with-lease?

(Ich kann mir nicht vorstellen, jemals Gewalt ohne Leasing anwenden zu wollen!)

Dan Fabulich
quelle

Antworten:

141

AFAIK Es ist keine Konfiguration verfügbar, die git anweist, immer force-with-leasestatt zu verwenden force. Dies scheint ein gutes Beispiel für eine Funktionsanforderung zu sein. Wenn Sie kein Problem damit haben, in die Git-Code-Basis einzutauchen, können Sie sie selbst implementieren und zur Überprüfung einreichen.

BEARBEITEN Dies gilt derzeit noch für April 2019.

Bis dahin sehe ich wie so oft nur die Möglichkeit, eine zu erstellen, aliasdie diesem Zweck dient.

Erstellen Sie einen Alias

Um einen Alias ​​zu erstellen, würde man verwenden git config --global alias.<alias-name> <command>, in unserem Fall würde ich etwas Ähnliches vorschlagen.

git config --global alias.pushf "push --force-with-lease"

Dadurch wird ein Eintrag in Ihrer globalen .gitconfigDatei erstellt (den Sie normalerweise in Ihrem Home-Verzeichnis finden ). Danach können Sie einfach git pushfmit Force-with-Lease verwenden .

Mach dir die Hände schmutzig

Wenn Sie die Funktion selbst implementieren möchten, sich aber nicht sicher sind, wo Sie anfangen sollen, sollten Sie sich zunächst das Dokumentationsverzeichnis im Git-Repository ansehen . Hier finden Sie die Codierungsrichtlinien und Informationen zum Einreichen von Patches .

Sie finden all diese Links und mehr auf der offiziellen Community-Seite .

Sascha Wolf
quelle
25
Ein Hinweis darauf, dass dies kein Feature ist: Das übliche Argument gegen das Umschreiben von Standardbefehlen ("push --force") ist, dass Sie sich an sie gewöhnen, ihren Ursprung vergessen und sie eines Tages versehentlich auf diese Weise auf einem neuen System verwenden. Ähnlich wie Aliasing rmzu rm -iIhrer Bashrc; Sie werden eines Tages eine wichtige Datei auf einem Server vergessen und löschen. Mit Ihrem eigenen Alias ​​zu gehen hat dieses Problem nicht :)
hraban
2
Persönliche Anekdote / Wort der Vorsicht: Ich habe versucht, ein Aliasing durchzuführen, habe pushfaber immer überprüft, dass ich kein push -fAlias ​​erstellt habe, da es dem Alias ​​ähnlich sieht. Einige Teammitglieder verwendeten push -fsowieso und dachten, dass der Alias ​​nur eine kosmetische Abkürzung dafür war. Letztendlich haben wir stattdessen die sicherere Form aliasiert pushflund aufgehört , uns darüber Sorgen zu machen.
Kelvin
31

Ich mache mir Sorgen, dass ich dieses raffinierte Feature vergessen könnte, wenn ich es das nächste Mal brauche.

Git 2.13 (Q2 2017) erklärt, warum es keinen "Schutz" gegen das Vergessen dieser Push-Option gibt, denn selbst wenn Sie sie auf der Ebene nicht vergessen git push, wird sie möglicherweise dennoch ignoriert.

Siehe Commit f17d642 (19. April 2017) von Ævar Arnfjörð Bjarmason ( avar) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 46bdfa3 , 26. April 2017)

push: Dokumentieren und Testen --force-with-leasemit mehreren Fernbedienungen

Dokumentieren und testen Sie Fälle, in denen zwei Fernbedienungen auf dieselbe URL verweisen und ein Abruf im Hintergrund und nachfolgende git push --force-with-leasenicht aktualisierte Referenzen, die wir nicht abgerufen haben, nicht blockieren sollten.

Einige Editoren wie Microsoft VSC verfügen über eine Funktion zum automatischen Abrufen im Hintergrund. Dadurch wird der von --force-with-lease& angebotene Schutz umgangen--force-with-lease=<refname> , wie in der hier hinzugefügten Dokumentation angegeben.

Die Dokumentation für dengit push Moment enthält also:

Allgemeiner Hinweis zur Sicherheit: Bereitstellung dieser Option ohne erwarteten Wert, dh als --force-with-leaseoder --force-with-lease=<refname> sehr schlecht mit allem, was implizit git fetchauf der Fernbedienung ausgeführt wird, um im Hintergrund git fetch origin verschoben zu werden, z. B. in Ihrem Repository in einem Cronjob.

Der Schutz, den es bietet, --forcestellt sicher, dass nachfolgende Änderungen, auf denen Ihre Arbeit nicht basiert, nicht überlastet werden. Dies wird jedoch trivial zunichte gemacht, wenn ein Hintergrundprozess Refs im Hintergrund aktualisiert. Wir haben nichts anderes als die Remote-Tracking-Informationen, die als Heuristik für Refs dienen sollen, die Sie voraussichtlich gesehen haben und die bereit sind, zu überfallen.

Wenn Ihr Editor oder ein anderes System git fetchim Hintergrund ausgeführt wird, können Sie dies abmildern, indem Sie einfach eine andere Fernbedienung einrichten:

git remote add origin-push $(git config remote.origin.url)
git fetch origin-push

Wenn der Hintergrundprozess ausgeführt wird, werden git fetch origindie Referenzen origin-pushnicht aktualisiert und daher Befehle wie:

git push --force-with-lease origin-push

Schlägt fehl, wenn Sie nicht manuell ausführen git fetch origin-push.
Diese Methode wird natürlich vollständig von etwas besiegt, das ausgeführt git fetch --allwird. In diesem Fall müssten Sie sie entweder deaktivieren oder etwas Langwierigeres tun, wie:

git fetch              # update 'master' from remote
git tag base master    # mark our base point
git rebase -i master   # rewrite some commits
git push --force-with-lease=master:base master:master

Das heißt, Sie erstellen ein baseTag für Versionen des Upstream-Codes, den Sie gesehen haben und der bereit ist, zu überschreiben, dann den Verlauf neu zu schreiben und schließlich Push-Änderungen zu erzwingen, masterwenn die Remote-Version noch verfügbar ist base, unabhängig davon, auf was Ihre lokale Version remotes/origin/masterin der aktualisiert wurde Hintergrund.

VonC
quelle
30

Meine Lösung bestand darin, ein Wrapper-Skript zu erstellen und einen Alias ​​zu verwenden, damit ich ihn immer anstelle des realen verwende git.

Wann immer ich es versuche git push -f, sehe ich Folgendes:

⚡ git push -f
use this instead so you don't cause race conditions in the 
repo: git push --force-with-lease

Einige Vorteile dieses Skripts sind:

  • es trainiert mich, es gewohnheitsmäßig zu benutzen --force-with-lease, damit ich nicht genagt werde, wenn ich es falsch verstehe
  • Wenn wir aus irgendeinem Grund wirklich Druck erzwingen müssen, git push --forcewird es funktionieren.

So implementieren Sie es:

  1. Erstellen Sie ein benutzerdefiniertes Skript, das alle Parameter an git weiterleitet, mit Ausnahme von -f
  2. Alias ​​dieses Skript, also verwenden wir es anstelle von git

Diese Anweisungen setzen Linux oder Mac voraus, auf denen bash ausgeführt wird. Ich habe dies nicht mit zsh oder Windows versucht, aber ich gehe davon aus, dass es auch dort funktionieren wird.

~/.bash_profile::

alias git=~/.git_wrapper.sh

~./git_wrapper.sh::

#!/bin/bash
for arg in "$@"; do
    if [ "$arg" = "push" ]; then
        ispush=1
    elif [ "$ispush" = 1 -a "$arg" = '-f' ]; then
        echo "use this instead so you don't cause race conflicts in the repo: git push --force-with-lease"
        exit 1
    fi
done

git "$@"

gitStarten Sie mit diesen Änderungen Ihr Terminal neu und sollten Sie jetzt auf Hochtouren sein, wenn Sie versuchen, Push zu erzwingen.

Jessica Knight
quelle
17
Das scheint praktisch. +1. Vielleicht ersetzen Sie "Hey Idiot" durch "Hey, du sanfte, aber einfache Seele" oder so etwas;)
VonC
5

Für Leute, die OMYZSH verwenden, können Sie einfach verwenden ggfl.

Nicolas
quelle
3

Ich möchte daran erinnert werden, dass ich es nicht verwenden sollte -f, aber ich möchte nicht dazu verleitet werden, zu glauben, dass dies -fbedeutet --force-with-lease. Das ist also meine Meinung:

git() {
  if [[ $@ == 'push -f'* ]]; then
    echo Hey stupid, use --force-with-lease instead
  else
    command git "$@"
  fi
}

Fügen Sie zu Ihrem .bash_profile, .bashrcoder hinzu .zshrc.

neu242
quelle
1

Sie können eine Bash-Funktion erstellen, die anstelle von ersetzt gitund verwendet --force-with-leasewird--force

# replaces `git push --force` with `git push --force-with-lease`
git() {
  if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then
    command git push --force-with-lease
  else
    command git "$@"
  fi
}

oder in einer Zeile:

git() { if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then command git push --force-with-lease; else command git "$@"; fi; }

Fügen Sie es einfach Ihrem ~/.bashrcoder hinzu ~/.zshrc.

Paulodiovani
quelle