Git-annex

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen

git-annex verwaltet Dateien in einem git-Repository ohne deren Inhalte direkt ins git-Repo zu spielen. Dies erscheint auf den ersten Blick etwas paradox, vermeidet jedoch, dass git zu große Dateien im Repo verwalten muss. Dabei befinden sich nur die Dateinamen und zugehörige Metadaten direkt im git-Repo. Die Daten der Dateien selbst werden in einem separaten Ordner abgelegt und von git-annex verwaltet.

Git-annex bietet unterschiedliche Verwendungs-Szenarien und Sicherheits-Funktionen. Es kann sicherstellen, dass von einer Datei mehrere Kopien in den Repositories sein müssen. Dadurch kann eine Datei nicht mehr irrtümlich gelöscht werden, da git-annex die Anzahl der Kopien überprüft. Außerdem müssen nicht mehr alle Dateiinhalte auf jedem System vorhanden sein. Sie können bei Bedarf von anderen Systemen via git annex get geholt werden.

Installation

Die git-annex Installation unter Ubuntu kann entweder aus den Repos, oder manuell durchgeführt werden:

  1. Aus den Repos hinkt die git-annex Version den aktuellen Entwicklungsversionen hinterher:
  2. Manuell
    • git-annex wird auch als vorkompilierte Software zur Verfügung gestellt.[1] Die Binaries werden am Ziel-System ausgepackt und verwendet:
:~$ wget 'http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz'
:~$ tar xzf git-annex-standalone-amd64.tar.gz
:~$ PATH="$PATH:$HOME/downloads/git-annex.linux"
:~$ git-annex version
git-annex version: 4.20131003-gbe0b734
build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi TDFA
key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
remote types: git gcrypt S3 bup directory rsync web webdav glacier hook

Die Pfadänderung kann unter Ubuntu auch permanent gesetzt werden (s.a. Umgebungsvariablen unter Ubuntu permanent setzen). Dazu wird folgende Zeile in die Datei .pam_environment des Home-Verzeichnisses eingefügt:

PATH DEFAULT=${PATH}:${HOME}/Applications/git-annex.linux

Interne Strukturen

Git-annex verwaltet im sogenannten "Indirect Mode" die Dateinamen als symbolische Links auf deren eigentlichen Inhalt:[2]

:~/annex$ ls -la
[...]
debhelper-slides.pdf -> .git/annex/objects/32/64/SHA256E-s1988981--8aaa02dda217
bbabd79a11a5f93fdd4ca8ae4e723c86b4bb91c69d4095a84006.pdf/SHA256E-s1988981--8aaa
02dda217bbabd79a11a5f93fdd4ca8ae4e723c86b4bb91c69d4095a84006.pdf

Sind die Dateiinhalte zu einem Dateinamen vorhanden, ist ein gültiger symbolischer Link vorhanden. Ansonsten zeigt der Link ins Leere und der Dateiinhalt muss über git annex get zuerst von einem anderen Repository geholt werden.

Dateien im Indirect Mode modifizieren

Um eine Datei zu editieren, die sich im git-annex Repository befindet, muss die Datei zuvor entsperrt werden. Dieser Schritt soll vor allem vorm ungewollten Löschen einer Datei bewahren (git-annex prüft über numcopies, ob sich in anderen Repos Kopien der Datei befinden):

:~/annex$ git annex unlock debhelper-slides.pdf
unlock debhelper-slides.pdf (copying...) ok
:~/annex$ ls -la
[...]
-rw-r--r--  1 tktest tktest 1988981 Oct  9 12:30 debhelper-slides.pdf

Nach dem unlock kann die Datei bearbeitet werden. Ein darauf folgender Commit erzeugt über einen Post-Commit-Hook für git-annex wieder den symbolischen Link.

Direct Mode

Neben dem indirekten Modus bietet der direkte Modus den Komfort, die Dateien direkt zu bearbeitet. Die Sicherheitsfunktionen, die git-annex normalerweise bietet, fallen dann aber weg. Darum starten im Regelfall alle git-annex-Repositories im indirekten Modus. Eine Ausnahme bilden die Repositories, die über die Weboberfläche per git-annex assistant erzeugt wurden. Über indirect und direct Kommandos kann außerdem zwischen den beiden Modi gewechselt werden:

:~/annex$ git annex direct
commit  
# On branch master
nothing to commit (working directory clean)
ok
direct debhelper-slides.pdf ok
direct git-pkg-2011.pdf ok
direct  ok

Ein erstes Repository erstellen und verwalten

Alice und Bob synchronisieren über SSH ihre Repositories.

Im folgenden Beispiel tauschen Alice und Bob Daten direkt aus. Jeder der beiden besitzt ein git-annex Repository, in dem die Daten verwaltet werden. Da die beiden direkt über SSH miteinander kommunizieren, kann mit git-annex:

  • Alice auf ihrem System eine Datei zu git-annex hinzufügen und mit git annex sync die Metadaten aktualisieren.
  • Bob git annex sync aufrufen um ebenfalls zu synchronisieren. Er erhält dabei im ersten Schritt einen gebrochenen symbolischen Link auf die Datei.
  • Bob git annex get aufrufen und sich dadurch auch den Inhalt der Datei auf sein System holen.
  • Alice aktiv mit git annex copy Dateien zu Bob kopieren.
  • Bob Dateien, die von Alice in git-annex gekommen sind, mit git annex sync lokal übernehmen.
  • sicher gestellt werden, dass zumindest jede Datei immer ein Mal vorhanden ist. Solange der andere die Datei besitzt, kann einer der beiden die Datei droppen (die Daten fallen lassen, den Dateinamen bzw. Link behalten).

git-annex Repo Alice

Alice erstellt sich in ihrem Verzeichnis annex eine git-annex Repository:

:~/annex$ git init
Initialized empty Git repository in /home/alice/annex/.git/
:~/annex$ git annex init "Alice"
init Alice ok
(Recording state in git...)

Sie fügt die Daten hinzu, die sie mit git-annex verwalten will:

:~/annex$ cp ~/Downloads/debhelper-slides.pdf .
:~/annex$ git annex add .
add debhelper-slides.pdf (checksum...) ok
(Recording state in git...)
:~/annex$ git commit -a -m "Added slides"
[master (root-commit) 761a810] Added slides
 1 file changed, 1 insertion(+)
 create mode 120000 debhelper-slides.pdf

Um sich mit Bob zu synchronisieren, fügt Sie dessen git-annex Repository als eine entferntes Repository hinzu:[3]

:~/annex$ git remote add bob ssh://bob@192.168.56.104/home/bob/annex

git-annex Repo Bob

Bob klont sich das vorhandene Repo von Alice und initialisiert sein git-annex Repository mit seinem Namen:

:~/annex$ git clone ssh://alice@192.168.56.1/home/alice/annex .
Cloning into '.'...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 13 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (2/2), done.
:~/annex$ git annex init "Bob"
init Bob ok
(Recording state in git...)

Er fügt ebenfalls Alice als Remote hinzu:

:~/annex$ git remote add alice ssh://alice@192.168.56.1/home/alice/annex

Alice und Bob synchronisieren sich

Alice und Bob können auf ihrer Seite über

git annex sync

ihre Repos aktualisieren und Neuerungen zum Partner pushen:

:~/annex$ git annex sync bob
commit  
ok
pull bob 
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 0), reused 1 (delta 0)
Unpacking objects: 100% (5/5), done.
From ssh://192.168.56.104/home/bob/annex
 * [new branch]      git-annex  -> bob/git-annex
 * [new branch]      master     -> bob/master
ok
(merging bob/git-annex into git-annex...)
(Recording state in git...)
push bob 
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 435 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://bob@192.168.56.104/home/bob/annex
 * [new branch]      git-annex -> synced/git-annex
 * [new branch]      master -> synced/master
ok

Hat Alice neue Dateien hinzugefügt, erhält Bob im ersten Schritt nur einen gebrochenen symbolischen Link, ohne die eigentlichen Daten der Datei:

:~/annex$ git annex sync alice
(merging synced/git-annex origin/git-annex into git-annex...)
commit  
ok
pull alice 
From ssh://192.168.56.1/home/alice/annex
 * [new branch]      git-annex  -> alice/git-annex
 * [new branch]      master     -> alice/master
 * [new branch]      synced/master -> alice/synced/master
ok

Folgender find-Befehl listet gebrochene symbolische Links auf:

:~/annex$ find -L . -type l
./git-pkg-2011.pdf

Durch ein git annex get von Alice, kann er auch den Datei-Inhalt erhalten:

:~/annex$ git annex get .
get debhelper-slides.pdf (from alice...) 
SHA256E-s1988981--8aaa02dda217bbabd79a11a5f93fdd4ca8ae4e723c86b4bb91c69d4095a84006.pdf
     1988981 100%   24.63MB/s    0:00:00 (xfer#1, to-check=0/1)

sent 30 bytes  received 1989376 bytes  265254.13 bytes/sec
total size is 1988981  speedup is 1.00
ok
(Recording state in git...)

Alice kopiert Daten zu Bob

:~/annex$ cp ~/Downloads/git-pkg-2011.pdf .
:~/annex$ git annex add .
add git-pkg-2011.pdf (checksum...) ok
(Recording state in git...)
:~/annex$ git commit -a -m "Added tutorial"
[master 50c8091] Added tutorial
 1 file changed, 1 insertion(+)
 create mode 120000 git-pkg-2011.pdf
:~/annex$ git annex copy . --to bob
copy debhelper-slides.pdf (checking bob...) ok
copy git-pkg-2011.pdf (checking bob...) (to bob...) 
SHA256E-s359984--e87901d377b5c31377a87eb07a28cd133b07feed380f869867abb04bc85d3e47.pdf
      359984 100%   52.01MB/s    0:00:00 (xfer#1, to-check=0/1)

sent 360173 bytes  received 31 bytes  720408.00 bytes/sec
total size is 359984  speedup is 1.00
ok
(Recording state in git...)

Wenn Bob synchronisiert hat ist die Datei inkl. Inhalt bei ihm angelangt. Ohne git annex copy hätte Bob wieder nur einen gebrochenen symbolischen Link vorgefunden:

:~/annex$ git annex sync
commit  
ok
pull origin
:~/annex$ ls
debhelper-slides.pdf  git-pkg-2011.pdf

Da Alice die Datei kopiert, befindet sie sich nun bei Alice und Bob:

:~/annex$ git annex whereis .
whereis debhelper-slides.pdf (2 copies) 
  	de5e57a3-4517-4a05-84ee-60708bbd9d3b -- here (Bob)
   	e3d44122-8756-4f1c-aa5b-5ecdfe01bc4b -- origin (Alice)
ok
whereis git-pkg-2011.pdf (2 copies) 
  	de5e57a3-4517-4a05-84ee-60708bbd9d3b -- here (Bob)
   	e3d44122-8756-4f1c-aa5b-5ecdfe01bc4b -- origin (Alice)
ok

Einzelnachweise

  1. git-annex Installations-Pakete (git-annex.branchable.com)
  2. git annex direct mode (git-annex.branchable.com)
  3. git-remote Manual Page (kernel.org)


Foto Georg Schönberger.jpg

Autor: Georg Schönberger

Georg Schönberger, Abteilung DevOps bei der XORTEX eBusiness GmbH, absolvierte an der FH OÖ am Campus Hagenberg sein Studium zum Bachelor Computer- und Mediensicherheit, Studium Master Sichere Informationssysteme. Seit 2015 ist Georg bei XORTEX beschäftigt und arbeitet sehr lösungsorientiert und hat keine Angst vor schwierigen Aufgaben. Zu seinen Hobbys zählt neben Linux auch Tennis, Klettern und Reisen.


Das könnte Sie auch interessieren

Git Grundbefehle
Git Grundlagen
Git-annex Archiv mit git-annex assistant