[expandido do meu comentário para o OP]. Crie no repositório um diretório flat
que contém uma cópia de todos os arquivos, mas em uma lista simples. As cópias seriam hard links, por isso não ocupe espaço. Faça o mesmo na máquina local. Você pode, então, rsync do diretório flat local para o diretório flat remoto. Isso atualizará todos os arquivos remotos, já que o rsync preservará links físicos remotos se você usar --inplace
. Os diretórios planos podem ser criados pelo script antes do rsync e removidos depois.
Aqui está uma prova de script de teste de conceito:
#!/bin/bash
dosync(){ # function to create flat trees and rsync them
mkdir flat
mkdir flatl
find repo -type f -exec ln {} flat \;
find local -type f -exec ln {} flatl \;
rsync -aHv --inplace flatl/ flat
rm -fr flat flatl
}
# create repo and local dirs with same content. 3 empty files
cd /tmp || exit
mkdir repo
( cd repo; touch a b c )
mkdir local
rsync -a repo/ local
dosync
echo hi >local/a # example change of local file a
dosync
mkdir repo/new # example move of repo file b
mv repo/b repo/new/
echo hello >local/b # change local file b
dosync
ls -lR repo local
# rm -fr flat flatl repo local
Para a direção inversa, após o dosync ter transferido seus modifs locais para o repositório, você pode apenas rm -fr local
e "rsync -a repo / local" para copiar o repositório completo para o sistema de arquivos local. Em vez disso, você pode reduzir o número de arquivos que precisam ser transferidos para apenas os novos no repositório usando uma técnica semelhante:
reversesync(){
mkdir flat
mkdir flatl
find repo -type f -exec ln {} flat \;
find local -type f -exec ln {} flatl \;
mv flat repo/flat
mv flatl local/flat # not flatl!
rsync -aHv --delete repo/ local
rm -fr repo/flat local/flat
}
Isso move as árvores planas para o repositório e dirs locais, respectivamente, para que o rsync possa ver os arquivos com link físico e evitar copiá-los. (Obviamente, os diretórios planos devem ter o mesmo nome desta vez).
Se você tem apenas um único arquivo conhecido que você alterou, você pode usar find
no repositório para obter sua nova posição na árvore e rsync o arquivo para lá. Por exemplo:
file=mychangedfile.abc
to=$(find repo -name "$file")
from=$(find local -name "$file")
rsync -av "$from" "$to"
Isso pressupõe que o repositório esteja montado, caso contrário, você pode usar ssh repo find...
.
Se você não pode usar o ssh no repositório, você pode usar o rsync para um destino local fictício para obter a lista de arquivos e extrair aquele que você deseja:
to=$(rsync -a --list-only repo dummy | awk '/\/'"$file"'$/{print $NF}')