push --force-with-lease por padrão

130

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!)

Dan Fabulich
fonte

Respostas:

141

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.

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

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 .

Deixe suas mãos sujas

Se você deseja implementar o recurso sozinho, mas não sabe por onde começar, verifique primeiro o diretório de documentação no repositório git . Aqui você pode encontrar as diretrizes de codificação e informações sobre como enviar patches .

Você pode encontrar todos esses links e muito mais na página oficial da comunidade .

Sascha Wolf
fonte
25
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.

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)

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.

Portanto, a documentação dogit push momento inclui:

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:

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

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.

VonC
fonte
30

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:

  1. crie um script personalizado que passará por quaisquer parâmetros para o git, exceto para -f
  2. 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.

Jessica Knight
fonte
17
Isso parece conveniente. +1. Talvez substituir "hey idiota" por "hey, você alma gentil, mas simples" ou somehing assim;)
VonC
5

Para pessoas que usam OMYZSH, você pode simplesmente usar ggfl.

Nicolas
fonte
3

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
}

Adicione ao seu .bash_profile, .bashrcou .zshrc.

neu242
fonte
1

Você pode criar uma função bash que substitua gite use em --force-with-leasevez de--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
}

ou, em uma linha:

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

Basta adicioná-lo ao seu ~/.bashrcou ~/.zshrc.

paulodiovani
fonte