Альтернатива с использованием git-annex
:
Сначала мы настроим тестовые файлы:
#!/bin/bash
# faster than /dev/urandom
randfile='openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt < /dev/zero'
dd='dd bs=1M count=5 iflag=fullblock'
for I in 1 2
do
mkdir root$I
cd root$I
for J in 1 2
do
mkdir dir$J
if [ -e dir2 ]
then
cd dir2
eval $randfile | eval $dd of=file1
eval $randfile | eval $dd of=file2
if [ `pwd | grep root1` ]; then
eval $randfile | eval $dd of=file3
elif [ `pwd | grep root2` ]; then
eval $randfile | eval $dd of=file4
fi
cd ..
fi
done
cd ..
done
Это создает каталоги с двоичными файлами, содержащими случайные данные. На данный момент файлы:
user@host$ find root? -path '*/.git*' -prune -o -print | sort -n
root1
root1/dir1
root1/dir2
root1/dir2/file1
root1/dir2/file2
root1/dir2/file3
root2
root2/dir1
root2/dir2
root2/dir2/file1
root2/dir2/file2
root2/dir2/file4
Теперь мы инициализируем репозитории и выполняем синхронизацию:
cd root1
git init
git annex init 'root1'
git remote add root2 ../root2
#git annex direct
git annex add .
git commit -a -m 'Files added.'
cd ..
cd root2
git init
git annex init 'root1'
git remote add root1 ../root1
#git annex direct
git annex add .
git commit -a -m 'Files added.'
cd ..
mkdir unioned
cd unioned
git init
git annex init 'unioned'
git remote add root1 ../root1
git remote add root2 ../root2
git annex add .
git commit -a -m 'Files added.'
git annex sync
cd ..
На данный момент, содержимое unioned/
являются:
user@host$ find root? unioned -path '*/.git*' -prune -o -print | sort -n
root1
root1/dir1
root1/dir2
root1/dir2/file1
root1/dir2/file2
root1/dir2/file3
root2
root2/dir1
root2/dir2
root2/dir2/file1
root2/dir2/file2
root2/dir2/file4
unioned
unioned/dir2
unioned/dir2/file1
unioned/dir2/file1.variant-065a
unioned/dir2/file1.variant-a33e
unioned/dir2/file2
unioned/dir2/file2.variant-08f3
unioned/dir2/file2.variant-75c4
unioned/dir2/file3
unioned/dir2/file4
Где *.variant-*
ссылка на разные файлы в разных репозиториях. Кроме того, unioned
прежнему не содержит данных, пока мы не проведем git annex get
. На данный момент, git annex list
показывает, где файлы находятся и / или получены из:
user@host$ cd unioned; git annex list
here
|root1
||root2
|||web
||||
__X_ dir2/file1.variant-065a
_X__ dir2/file1.variant-a33e
__X_ dir2/file2.variant-08f3
_X__ dir2/file2.variant-75c4
_X__ dir2/file3
__X_ dir2/file4
Альтернативой в более длинной форме является git annex whereis
. Наконец, чтобы разрешить конфликты и распространить слияние изнутри unioned/dir2
:
cd unioned/dir2
git annex get # retrieve the actual content
git annex unlock # unlock the files - replace the symlinks with the actual repofiles
rm file1
git mv file1.variant-065a file1
git rm -f file1.variant-a33e
rm file2
git mv file2.variant-75c4 file2
git rm -f file2.variant-08f3
git annex add . # "commits" the changes, converts files back into symlinks
git annex sync # propagates the changes back to the other repos
Который дает:
git annex sync
commit ok
pull root2
ok
pull root1
ok
push root2
Counting objects: 61, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (26/26), done.
Writing objects: 100% (37/37), 2.67 KiB | 0 bytes/s, done.
Total 37 (delta 14), reused 0 (delta 0)
To ../root2
e5df80f..720b34b git-annex -> synced/git-annex
b055385..ad8c5c2 master -> synced/master
ok
push root1
Counting objects: 61, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (26/26), done.
Writing objects: 100% (37/37), 2.67 KiB | 0 bytes/s, done.
Total 37 (delta 14), reused 0 (delta 0)
To ../root1
e5df80f..720b34b git-annex -> synced/git-annex
b055385..ad8c5c2 master -> synced/master
ok
Наконец, git annex list
показывает, где эти файлы находятся после синхронизации: в unioned/
есть копии всех файлов, выбранных на разных серверах, как указано выше.
git-annex
также имеет прямой режим, который работает непосредственно с файловой системой без использования символических ссылок.
Настройка этого для использования на удаленных компьютерах - это вопрос настройки удаленных устройств через ssh с использованием стандартного git, однако его поведение описано здесь: http://git-annex.branchable.com/walkthrough/using_ssh_remotes/
Общее описание приложения git находится здесь: http://git-annex.branchable.com/walkthrough/