Eu acabei de aprender git push --force-with-lease. É incrível. Mas, é claro, eu não uso a força com tanta frequência e, por isso, estou preocupado em esquecer esse recurso bacana da próxima vez que precisar.
Existe uma maneira de configurar o git para que git push -fele --force-with-leaseseja usado automaticamente, a menos que eu o substitua intencionalmente --no-force-with-lease?
(Não consigo imaginar querer usar a força sem concessão!)
AFAIK não há configuração disponível para dizer ao git para sempre usar em force-with-leasevez de force. Este parece ser um bom exemplo para uma solicitação de recurso; se você não tiver nenhum problema para mergulhar na base de código git, poderá implementá-lo e enviá-lo para revisão.
EDITAR Tal como está, isso ainda é verdade em abril de 2019.
Até então, a única opção que vejo é, com tanta frequência, criar uma aliasque atenda a esse propósito.
Crie um alias
Para criar um alias que se usaria git config --global alias.<alias-name> <command>, no nosso caso, eu sugeriria algo semelhante a isso.
Isso criará uma entrada no seu .gitconfigarquivo global (que geralmente você pode encontrar no diretório inicial ). Depois disso, você pode simplesmente usar git pushfpara forçar com locação .
Uma observação sobre isso não ser um recurso: o argumento comum contra a reescrita de comandos padrão ("push - force") é que você se acostuma com eles, esquece sua origem e um dia acidentalmente os usa dessa maneira em um novo sistema. Muito parecido com aliasing rmpara rm -iem seu .bashrc; você esquecerá e excluirá um arquivo importante em um servidor algum dia. Indo com seus próprios alias não tem esse problema :)
Hraban
2
Anedota pessoal / palavra de cautela: tentei usar o alias, pushfmas sempre verifiquei duas vezes que não estava fazendo um push -f, por parecer semelhante ao alias. Alguns membros da equipe estavam usando de push -fqualquer maneira, pensando que o apelido era apenas uma abreviação cosmética para ele. Por fim, aliasmos a forma mais segura pushfle paramos de nos preocupar com ela.
22419 kelvin
31
Estou preocupado que eu possa esquecer esse recurso bacana da próxima vez que precisar.
O Git 2.13 (Q2 2017) explica por que não há "proteção" contra esta opção de envio sendo esquecida, porque mesmo que você não a esqueça no git pushnível, ela ainda pode ser ignorada.
push: documento e teste --force-with-leasecom vários controles remotos
Documente e teste os casos em que existem dois controles remotos apontando para a mesma URL e uma busca em segundo plano e subsequente git push --force-with-leasenão devem refutar referências não atualizadas que não foram buscadas.
Alguns editores como o VSC da Microsoft têm um recurso para buscar automaticamente em segundo plano, isso ignora as proteções oferecidas por --force-with-lease&--force-with-lease=<refname> , conforme observado na documentação adicionada aqui.
observação geral sobre segurança: fornecer esta opção sem um valor esperado, ou seja, como --force-with-leaseou --force-with-lease=<refname>
interage muito mal com qualquer coisa que implícita seja executada git fetchno controle remoto para ser empurrada para segundo plano, por exemplo, git fetch origin
no seu repositório em um cronjob.
A proteção oferecida --forceé garantir que as alterações subsequentes nas quais seu trabalho não foi baseado não sejam prejudicadas, mas isso será derrotado trivialmente se algum processo em segundo plano estiver atualizando as referências em segundo plano. Não temos nada, exceto as informações de rastreamento remoto, como uma heurística para os árbitros que você deve ter visto e está disposto a adotar.
Se o seu editor ou outro sistema estiver sendo executado git fetchem segundo plano para você, uma maneira de atenuar isso é simplesmente configurar outro controle remoto:
Agora, quando o processo em segundo plano for executado, git fetch originas referências origin-pushnão serão atualizadas e, portanto, comandos como:
git push --force-with-lease origin-push
Falhará, a menos que você execute manualmente git fetch origin-push.
É claro que esse método é totalmente derrotado por algo que é executado git fetch
--all; nesse caso, você precisa desativá-lo ou fazer algo mais entediante como:
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
Ou seja, crie uma basetag para versões do código upstream que você viu e deseja sobrescrever, depois reescreva o histórico e, finalmente, force as alterações por push para masterse a versão remota ainda estiver base, independentemente do local em que seu local remotes/origin/masterfoi atualizado. fundo.
Minha solução foi criar um script de wrapper e usar um alias para que eu sempre o use no lugar do real git.
Sempre que tento git push -f, vejo o seguinte:
⚡ git push -f
use this instead so you don't cause race conditions in the
repo: git push --force-with-lease
Algumas vantagens deste script são:
ele me treina para usar habitualmente --force-with-lease, para que eu não seja incomodado quando entendi errado
se, por algum motivo, realmente forçarmos o impulso, git push --forcefuncionará.
Como implementá-lo:
crie um script personalizado que passará por quaisquer parâmetros para o git, exceto para -f
alias esse script, então usamos em vez de git
Essas instruções assumem Linux ou Mac, executando o bash. Eu não tentei isso com o zsh ou Windows, mas presumo que funcione lá também.
~/.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 "$@"
Com essas alterações, reinicie o seu terminal e gitagora deve ficar animado ao tentar forçar o push.
Quero ser lembrado de que não devo usar -f, mas não quero ser enganado a acreditar que isso -fsignifica --force-with-lease. Então esta é a minha opinião:
git() {
if [[ $@ == 'push -f'* ]]; then
echo Hey stupid, use --force-with-lease instead
else
command git "$@"
fi
}
rm
pararm -i
em seu .bashrc; você esquecerá e excluirá um arquivo importante em um servidor algum dia. Indo com seus próprios alias não tem esse problema :)pushf
mas sempre verifiquei duas vezes que não estava fazendo umpush -f
, por parecer semelhante ao alias. Alguns membros da equipe estavam usando depush -f
qualquer maneira, pensando que o apelido era apenas uma abreviação cosmética para ele. Por fim, aliasmos a forma mais segurapushfl
e paramos de nos preocupar com ela.O Git 2.13 (Q2 2017) explica por que não há "proteção" contra esta opção de envio sendo esquecida, porque mesmo que você não a esqueça no
git push
nível, ela ainda pode ser ignorada.Veja commit f17d642 (19 de abril de 2017) por Ævar Arnfjörð Bjarmason (
avar
) .(Mesclado por Junio C Hamano -
gitster
- na commit 46bdfa3 , 26 de abril de 2017)Portanto, a documentação do
git push
momento inclui:fonte
Minha solução foi criar um script de wrapper e usar um alias para que eu sempre o use no lugar do real
git
.Sempre que tento
git push -f
, vejo o seguinte:Algumas vantagens deste script são:
--force-with-lease
, para que eu não seja incomodado quando entendi erradogit push --force
funcionará.Como implementá-lo:
-f
git
Essas instruções assumem Linux ou Mac, executando o bash. Eu não tentei isso com o zsh ou Windows, mas presumo que funcione lá também.
~/.bash_profile
:~./git_wrapper.sh
:Com essas alterações, reinicie o seu terminal e
git
agora deve ficar animado ao tentar forçar o push.fonte
Para pessoas que usam OMYZSH, você pode simplesmente usar
ggfl
.fonte
Quero ser lembrado de que não devo usar
-f
, mas não quero ser enganado a acreditar que isso-f
significa--force-with-lease
. Então esta é a minha opinião:Adicione ao seu
.bash_profile
,.bashrc
ou.zshrc
.fonte
Você pode criar uma função bash que substitua
git
e use em--force-with-lease
vez de--force
ou, em uma linha:
Basta adicioná-lo ao seu
~/.bashrc
ou~/.zshrc
.fonte