Tema: version-control
-
Tags e releases: tags leves versus anotadas e como elas se propagam
Uma tag leve é apenas um nome para um commit; uma tag anotada é um objeto com autor, data, mensagem e assinatura opcional. Por isso o git describe ignora tags leves por padrão e os releases devem usar tags anotadas ou assinadas. As tags não são enviadas junto com os branches, a menos que se use --follow-tags ou --tags, e uma tag já publicada nunca deve ser movida.
-
Cherry-pick: quando é adequado e o que custa ao histórico
O git cherry-pick reaplica a alteração de um commit como um novo commit com outro ID; é a ferramenta certa para fazer backport de uma correção para uma branch de manutenção ou resgatar um commit de uma branch abandonada, mas cada pick cria uma duplicata que os merges não reconhecem. Por isso, registre a origem com -x e faça merge em vez de pick quando quiser a branch inteira.
-
Recuperar commits e branches perdidos com o reflog
O reflog registra todos os movimentos de HEAD e de cada branch no repositório local. Assim, é possível desfazer um reset, rebase, amend ou exclusão de branch ruins: basta localizar a posição anterior e criar uma nova branch nela. Por padrão, as entradas expiram após 90 dias (30 para as inalcançáveis), e alterações não commitadas nunca estiveram nele.
-
Boas mensagens de commit: registrar o porquê da mudança
Uma linha de assunto de cerca de 50 caracteres no imperativo, uma linha em branco e um corpo que explica a motivação, as alternativas e as consequências, em vez de recontar o diff.
-
Rebase ou merge: como integrar uma branch
O merge preserva o histórico tal como aconteceu e adiciona um commit de merge; o rebase reescreve uma branch sobre uma nova base para obter um histórico linear. Nunca faça rebase de commits nos quais outras pessoas basearam o trabalho delas.
-
Importações de assets reproduzíveis: preserve identidade, configurações e versões das ferramentas
Monte um fluxo de trabalho de assets que possa ser reconstruído a partir de um checkout limpo, preservando os arquivos de origem, a identidade das referências, a configuração do importador e a toolchain prevista.
-
Assinar commits e tags com uma chave SSH ou GPG
O Git assina commits e tags com OpenPGP, X.509 ou, desde gpg.format=ssh, uma chave SSH simples; quem assina define gpg.format e user.signingKey, quem verifica precisa de um arquivo de signatários permitidos (SSH) ou de um chaveiro confiável (GPG), e nas plataformas a checagem é feita com git verify-commit ou com o selo de assinatura do host.
-
Como manter commits de reformatação fora do git blame: -w e arquivos ignore-revs
O git blame -w ignora espaços em branco ao rastrear linhas; --ignore-rev e um arquivo .git-blame-ignore-revs versionado pulam commits indicados, como reformatações em massa, e atribuem as linhas à alteração significativa anterior; -M/-C acompanham linhas movidas ou copiadas. O GitHub lê esse mesmo arquivo automaticamente.
-
Usar o stash com segurança: mensagens, arquivos não rastreados e branches de stash
Um stash é um commit guardado em refs/stash, cujas entradas mais antigas existem apenas no reflog dessa referência. Dê uma mensagem a cada stash, inclua arquivos não rastreados de forma deliberada, prefira apply a pop até verificar o resultado e use git stash branch quando a base tiver avançado.
-
Conventional Commits: tipos de commit legíveis por máquina
A especificação Conventional Commits acrescenta às mensagens de commit um prefixo tipado (feat, fix e outros) e marcadores de breaking change, para que changelogs e incrementos de versão possam ser derivados automaticamente.
-
Códigos de saída do git em que um agente pode confiar: diff --exit-code, ls-remote --exit-code e o 125 do bisect run
A maioria dos comandos porcelain do git documenta apenas «código diferente de zero em caso de falha», sem tabela numérica fixa, mas três comandos têm um contrato exato e citável: git diff/--quiet usa 1 para diferenças, git ls-remote --exit-code usa 2 quando não há refs correspondentes, e git bisect run reserva o 125 para «ignorar este commit», não para «ruim». Um merge com conflito é indicado por estado (MERGE_HEAD), não por um número documentado.
-
Trabalhando em um repositório grande com sparse checkout e partial clone
O sparse checkout limita quais diretórios aparecem na árvore de trabalho (o modo cone lista diretórios), o partial clone com --filter=blob:none adia o download do conteúdo dos arquivos até que seja necessário, e o shallow clone trunca o histórico; os três resolvem problemas diferentes e podem ser combinados, mas o partial clone exige que o promisor remote esteja online.
-
Como escolher um fluxo de trabalho de branches no Git
Mostra como branches de longa duração e branches de tópico se combinam num fluxo de trabalho e quais perguntas definem a escolha entre os modelos trunk-based, feature branch e release branch.
-
Como escrever mensagens de commit que explicam o porquê
Um formato curto e verificável para mensagens de commit: uma linha de resumo de até cerca de 50 caracteres, uma linha em branco e um corpo que explica a motivação e as consequências em vez de repetir o diff.
-
Remover binários grandes do histórico do Git com git filter-repo
Um repositório continua grande depois de um arquivo pesado ser apagado, porque cada clone carrega todo o histórico. Para reduzi-lo, é preciso localizar os blobs problemáticos, reescrever com git filter-repo todos os commits que os contêm num clone novo, fazer force push de todas as branches e tags e pedir que todos clonem de novo, já que os commits reescritos têm novos IDs.
-
Desenvolvimento baseado em trunk e branches de curta duração
Integrar o trabalho de todos numa única linha compartilhada pelo menos uma vez por dia, manter os branches de curta duração e esconder o trabalho inacabado atrás de feature flags reduz conflitos de merge e torna a integração contínua real.
-
.gitattributes: fins de linha, diff drivers, merge drivers e export-ignore
Um arquivo .gitattributes versionado define o comportamento por caminho para toda a equipe: text=auto e eol normalizam fins de linha, diff= atribui padrões de cabeçalho de hunk ou textconv para binários, merge= escolhe um driver como union, binary marca arquivos que devem ficar intactos e export-ignore exclui caminhos do git archive.
-
Submodules, subtrees ou vendoring: três formas de incluir outro repositório
Um submodule registra um ponteiro (gitlink) para um commit de outro repositório e exige comandos extras de cada usuário; o git subtree copia os arquivos do outro projeto, e opcionalmente seu histórico, para um subdiretório que se comporta como arquivos comuns; o vendoring simples copia os arquivos e registra manualmente a versão do upstream. A escolha depende da frequência com que a dependência muda e de quem precisa conseguir clonar.
-
Como limpar uma branch antes da revisão
Antes de pedir revisão, faça squash dos commits de correção, divida os que misturam assuntos e reescreva as mensagens, de modo que cada commit seja uma única alteração revisável; git rebase -i e autosquash cuidam da parte mecânica.
-
Git LFS: arquivos de ponteiro, filtros smudge e quando não usar
O Git LFS substitui arquivos grandes rastreados por pequenos ponteiros de texto (version, oid sha256, size) e guarda o conteúdo em um servidor separado por meio dos filtros clean e smudge. Mantém os clones pequenos, mas adiciona um segundo sistema de armazenamento com cotas próprias, e por isso usá-lo para ativos pequenos que mudam pouco ou para saídas de build geralmente custa mais do que economiza.
Legível por máquina: JSON