Ampliação do Git

Stefan Saasen
Stefan Saasen
Voltar para a lista

Enquanto o Mercurial tem uma API bem definida (embora interna) que pode ser usada para escrever extensões que ampliam a funcionalidade do Mercurial, o modelo de extensão do Git segue a filosofia Unix de compor programas pequenos e simples para obter um efeito semelhante. Ou seja: as "extensões" do Git podem ser escritas em qualquer linguagem, e, seguindo algumas regras simples, ainda é possível adicionar comandos que aparecem como se fossem integrados.

Exemplo: atividade git

Para ver a atividade em todas as ramificações em um repositório, implementei um comando git activity. O git activity mostra a confirmação mais recente em cada ramificação, classificada pelo mais recente.

Ele mostra o seguinte resultado quando executado no repositório Rails:

Saída do Rails

O roteiro é gravado em bash e é bastante simples. Configuramos cores e analisamos algumas opções de linha de comando que os scripts suportam (por exemplo, para desativar cores, limitar a saída) e, em seguida, a gente executa o git for-each-ref para gerar informações sobre cada ref.

 #!/bin/bash set -e GIT_OPTS="" OUTPUT_FILTER="cat" # no-op commit_id_format=$(tput setaf 1) date_format=$(tput bold; tput setaf 4) author_format=$(tput setaf 2) ref_name_format=$(tput setaf 3) bold=$(tput bold) reset=$(tput sgr0) function usage() { echo "" echo "git activity" echo "" echo " Consulte 'man git-activity' para obter mais informações" } # na verdade analisa as opções e realiza ações enquanto [[ $1 = -?* ]]; do case $1 in -h|--help) usage exit 0 ;; --fetch) echo "Fetch updates" git fetch -q ;; -c|--count) shift limit=${1-"10"} #OUTPUT_FILTER="tail -n ${limit}" GIT_OPTS="--count=${limit}" ;; --no-color|--no-color) commit_id_format="" date_format="" author_format="" ref_name_format="" bold="" reset="" ;; *) ;; esac shift done # Use uma nova linha como separador de campo IFS=$(echo -en "\n\b") # Use tac se disponível, caso contrário complete com possivelmente-nem-sempre-disponível⏎# -r flag (para saída reversa) TAC=$(which tac || echo 'tail -r') para linha em $(git for-each-ref ${GIT_OPTS} refs/remotes --format="%(authordate:relative)|%(objectname:short)|%(authorname)|%(refname:short)|%(subject)" --sort="-authordate"); do fields=(`echo $line | tr "|" "\n"`) printf "${date_format}%15s${reset} ${commit_id_format}%s${reset} - ${author_format}[%s]${reset} (${ref_name_format}%s${reset}): %s\n" ${fields[*]} done | eval $TAC # classifica em ordem invertida a saída para exibir a entrada mais recente por último

As regras importantes a serem seguidas para tornar esse script disponível como um subcomando git são:

  • Ele deve ser chamado de git-COMMANDNAME, neste caso, é chamado de git-activity
  • e ele precisa ser executável e estar disponível no $PATH. No meu exemplo, o script git-activity personalizado está no diretório /usr/local/bin, mas pode estar em qualquer diretório que esteja no $PATH:
[5002] λ > type git-activity git-activity is /usr/local/bin/git-activity [5002] λ > git activity [...]

Disponibilizar um manual/página de ajuda

Se o comando personalizado tiver uma página de manual que o acompanha, o comando git help também vai mostrar as informações de ajuda. Por exemplo, a página do manual do comando activity está localizada em /usr/local/share/man/man1/git-activity.1 e pode ser exibida por man git-activity ou git help activity.

O comando manpath pode ser usado para mostrar os locais que o sistema usa para localizar páginas de manual:

[5003] λ > manpath /Users/ssaasen/.opam/system/man:/usr/local/share/man:/usr/share/man:\ /Users/ssaasen/.cabal/share/man:/opt/scala/man

A saída para git help activity é (usando https://bitbucket.org/ssaasen/git-pastiche/src/master/man/git-activity.1):

Página do manual de atividades do Git

Dicas bônus: as páginas de manual podem ser facilmente geradas a partir do Markdown usando o pandoc:

[5010] λ > pandoc -s -w man doc/git-activity.1.md -o ./distribution/man/git-activity.1 # Exibe a página man para testes [5011] λ > nroff -man ./distribution/man/git-activity.1 # Mostra a página man real sendo usada após copiá-la para um local manpath conhecido: [5012] λ > man -wa git-activity /usr/local/share/man/man1/git-activity.1

Conclusão

Seguindo algumas regras simples e adotando o modelo Unix de composição de funcionalidades a partir de programas e scripts pequenos e concentrados, pode ser verificado que é surpreendentemente fácil estender a funcionalidade do git e tornar os comandos personalizados parte do conjunto de comandos git.

Mais extensões

A fonte para o git-activity e alguns outros comandos podem ser encontrados aqui: https://bitbucket.org/ssaasen/git-pastiche

Outros comandos adicionais do git podem ser encontrados aqui:

Pronto(a) para aprender Git?

Tente este tutorial interativo.

Comece agora mesmo