Comando Git para remover várias linhas removidas dos commits que originalmente as adicionaram

3

Depois de remover várias linhas de um arquivo com versão git, em vez de fazer um novo commit que remova essas linhas, existe um comando git que apenas retire essas linhas das submissões que originalmente as introduziram? Por exemplo, dado este arquivo:

$ echo "Line 1" >> foo
$ echo "Line 2" >> foo
$ git commit -a -m "Add 1, 2"
[master 1005cbb] Add 1, 2
 1 file changed, 2 insertions(+)

$ echo "Line 3" >> foo
$ git commit -a -m "Add 3"
[master 5036981] Add 3
 1 file changed, 1 insertion(+)

$ echo "Line 4" >> foo
$ echo "Line 5" >> foo
$ git commit -a -m "Add 5, 6"
[master 41ca6ab] Add 5, 6
 1 file changed, 2 insertions(+)

$ git blame -s foo
1005cbbb 1) Line 1
1005cbbb 2) Line 2
50369811 3) Line 3
41ca6ab6 4) Line 4
41ca6ab6 5) Line 5

Digamos que eu remova as linhas 2-4:

$ sed -i '/Line [234]/d' foo
$ git diff
diff --git a/foo b/foo
index 572d5d9..e486b1b 100644
--- a/foo
+++ b/foo
@@ -1,5 +1,2 @@
 Line 1
-Line 2
-Line 3
-Line 4
 Line 5

Agora, em vez de confirmar essa alteração, quero executar algo que apenas remova essas linhas do histórico, resultando em uma nova árvore na qual 1005cbb (ou qualquer que seja o novo hash) adiciona apenas "Linha 1", 5036981 está vazio (ou desaparecido) e 41ca6ab adiciona "Linha 5".

Isso é possível? A coisa mais próxima que consigo pensar é remover cada linha separadamente e git commit --fixup hash-of-the-commit-that-added-that-line antes de rebasing, mas estou curioso para saber se há um método integrado melhor antes de tentar automatizar a execução dessa maneira.

    
por Michael Mrozek 28.12.2016 / 07:26

1 resposta

2

Isso é o que git filter-branch é para. Ele executa um comando em todas as revisões do histórico e reafirma o resultado, alterado ou não. Ele alterará todos os hashes de cada commit após a primeira revisão modificada, tornando o novo branch incompatível com qualquer clone.

Se sed -i '/Line [234]/d' foo for o comando que faz a modificação desejada, você poderá aplicá-lo como um filtro de árvore:

git filter-branch --tree-filter "sed -i '/Line [234]/d' foo" HEAD

Geralmente é mais fácil colocar qualquer coisa complicada em seu próprio script. O comando de filtragem é executado a partir de outro diretório, portanto, forneça o caminho completo.

Existem muitos modos de filtragem. Os filtros de árvore modificam os próprios arquivos e podem ser combinados com outros filtros para alterar mensagens ou detalhes de confirmação, pais, tags e assim por diante. Os filtros de árvore se comportam como se você executasse git add -f * em um novo repositório - todos os arquivos existentes são adicionados ao seu conteúdo atual, desconsiderando qualquer ignorar local ou global , e qualquer arquivo que não exista mais é removido. / p>     

por 28.12.2016 / 07:49