Como faço para salvar arquivos alterados?

8

Eu tenho duas pastas:

  • ORIGINAL/
  • ORIGINAL_AND_MY_CHANGES /

Meu amigo tem uma cópia de ORIGINAL /. Gostaria de gerar MY_CHANGES.tgz - ele deve conter apenas arquivos novos / alterados de ORIGINAL_AND_MY_CHANGES / em comparação com ORIGINAL /. Assim, meu amigo pode descompactá-lo em sua cópia de ORIGINAL / e obter ORIGINAL_AND_MY_CHANGES /. Como posso fazer isso?

PS Eu tentei, diffmas ele não pode salvar dados binários e rsync --link-dest- gera links físicos que são inúteis no arquivo.

PPS No meu caso, o tempo de modificação não pode ser usado para decidir qual arquivo foi alterado.

Dmitry
fonte
1
Você olhou para o diretório "diff"? questão?
rozcietrzewiacz

Respostas:

7

Com rsync

O que você está fazendo é essencialmente um backup incremental: seu amigo (seu backup) já possui os arquivos originais e você deseja criar um arquivo que contenha os arquivos que você alterou desse original.

O Rsync possui recursos para backups incrementais.

cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
  • -a significa preservar todos os atributos (horários, propriedade etc.).
  • -c significa comparar o conteúdo do arquivo e não confiar na data e no tamanho.
  • --compare-dest=/some/directorysignifica que arquivos idênticos nesse diretório e na árvore de origem não são copiados. Observe que o caminho é relativo ao diretório de destino.

O Rsync copia todos os diretórios, mesmo que nenhum arquivo termine lá. Para se livrar desses diretórios vazios, execute find -depth CHANGES_ONLY -type d -empty -delete(ou se você findnão tiver -deletee -emptyexecute find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null).

Em seguida, faça o arquivo morto a partir do CHANGES_ONLYdiretório

O caminho para pedestres

Atravesse o diretório com seu arquivo. Ignore arquivos idênticos ao original. Crie diretórios no destino, conforme necessário. Copie os arquivos alterados.

cd ORIGINAL_AND_MY_CHANGES
find . \! -type d -exec sh -c '
  for x; do
    if cmp -s "$x" "../ORIGINAL/$x"; then continue; fi
    [ -d "../CHANGES_ONLY/$x" ] || mkdir -p "../CHANGES_ONLY/${%/*}"
    cp -p "$x" "../CHANGES_ONLY/$x"
  done
' {} +
Gilles 'SO- parar de ser mau'
fonte
É ainda melhor solução do que do enzotib porque eu posso colocar MY_CHANGES no controle de origem e atualização / rastrear essas mudanças (se o arquivo de lote I atualização do rsync sob controle de origem que vai ser impossível ver quais arquivos foram alterados)
Dmitry
@Dmitry Se você estiver usando o controle de origem, por que não colocar import / track ORIGINALe criar ORIGINAL_AND_MY_CHANGESuma filial? Em seguida, descubra CHANGEScom um comando scm.
Gilles 'SO- stop be evil' (
No meu caso ORIGINAL, são fontes da plataforma Android (3GB, arquivos 126000). Até a execução do rsync leva de 15 a 20 minutos. Eu acho que a adição de todas essas coisas sob controle de origem levará muito espaço e tempo.
Dmitry
@ Dmitry Isso resolve então. Se for fontes do Android, use repo e git. Trabalhe em seu próprio ramo. Já é difícil gerenciar aqueles com controle de versão, estremeço ao pensar como pode ser sem ele. Felizmente, o git é muito bom em gerenciar filiais locais.
Gilles 'SO- stop be evil' (
Infelizmente, é uma fonte Android personalizada, sem repositórios repo / git.
Dmitry
5

O comando

rsync --only-write-batch=FILE $other_options ORIGINAL_AND_MY_CHANGES/ ORIGINAL/

produziria um arquivo de lote contendo as alterações necessárias (sem modificar nada).

O patch pode ser aplicado em outro site, onde você pega o lote FILE, com

rsync --read-batch=FILE ORIGINAL/
enzotib
fonte