Compartilhando uma árvore de projetos entre ambientes

1

Para economizar espaço e tempo, copiei uma árvore de grande projeto em uma unidade de rede como links físicos, ou seja,

cp -a -r --link proj proj_B

(background: é enorme, precisa ser reconstruído a partir de dois ambientes incompatíveis e não tem um bom suporte para especificar locais intermediários e de produtos. Por isso, foi um truque rápido para obter uma reconstrução no ambiente "B": depois de copiar limpar e reconstruir a partir de "proj_B / obj". Ambos os ambientes estão sob LinuxMint 16)

O problema com essa abordagem é que as edições não serão (confiavelmente) compartilhadas entre essas árvores, por exemplo, salvar uma edição em "proj / foo.cpp" deixará apontando para um novo inode e "proj_B / foo.cpp" ainda apontará para o antigo (talvez do padrão de perda-evitação de "save temp; mv orig temp2 ; mv temp orig; rm temp2 ").

Para fonte de compartilhamento, eu acho que preciso de links simbólicos para os diretórios de origem (mas não simplesmente um link simbólico da raiz do projeto, já que os diretórios binários precisam ser mantidos separados), por exemplo. algo como:

cp -a -r --symbolic-link proj proj_B

seguido por desvincular os diretórios binários (exceto que a cópia recursiva de links simbólicos falha com "pode fazer links simbólicos relativos apenas no diretório atual". Mas algo semelhante poderia ser feito com "find -exec", ou apenas capitulando e escrevendo um script)

Mas antes disso eu queria uma verificação de sanidade: existe uma ferramenta melhor para isso desde o começo (por exemplo, uma combinação de sinalizadores de rsync)? Ou essa abordagem de compartilhamento está fadada a terminar em lágrimas e a perder dados, e eu devo me resignar a usar duas cópias (e muitas maldições quando descobri que esqueci de fazer as alterações mais recentes entre elas)?

    
por Tom Goodfellow 28.05.2014 / 10:50

3 respostas

1

Eu não usaria links físicos. Alguns editores quebram hard links quando salvam arquivos, outros não, e alguns podem ser configurados. No entanto, a preservação de links físicos ao salvar um arquivo implica que o arquivo está gravado no lugar, o que significa que, se o sistema travar durante a gravação, você ficará com um arquivo incompleto. É por isso que o save-to-new-file-and-move-in-place é preferível - mas isso quebra os hard links.

Em particular, a maioria dos softwares de controle de versão interrompe os links físicos. Tão hard links estão fora.

Uma floresta de links simbólicos não tem esse problema. Você precisa garantir que aponta seu editor para a cópia principal ou que o editor segue links simbólicos.

Você pode criar a floresta de links simbólicos com cp -as . No entanto, se você criar novos arquivos, cp -as será inconveniente para criar os links simbólicos correspondentes (ele fará o trabalho, mas o afogará em reclamações de que o destino já existe). Você pode usar um loop de shell simples.

for env in environement1 environment2 environment3; do
  cd "../$env"
  find ../src \
       -type d -exec mkdir {} + \
       -o -exec sh -c 'ln -s "$@" .' _ {} +
done
    
por 29.05.2014 / 04:55
0

The problem with this approach is that edits won't be (reliably) shared between these trees, e.g. saving an edit to "proj/foo.cpp" will leave it pointing to a new inode and "proj_B/foo.cpp" will still point to the old one.

Isso está incorreto. Se você tiver dois arquivos vinculados, eles sempre terão o mesmo conteúdo. As edições não devem mudar isso.

Se você precisar editar arquivos, parece que você precisa de algo como armazenamento central para seus dois diretórios. Pode ser melhor seria colocar seu projeto sob controle de versão (como o git)?

    
por 28.05.2014 / 11:45
0

Uma forma convertida da resposta do @Gilles, permitindo uma sintaxe mais semelhante ao do CP (meu script do Bash é ridiculamente elementar, então não consegui descobrir como empacotar a substituição do caminho em "-exec {}")

#/usr/bin/bash
if [ $# -ne 2 ] ; then  echo "Args: <original tree> <new tree of symlinks>" ; exit 1; fi
mkdir -p "$2"
srclen=${#1}
find "$1" | while read line
do
    sub=${line:$srclen}
    if [ -d "$line" ]
    then
        mkdir "$2$sub"
    else
        ln -s "$1$sub" "$2$sub"
    fi
done
    
por 02.06.2014 / 16:07