O que é a flag --end-of-options do git
Existe um problema clássico em ferramentas de linha de comando: e se um nome de arquivo começar com hífen? O shell e o programa interpretam o argumento como uma opcao em vez de um nome de arquivo, causando erros confusos ou comportamentos inesperados.
O git resolveu isso com a flag --end-of-options. Quando você coloca --end-of-options antes de um argumento, você esta dizendo ao git: tudo que vem depois disso e um nome de arquivo ou commit, não uma opcao.
Essa flag existe em vários programas POSIX ha décadas na forma de --, mas o git adicionou a versão nomeada --end-of-options para deixar o comportamento mais explicito e legível. Parece um detalhe pequeno, mas tem implicações reais de segurança em scripts e pipelines de CI/CD.
Como o problema acontece na prática
Imagine que alguém cria uma branch com o nome -f ou --all. Quando você passa esse valor para um comando git sem cuidado, o programa pode interpretar como uma opcao em vez do argumento que você queria.
Um caso mais prático: em pipelines de CI/CD, o nome da branch muitas vezes vem de uma variável de ambiente controlada por quem abre um pull request. Se o pipeline faz git checkout $BRANCH_NAME sem cuidado, um nome de branch malicioso poderia injetar opcoes no comando git.
O --end-of-options e a forma mais limpa de resolver isso: git checkout --end-of-options "$BRANCH_NAME" garante que o valor sempre seja tratado como um nome de branch, não como opcoes.
Em scripts de CI/CD que usam variáveis de ambiente para nomes de branch, commit ou arquivo, use sempre --end-of-options ou -- para separar opcoes de argumentos. E uma prática de segurança, não apenas de estilo.
A diferença entre -- e --end-of-options
O git tem dois separadores parecidos mas com comportamentos diferentes.
-- (duplo traço): separa opcoes de nomes de arquivos. Muito usado para evitar ambiguidade com arquivos que começam com hífen. Exemplo: git checkout -- arquivo.txt garante que arquivo.txt e um caminho, não uma branch.
--end-of-options: mais explicito e mais amplo. Sinaliza que tudo após este ponto e um argumento posicional, seja nome de arquivo, commit, branch ou qualquer coisa. Mais legível em scripts longos.
Em scripts, prefira --end-of-options pela legibilidade. Em uso interativo no terminal, -- e mais rápido de digitar e amplamente entendido pela comunidade.
Como usar: exemplos práticos
Veja situações reais onde essa flag faz diferença:
# Sem --end-of-options: pode falhar se $ARQUIVO começar com hífen
git add $ARQUIVO
# Com --end-of-options: seguro independente do nome
git add --end-of-options "$ARQUIVO"
# Em CI/CD com variável de ambiente para branch
# Inseguro:
git checkout "$BRANCH_NAME"
# Seguro:
git checkout --end-of-options "$BRANCH_NAME"
# Mostrando diff de arquivo com nome esquisito
git diff -- -v
# Verificar commit hash vindo de variável
git show --end-of-options "$COMMIT_HASH"Uma situação clássica e a diferença entre git checkout branch e git checkout -- arquivo. O -- diz ao git que o próximo argumento e um caminho de arquivo. O --end-of-options e mais explicito sobre essa intenção.
Quando escrever scripts que aceitam entradas do usuário e as passam para comandos git, adicione --end-of-options como regra automática. O custo e zero e a proteção contra inputs inesperados e real.
Comparação: git vs outros comandos POSIX
O padrão POSIX define que -- deve finalizar o processamento de opcoes em qualquer utilitário de linha de comando. Esse comportamento existe ha décadas em ls, grep, cp, mv e outros comandos Unix.
O --end-of-options e específico do git e foi adicionado para tornar o comportamento mais explicito. A diferença prática: ls -- -arquivo funciona para listar um arquivo chamado -arquivo. git log --end-of-options -abc123 mostraria o commit -abc123 sem interpretar como opcao.
O conceito e o mesmo, a sintaxe do git e mais legível para quem le scripts complexos.
Pontos positivos e limitações
O --end-of-options resolve de forma limpa um problema real de ambiguidade. E mais legível que --, funciona nos subcomandos principais do git, e a intenção fica clara para quem le o script depois.
As limitações são mínimas: nem todo subcomando do git suporta --end-of-options (alguns mais antigos só reconhecem --), e em uso interativo no terminal digitar a flag completa e menos eficiente. Para uso em scripts, onde a clareza importa mais, e a escolha certa.
O suporte foi adicionado de forma consistente nas versões modernas do git. Se você estiver em um ambiente muito antigo (git anterior a 2.24), use -- como alternativa compatível.
Casos de uso reais
Pipelines de CI/CD: qualquer pipeline que usa o nome da branch como variável em comandos git se beneficia. GitHub Actions, GitLab CI e Jenkins passam o nome da branch como variável de ambiente.
Scripts de automação de repositório: scripts que fazem checkout, merge, tag ou push com base em entradas externas devem usar essa flag por padrão.
Ferramentas de CLI que chamam git internamente: se você esta escrevendo uma CLI em Python ou Go que chama subprocessos git, proteja as chamadas com --end-of-options antes de qualquer argumento que venha de entrada do usuário.
Hooks do git: pre-commit, pre-push e outros hooks que executam comandos git com nomes de arquivo ou referência passados como argumentos se tornam mais robustos com essa prática.
Dicas e boas práticas
Crie um alias no seu .bashrc ou .zshrc para os comandos git mais usados com variáveis: alias gco='git checkout --end-of-options'. Você ganha a proteção sem ter que digitar a flag toda vez.
Mesmo com --end-of-options, sempre valide entradas do usuário em scripts críticos. A flag protege contra interpretação incorreta como opcoes, mas não contra outros tipos de inputs maliciosos como path traversal.
Nunca use interpolação de variáveis sem aspas em comandos git em shell scripts: git checkout $BRANCH pode sofrer word splitting. Sempre use aspas: git checkout --end-of-options "$BRANCH".
Vale a pena usar git --end-of-options?
Sim, especialmente em qualquer contexto automatizado. Em uso interativo, o -- já e suficiente e mais rápido de digitar. Mas em scripts, pipelines e ferramentas que passam argumentos dinâmicos para o git, adotar --end-of-options como padrão e uma decisão de qualidade que custa zero.
A maioria dos problemas causados por essa ambiguidade aparece raramente, o que significa que quando aparecem são difíceis de diagnosticar. Prevenir com uma flag e muito mais barato que debugar um pipeline de CI/CD com comportamento esquisito.
O próximo passo e revisar seus scripts que chamam git com variáveis e adicionar a flag onde ela esta faltando. Uma busca rápida por git checkout $ ou git add $ no seu repositório de scripts e um bom ponto de partida.
Comentários
Deixar um comentárioVocê precisa ter uma conta no DevLevelUp para comentar.