Revisão de código para empurrar a ramificação atual com um script bash

2

Olá pessoal, isso é mais uma revisão de código do que qualquer outra coisa e também para pedir algum esclarecimento. Acabei de escrever o seguinte script: que envia minha ramificação atual para sua parte remota do contador.

#!/usr/bin/env bash

# Usage: pushes current checkout branch to its remote counterpart.

current_branch=$(git symbolic-ref HEAD 2>/dev/null) ||
current_branch="(unnamed branch)"

git push origin ${current_branch}

Eu tenho a coisa git symbolic-ref ... depois de pesquisar como realizar o que estou tentando fazer. Parece fazer o que eu quero, mas existe outra maneira de conseguir isso?

Também não entendo o que esta parte significa / faz 2>/dev/null

EDITAR: depois de ler um pouco os bashdocs eu acho é algum rei de redirecionamento?

    
por intercoder 11.09.2018 / 15:07

2 respostas

4

Ok, aqui vai a revisão de código.

# Usage: pushes current checkout branch to its remote counterpart.

Ignora a primeira palavra. Este é um comentário descrevendo o que o script faz, não como usá-lo.

current_branch=$(git symbolic-ref HEAD 2>/dev/null) ||
current_branch="(unnamed branch)"

Você está executando git symbolic-ref HEAD , descartando seu stderr e atribuindo o stdout a uma variável. Caso isso falhe, você usa o nome da ramificação (unnamed branch) .

git push origin ${current_branch}

No final, você está empurrando sua filial local para a origem.

Aqui estão algumas explicações:

A parte 2 > / dev / null

Todo programa rodando em um terminal Linux / Unix possui um canal de entrada chamado stdin , que normalmente coleta sua entrada do teclado. Ele também possui dois canais de saída chamados stdout (saída padrão para impressão de informações normais de operação) e stderr (erro padrão para impressão de avisos e erros de tempo de execução). Esses canais estão tendo sua origem no hardware, mas agora são um padrão de software puro que todos os terminais suportam. A maneira como o Bash lida com os canais stdout e stderr é através dos ponteiros representados pelos números 1 e 2 . O que a parte 2> está fazendo é dizer ao programa para redirecionar seu stderr para um destino diferente. /dev/null é um dispositivo virtual que basicamente atua como um buraco negro. Qualquer coisa enviada lá é perdida. Assim, o 2>/dev/null significa literalmente "não imprima qualquer saída não padrão".

O || parte

O canal duplo no bash significa: Se o programa no lado esquerdo falhou, isto é, retornado com um código de saída que não é 0 , execute o lado direito do tubo duplo. Seu lado "direito" continua na próxima linha, onde você atribui à mesma variável um valor de fallback.

Agora voltemos à revisão.

Você deseja enviar sua ramificação recém-criada para uma ramificação remota na origem e deseja que ela tenha o mesmo nome da ramificação local.

Seu código não faz isso. Bem, não de forma confiável.

HEAD in git é uma referência especial que aponta para o commit mais recente em sua ramificação atualmente retirada, se houver alguma. A última parte é onde o seu código é perigoso. HEAD não está necessariamente sempre apontando para uma ramificação. Também pode estar em um chamado estado HEAD separado. Nesse caso, seu comando falhará com o erro fatal: ref HEAD is not a symbolic ref . Esse erro é descartado pelo seu script e, em vez disso, continuaria com o nome da ramificação (unnamed branch) . A última linha tentaria empurrar sua ramificação local como (unnamed branch) , o que você provavelmente não deseja.

Mesmo que o comando seja bem-sucedido, você obterá a saída como refs/heads/yourbranchname . Você pode usar a opção --short para obter apenas a última parte:

git symbolic-ref --short HEAD

O resultado será:

yourbranchname

E se não tivermos uma filial? Simples. Você não quer empurrar nada! Você deve preferir sair do script se o nome da ramificação não puder ser determinado. Você pode fazer isso das seguintes maneiras. Adicione um exit $errorcode explícito ou use o set -e flag do bash:

current_branch=$(git symbolic-ref HEAD) || exit $?

Aqui $? contém o código de saída do último comando, portanto, a chamada git com falha. Você não precisa esconder o stderr . É útil determinar o que deu errado.

Alternativamente:

set -e
current_branch=$(git symbolic-ref HEAD)

O set -e ativa um modo especial de bash, onde ele sai do script em cada erro. Eu o encorajo a usá-lo em todos os roteiros.

Próxima parte:

git push origin ${current_branch}

Não há nada de errado com este comando, mas acho que você está fazendo sua própria vida um pouco difícil. Esse comando detalhado é necessário apenas uma vez para criar um link entre a ramificação local e o remoto. Você pode salvar esse link usando a opção -u da seguinte forma:

git push -u origin ${current_branch}

Depois de executar este comando uma vez, você pode digitar git push e ele será automaticamente enviado para o ramo remoto correto. Tenha em mente que quando você faz check-out ou clona ramificações remotas, esse link é estabelecido automaticamente. Isso é necessário apenas para ramos que foram criados localmente.

Vamos resumir

Você pode querer reescrever seu script assim:

#!/usr/bin/env bash

# Pushes current checkout branch to its remote counterpart.

set -e

current_branch=$(git symbolic-ref --short HEAD)
git push -u origin "${current_branch}"

Depois de executá-lo uma vez para uma nova ramificação, use:

git push
    
por 11.09.2018 / 15:47
2

Veja a configuração push.default em git help config .

Citarei parte disso:

   push.default
       Defines the action git push should take if no refspec is
       explicitly given. Different values are well-suited for specific
       workflows; for instance, in a purely central workflow (i.e. the
       fetch source is equal to the push destination), upstream is
       probably what you want. Possible values are:

       ...

       o   current - push the current branch to update a branch with
           the same name on the receiving end. Works in both central
           and non-central workflows.

Então, em suma, execute git config --global push.default current uma vez em sua máquina e depois use git push a partir de agora.

A moral da história é uma das minhas duas regras principais de escrita de roteiro:

Sempre verifique os documentos antes de inventar uma nova roda. Com muita frequência (para ferramentas amplamente usadas), já existe uma opção para fazer exatamente o que você precisa sem escrever seu próprio "shim" scripts.

(Violações desta regra, onde um longo e complexo script "wrapper" foi escrito para uma ferramenta na ignorância de uma determinada linha de comando que fará a mesma coisa, são muito comuns e muito dolorosas de ver.)

    
por 12.09.2018 / 02:57