Este é o comando git-filter-branch que pode ser executado no provedor de hospedagem gratuita OnWorks usando uma de nossas várias estações de trabalho online gratuitas, como Ubuntu Online, Fedora Online, emulador online do Windows ou emulador online do MAC OS
PROGRAMA:
NOME
git-filter-branch - Reescrever branches
SINOPSE
git ramo-filtro [--env-filter ] [--tree-filter ]
[--index-filter ] [--parent-filter ]
[--msg-filter ] [--commit-filter ]
[--tag-name-filter ] [--subdirectory-filter ]
[--prune-vazio]
[--original ] [-d ] [-f | --força]
[-] [ ...]
DESCRIÇÃO
Permite reescrever o histórico de revisão do Git reescrevendo os ramos mencionados no
opções>, aplicando filtros personalizados em cada revisão. Esses filtros podem modificar cada árvore
(por exemplo, removendo um arquivo ou executando uma reescrita perl em todos os arquivos) ou informações sobre cada
comprometer-se. Caso contrário, todas as informações (incluindo tempos de confirmação originais ou informações de mesclagem)
será preservado.
O comando apenas reescreverá o positivo refs mencionados na linha de comando (por exemplo, se você
passar a..b, só b será reescrito). Se você não especificar nenhum filtro, os commits serão
confirmado sem quaisquer alterações, o que normalmente não teria efeito. No entanto, este
pode ser útil no futuro para compensar alguns bugs do Git ou algo parecido, portanto, tal
o uso é permitido.
NOTA: Este comando honra o arquivo .git / info / grafts e refs no refs / replace / namespace.
Se você tiver quaisquer enxertos ou refs de substituição definidos, a execução deste comando os tornará
permanente.
ATENÇÃO! O histórico reescrito terá nomes de objetos diferentes para todos os objetos e
não convergirá com o ramo original. Você não será capaz de empurrar e
distribua o ramo reescrito sobre o ramo original. Por favor, não use isso
comando se você não souber todas as implicações e evite usá-lo de qualquer maneira, se um simples
um único commit seria suficiente para resolver o seu problema. (Veja a seção "RECUPERANDO DO UPSTREAM
Seção REBASE "em git-rebase(1) para obter mais informações sobre a reescrita publicada
história.)
Sempre verifique se a versão reescrita está correta: As referências originais, se diferente de
os reescritos, serão armazenados no namespace refs / original /.
Observe que, uma vez que esta operação é muito cara de I / O, pode ser uma boa ideia redirecionar
o diretório temporário fora do disco com o -d opção, por exemplo, em tmpfs. Supostamente a aceleração
é muito perceptível.
Filtros
Os filtros são aplicados na ordem listada abaixo. o argumento é sempre
avaliada no contexto do shell usando o avaliação comando (com a notável exceção do
filtro de confirmação, por razões técnicas). Antes disso, a variável de ambiente $ GIT_COMMIT
será definido para conter o id do commit sendo reescrito. Além disso, GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL e
GIT_COMMITTER_DATE são retirados do commit atual e exportados para o ambiente, em
a fim de afetar as identidades do autor e do committer do commit de substituição criado por
git-commit-tree(1) depois que os filtros forem executados.
Se houver avaliação de retorna um status de saída diferente de zero, toda a operação será
abortada.
A mapa, está disponível uma função que leva um argumento "sha1 id original" e produz um
"reescrito sha1 id" se o commit já foi reescrito, e "sha1 id original"
de outra forma; a mapa, função pode retornar vários ids em linhas separadas se o seu filtro de confirmação
emitiu vários commits.
OPÇÕES
--env-filter
Este filtro pode ser usado se você só precisa modificar o ambiente no qual o commit
será realizado. Especificamente, você pode querer reescrever o autor / committer
variáveis de ambiente de nome / e-mail / horário (ver git-commit-tree(1) para detalhes). Não
esqueça de exportar novamente as variáveis.
--tree-filter
Este é o filtro para reescrever a árvore e seu conteúdo. O argumento é avaliado
no shell com o diretório de trabalho definido como a raiz da árvore em check-out. O novo
árvore é então usada como está (novos arquivos são adicionados automaticamente, arquivos desaparecidos são removidos automaticamente
- nem arquivos .gitignore nem quaisquer outras regras de ignorar TEM QUALQUER EFEITO!).
--index-filter
Este é o filtro para reescrever o índice. É semelhante ao filtro de árvore, mas
não verifique a árvore, o que o torna muito mais rápido. Freqüentemente usado com git rm
--cached --ignore-unmatch ..., veja EXEMPLOS abaixo. Para casos cabeludos, veja git-update-
índice(1).
--parent-filter
Este é o filtro para reescrever a lista pai do commit. Vai receber o pai
string em stdin e deve produzir a nova string pai em stdout. A string pai é
no formato descrito em git-commit-tree(1): vazio para o commit inicial, "-p
pai "para um commit normal e" -p pai1 -p pai2 -p pai3 ... "para uma fusão
comprometer-se.
--msg-filter
Este é o filtro para reescrever as mensagens de confirmação. O argumento é avaliado no
shell com a mensagem de confirmação original na entrada padrão; sua saída padrão é usada
como a nova mensagem de confirmação.
--commit-filter
Este é o filtro para realizar o commit. Se este filtro for especificado, ele será
chamado em vez do git árvore de confirmação comando, com argumentos da forma "
[(-p ) ...] "e a mensagem de log no stdin. O ID do commit é esperado
em stdout.
Como uma extensão especial, o filtro de confirmação pode emitir vários IDs de confirmação; nesse caso,
os filhos reescritos do commit original terão todos eles como pais.
Você pode usar o mapa, função de conveniência neste filtro, e outras conveniências
funções também. Por exemplo, ligando skip_commit "$ @" vai deixar de fora a corrente
commit (mas não suas mudanças! Se você quiser isso, use git rebase em vez de).
Você também pode usar o git_commit_non_empty_tree "$ @" em vez do git commit-tree "$ @" se
você não deseja manter compromissos com um único pai e isso não altera o
árvore.
--tag-name-filter
Este é o filtro para reescrever nomes de tag. Quando aprovado, será chamado para cada
tag ref que aponta para um objeto reescrito (ou para um objeto tag que aponta para um
objeto reescrito). O nome da tag original é passado via entrada padrão, e a nova tag
o nome é esperado na saída padrão.
As marcas originais não são excluídas, mas podem ser substituídas; use "--tag-name-filter cat"
para simplesmente atualizar as tags. Neste caso, seja muito cuidadoso e certifique-se de ter o
tags antigas com backup caso a conversão tenha ocorrido.
A reescrita quase adequada de objetos de tag é suportada. Se a tag tiver uma mensagem
anexado, um novo objeto tag será criado com a mesma mensagem, autor e
carimbo de data / hora. Se a etiqueta tiver uma assinatura anexada, a assinatura será removida. Isto é
por definição, impossível preservar assinaturas. A razão pela qual isso é "quase" adequado,
é porque idealmente se a tag não mudou (aponta para o mesmo objeto, tem o mesmo
nome, etc.) deve manter qualquer assinatura. Esse não é o caso, as assinaturas irão
sempre ser removido, o comprador deve ficar atento. Também não há suporte para alterar o autor ou
timestamp (ou a mensagem da tag). Tags que apontam para outras tags serão
reescrito para apontar para o commit subjacente.
--subdirectory-filter
Observe apenas o histórico que toca o subdiretório fornecido. O resultado conterá
esse diretório (e apenas isso) como sua raiz do projeto. Implica a seção chamada “Remapear
ao ancestral ”.
--prune-vazio
Alguns tipos de filtros irão gerar commits vazios, que deixaram a árvore intacta. Esse
switch permite que git-filter-branch ignore tais commits. Porém, esta opção apenas
aplica-se a commits que têm um e apenas um pai, portanto, manterá as mesclagens
pontos. Além disso, esta opção não é compatível com o uso de --commit-filtro. Embora
você só precisa usar a função git_commit_non_empty_tree "$ @" em vez do git
commit-tree "$ @" idiom em seu filtro de commit para fazer isso acontecer.
--original
Use esta opção para definir o namespace onde os commits originais serão armazenados. o
o valor padrão é refs / original.
-d
Use esta opção para definir o caminho para o diretório temporário usado para regravar. Quando
aplicando um filtro de árvore, o comando precisa verificar temporariamente a árvore para alguns
diretório, que pode consumir um espaço considerável no caso de grandes projetos. Por padrão
faz isso no .git-rewrite / diretório, mas você pode substituir essa escolha por este
parâmetro.
-f, --força
git ramo-filtro recusa-se a começar com um diretório temporário existente ou quando lá
já são árbitros começando com refs / original /, a menos que forçado.
...
Argumentos para git lista de rev. Todas as referências positivas incluídas por essas opções são reescritas.
Você também pode especificar opções como --tudo, mas você deve usar -- para separá-los de
da git ramo-filtro opções. Implica a seção chamada “Remapear para ancestral”.
Remapear para antepassado
Usando lista de rev(1) argumentos, por exemplo, limitadores de caminho, você pode limitar o conjunto de revisões
que são reescritos. No entanto, referências positivas na linha de comando são diferenciadas: nós
não os deixe ser excluídos por tais limitadores. Para este propósito, eles são reescritos
para apontar para o ancestral mais próximo que não foi excluído.
EXEMPLOS
Suponha que você deseja remover um arquivo (contendo informações confidenciais ou direitos autorais
violação) de todos os commits:
git filter-branch --tree-filter 'nome do arquivo rm' HEAD
No entanto, se o arquivo estiver ausente da árvore de algum commit, um simples nome de arquivo rm irá
falhe para aquela árvore e se comprometa. Assim, você pode querer usar rm -f nome do arquivo como o
script.
Usando --index-filter com git rm produz uma versão significativamente mais rápida. Como usar rm
nome do arquivo, git rm - nome do arquivo em cache irá falhar se o arquivo estiver ausente da árvore de um
comprometer-se. Se você quiser "esquecer completamente" um arquivo, não importa quando ele entrou
histórico, então também adicionamos --ignore-unmatch:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
Agora, você obterá o histórico reescrito salvo no HEAD.
Para reescrever o repositório para parecer como se foodir / tivesse sido a raiz do projeto, e descartar todos
outra história:
git filter-branch --subdirectory-filter foodir - --todos
Assim, você pode, por exemplo, transformar um subdiretório de biblioteca em um repositório próprio. Note o --
que separa ramo-filtro opções de opções de revisão, e o --all para reescrever todos
ramos e marcas.
Para definir um commit (que normalmente está na ponta de outra história) para ser o pai do
commit inicial atual, a fim de colar o outro histórico por trás do histórico atual:
git filter-branch --parent-filter 'sed "s / ^ \ $ / - p /"' CABEÇA
(se a string pai estiver vazia - o que acontece quando estamos lidando com o commit inicial
- adicionar graftcommit como pai). Observe que isso pressupõe histórico com uma única raiz (que
ou seja, nenhuma mesclagem sem ancestrais comuns aconteceu). Se este não for o caso, use:
git filter-branch --filtro-pai \
'teste $ GIT_COMMIT = && echo "-p CABEÇA "|| gato '
ou ainda mais simples:
echo "$ commit-id $ graft-id" >> .git / info / grafts
git filter-branch $ graft-id..HEAD
Para remover commits de autoria de "Darl McBribe" da história:
git filter-branch --commit-filter '
if ["$ GIT_AUTHOR_NAME" = "Darl McBribe"];
então
skip_commit "$ @";
outro
git commit-tree "$ @";
fi 'HEAD
A função skip_commit é definido da seguinte forma:
skip_commit ()
{
mudança;
enquanto [-n "$ 1"];
do
mudança;
mapa "$ 1";
mudança;
feito;
}
A mágica da mudança primeiro joga fora o id da árvore e depois os parâmetros -p. Observe que este
lida com as mesclagens corretamente! No caso de Darl cometer uma fusão entre P1 e P2, será
propagados corretamente e todos os filhos da mesclagem se tornarão confirmações de mesclagem com P1, P2 como
seus pais em vez do commit de mesclagem.
NOTA as mudanças introduzidas pelos commits, e que não são revertidas por subseqüentes
confirma, ainda estará no ramo reescrito. Se você quer jogar fora alterar juntos
com os commits, você deve usar o modo interativo de git rebase.
Você pode reescrever as mensagens de log de commits usando --msg-filter. Por exemplo, git svn-id
strings em um repositório criado por git svn pode ser removido desta forma:
git filter-branch --msg-filter '
sed -e "/ ^ git-svn-id: / d"
'
Se você precisar adicionar Reconhecido por linhas para, digamos, os últimos 10 commits (nenhum dos quais é uma fusão),
use este comando:
git filter-branch --msg-filter '
gato &&
echo "Reconhecido por: Pernalonga[email protegido]>"
'CABEÇA ~ 10 .. CABEÇA
A opção --env-filter pode ser usada para modificar o committer e / ou a identidade do autor. Para
exemplo, se você descobriu que seus commits têm a identidade errada devido a uma configuração incorreta
user.email, você pode fazer uma correção, antes de publicar o projeto, assim:
git filter-branch --env-filter '
se teste "$ GIT_AUTHOR_EMAIL" = "root @ localhost"
então
GIT_AUTHOR_EMAIL =[email protegido]
exportar GIT_AUTHOR_EMAIL
fi
se teste "$ GIT_COMMITTER_EMAIL" = "root @ localhost"
então
GIT_COMMITTER_EMAIL =[email protegido]
exportar GIT_COMMITTER_EMAIL
fi
' -- --tudo
Para restringir a reescrita a apenas parte do histórico, especifique um intervalo de revisão além de
o novo nome do ramo. O novo nome do branch apontará para a revisão mais importante que um git
lista de rev deste intervalo será impresso.
Considere esta história:
D - E - F - G - H
//
ABC
Para reescrever apenas confirma D, E, F, G, H, mas deixe A, B e C sozinhos, use:
git filter-branch ... C..H
Para reescrever os commits E, F, G, H, use um destes:
git filter-branch ... C..H --não D
git filter-branch ... D..H --não C
Para mover a árvore inteira para um subdiretório ou removê-la de lá:
git filtro-ramo --index-filtro \
'git ls-files -s | sed "s- \ t \" * - & newsubdir / - "|
GIT_INDEX_FILE = $ GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$ GIT_INDEX_FILE.new" "$ GIT_INDEX_FILE" 'CABEÇA
LISTA PARA ENCOLHENDO A REPOSITÓRIO
git-filter-branch pode ser usado para se livrar de um subconjunto de arquivos, geralmente com alguns
combinação de --index-filter e --subdirectory-filter. As pessoas esperam o resultado
repositório seja menor que o original, mas você precisa de mais alguns passos para realmente fazer
é menor, porque o Git se esforça ao máximo para não perder seus objetos até que você mande. Primeiro
certifique-se de que:
· Você realmente removeu todas as variantes de um nome de arquivo, se um blob foi movido durante sua vida útil.
git log --name-only --follow --all - filename pode ajudá-lo a encontrar renomeações.
· Você realmente filtrou todos os refs: use --tag-name-filter cat - --all ao chamar
git-filtro-branch.
Então, há duas maneiras de obter um repositório menor. Uma maneira mais segura é clonar, que mantém
seu original intacto.
· Clone-o com git clone file: /// path / to / repo. O clone não terá o
objetos. Ver clone do git(1). (Observe que a clonagem com um caminho simples apenas links físicos
tudo!)
Se você realmente não deseja cloná-lo, por qualquer motivo, verifique os seguintes pontos
em vez disso (nesta ordem). Esta é uma abordagem muito destrutiva, então fazer a backup ou volte
para cloná-lo. Você foi avisado.
· Remova os refs originais apoiados por git-filter-branch: diga git para cada-ref
--format = "% (refname)" refs / original / | xargs -n 1 git update-ref -d.
· Expira todos os reflogs com git reflog expire --expire = now --all.
· Coleta de lixo todos os objetos não referenciados com git gc --prune = now (ou se o seu git-gc for
não é novo o suficiente para suportar argumentos para --prune, use git repack -ad; git prune
em vez de).
NOTAS
git-filter-branch permite que você faça reescritas complexas em script de shell de seu histórico Git,
mas você provavelmente não precisa dessa flexibilidade se estiver simplesmente removendo não desejado dados, como
arquivos ou senhas grandes. Para essas operações, você pode querer considerar A BFG
Limpador de repositório[1], uma alternativa baseada em JVM para git-filter-branch, normalmente pelo menos 10-50x
mais rápido para esses casos de uso e com características bastante diferentes:
· Qualquer versão particular de um arquivo é limpa exatamente uma vez. O BFG, ao contrário
git-filter-branch, não dá a você a oportunidade de lidar com um arquivo de forma diferente
com base em onde ou quando foi cometido em sua história. Esta restrição dá o
benefício de desempenho principal do BFG, e é bem adequado para a tarefa de limpeza de
dados - você não se importa onde os dados ruins são, você só quer ido.
· Por padrão, o BFG aproveita ao máximo as máquinas multi-core, limpeza de commit
árvores de arquivos em paralelo. git-filter-branch limpa os commits sequencialmente (ou seja, em um
maneira de encadeamento único), embora is possível escrever filtros que incluem seus próprios
paralelismo, nos scripts executados em cada confirmação.
· O comando opções[2] são muito mais restritivos do que o branch git-filter, e dedicados
apenas para as tarefas de remoção de dados indesejados - por exemplo: --strip-blobs-maior-que 1M.
GIT
Parte da git(1) suíte
NOTAS
1. O BFG Repo-Cleaner
http://rtyley.github.io/bfg-repo-cleaner/
2. opções de comando
http://rtyley.github.io/bfg-repo-cleaner/#exemplos
Use git-filter-branch online usando serviços onworks.net