Je viens d'apprendre git push --force-with-lease. C'est assez génial. Mais, bien sûr, je n'utilise pas la force si souvent, et j'ai donc peur d'oublier cette fonctionnalité astucieuse la prochaine fois que j'en aurai besoin.
Existe-t-il un moyen de configurer git afin git push -fqu'il l'utilise automatiquement à --force-with-leasemoins que je ne le remplace intentionnellement avec --no-force-with-lease?
(Je ne peux pas imaginer vouloir jamais utiliser la force sans bail!)
AFAIK il n'y a pas de configuration disponible pour dire à git de toujours utiliser à la force-with-leaseplace de force. Cela semble être un bon exemple de demande de fonctionnalité; si vous n'avez aucun problème pour plonger dans la base de code git, vous pouvez l'implémenter vous-même et le soumettre pour examen.
EDIT Dans l'état actuel des choses, cela est toujours vrai en avril 2019.
Jusque-là, la seule option que je vois est, comme si souvent, de créer un aliasqui sert cet objectif.
Créer un alias
Pour créer un alias, on utiliserait git config --global alias.<alias-name> <command>, dans notre cas, je suggérerais quelque chose de similaire.
Cela créera une entrée dans votre .gitconfigfichier global (que vous pouvez généralement trouver dans votre répertoire personnel ). Après cela, vous pouvez simplement utiliser git pushfpour forcer avec bail .
Une note sur ce n'est pas une fonctionnalité: l'argument commun contre la réécriture des commandes standard ("push --force") est que vous vous y habituez, oubliez leur origine, et un jour les utilisez accidentellement de cette manière sur un nouveau système. Tout comme l' aliasing rmà rm -ivotre .bashrc; vous oublierez et supprimerez un jour un fichier important sur un serveur. Aller avec votre propre alias n'a pas ce problème :)
hraban
2
Anecdote personnelle / mot d'avertissement: j'ai essayé de l'aliaser pushfmais j'ai toujours vérifié que je ne faisais pas de push -f, car il ressemblait à l'alias. Certains membres de l'équipe utilisaient de push -ftoute façon, pensant que l'alias n'était qu'un raccourci cosmétique pour cela. En fin de compte, nous avons aliasé la forme la plus sûre à la pushflplace et avons cessé de nous en préoccuper.
kelvin le
31
J'ai peur d'oublier cette fonctionnalité astucieuse la prochaine fois que j'en aurai besoin.
Git 2.13 (Q2 2017) explique pourquoi il n'y a pas de "protection" contre l'oubli de cette option push, car même si vous ne l' oubliez pas au git pushniveau, elle risque d'être ignorée.
push: document et test --force-with-leaseavec plusieurs télécommandes
Document et test pour les cas où il y a deux télécommandes pointant vers la même URL, et une récupération en arrière-plan et les suivantes git push --force-with-leasene devraient pas écraser les références non mises à jour que nous n'avons pas récupérées.
Certains éditeurs comme le VSC de Microsoft ont une fonction de récupération automatique en arrière-plan, ce qui contourne les protections offertes par --force-with-lease&--force-with-lease=<refname> , comme indiqué dans la documentation ajoutée ici.
note générale sur la sécurité: fournir cette option sans valeur attendue, c'est à dire as --force-with-leaseou --force-with-lease=<refname>
interagit très mal avec tout ce qui tourne implicitement git fetchsur la télécommande pour être poussé en arrière-plan, par exemple git fetch origin
sur votre référentiel dans un cronjob.
La protection qu'il offre --forcegarantit que les modifications ultérieures sur lesquelles votre travail n'était pas basé ne sont pas écrasées, mais cela est trivialement vaincu si un processus d'arrière-plan met à jour les références en arrière-plan. Nous n'avons rien d'autre que les informations de suivi à distance à utiliser comme heuristique pour les références que vous êtes censé avoir vues et que vous êtes prêt à écraser.
Si votre éditeur ou un autre système s'exécute git fetchen arrière-plan pour vous, un moyen d'atténuer ce problème consiste simplement à configurer une autre télécommande:
Maintenant, lorsque le processus d'arrière-plan s'exécute, git fetch originles références origin-pushne seront pas mises à jour, et donc les commandes telles que:
git push --force-with-lease origin-push
Échouera sauf si vous exécutez manuellement git fetch origin-push.
Cette méthode est bien sûr entièrement vaincue par quelque chose qui s'exécute git fetch
--all, dans ce cas, vous devrez soit la désactiver, soit faire quelque chose de plus fastidieux comme:
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
C'est-à-dire créer une basebalise pour les versions du code en amont que vous avez vues et que vous souhaitez écraser, puis réécrire l'historique, et enfin forcer les modifications à savoir mastersi la version distante est toujours à base, indépendamment de ce que votre local remotes/origin/mastera été mis à jour dans le Contexte.
Ma solution était de créer un script wrapper et d'utiliser un alias pour que je l'utilise toujours à la place du réel git.
Chaque fois que j'essaye git push -f, je vois ce qui suit:
⚡ git push -f
use this instead so you don't cause race conditions in the
repo: git push --force-with-lease
Certains avantages de ce script sont:
ça m'entraîne à utiliser habituellement --force-with-lease, donc je ne me fais pas harceler quand je me trompe
si, pour une raison quelconque, nous devons vraiment forcer la poussée, git push --forcecela fonctionnera.
Comment l'implémenter:
créer un script personnalisé qui passera par tous les paramètres à git, sauf pour -f
alias ce script donc nous l'utilisons au lieu de git
Ces instructions supposent Linux ou Mac, exécutant bash. Je n'ai pas essayé cela avec zsh ou Windows, mais je suppose que cela fonctionnera là aussi.
~/.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 "$@"
Avec ces changements, redémarrez votre terminal et gitdevrait maintenant être à la hauteur lorsque vous essayez de forcer le push.
Je veux qu'on me rappelle que je ne devrais pas utiliser -f, mais je ne veux pas être dupe en pensant que cela -fsignifie --force-with-lease. Voici donc mon avis:
git() {
if [[ $@ == 'push -f'* ]]; then
echo Hey stupid, use --force-with-lease instead
else
command git "$@"
fi
}
rm
àrm -i
votre .bashrc; vous oublierez et supprimerez un jour un fichier important sur un serveur. Aller avec votre propre alias n'a pas ce problème :)pushf
mais j'ai toujours vérifié que je ne faisais pas depush -f
, car il ressemblait à l'alias. Certains membres de l'équipe utilisaient depush -f
toute façon, pensant que l'alias n'était qu'un raccourci cosmétique pour cela. En fin de compte, nous avons aliasé la forme la plus sûre à lapushfl
place et avons cessé de nous en préoccuper.Git 2.13 (Q2 2017) explique pourquoi il n'y a pas de "protection" contre l'oubli de cette option push, car même si vous ne l' oubliez pas au
git push
niveau, elle risque d'être ignorée.Voir commit f17d642 (19 avril 2017) par Ævar Arnfjörð Bjarmason (
avar
) .(Fusionné par Junio C Hamano -
gitster
- in commit 46bdfa3 , 26 avril 2017)Donc, la documentation pour l'
git push
instant comprend:la source
Ma solution était de créer un script wrapper et d'utiliser un alias pour que je l'utilise toujours à la place du réel
git
.Chaque fois que j'essaye
git push -f
, je vois ce qui suit:Certains avantages de ce script sont:
--force-with-lease
, donc je ne me fais pas harceler quand je me trompegit push --force
cela fonctionnera.Comment l'implémenter:
-f
git
Ces instructions supposent Linux ou Mac, exécutant bash. Je n'ai pas essayé cela avec zsh ou Windows, mais je suppose que cela fonctionnera là aussi.
~/.bash_profile
:~./git_wrapper.sh
:Avec ces changements, redémarrez votre terminal et
git
devrait maintenant être à la hauteur lorsque vous essayez de forcer le push.la source
Pour les personnes utilisant OMYZSH, vous pouvez simplement utiliser
ggfl
.la source
Je veux qu'on me rappelle que je ne devrais pas utiliser
-f
, mais je ne veux pas être dupe en pensant que cela-f
signifie--force-with-lease
. Voici donc mon avis:Ajoutez à votre
.bash_profile
,.bashrc
ou.zshrc
.la source
Vous pouvez créer une fonction bash qui remplace
git
et utilise à la--force-with-lease
place de--force
ou, sur une seule ligne:
Ajoutez-le simplement à votre fichier
~/.bashrc
ou~/.zshrc
.la source