Accéder à Git en Ruby peut-être utile au sein d’une application Rails. Rugged est une gem permettant l’accès à Git via libgit2. Nous allons explorer quelques unes de ses possibilités.
Libgit2 est une implémentation en C de Git. Cette librairie permet d’accéder à toutes les fonctions de Git grâce à son API.
Rugged permet de rendre toutes les fonctions de libgit2 accessibles directement en Ruby.
Chez Synbioz Rugged
est utilisé au sein de PBTD. Nous l’utilisons au sein de l’application pour cloner, et mettre à jour les dépôts Git ajoutés à PBTD.
Nous avons également mis en place au sein de PBTD une librairie permettant d’accéder plus facilement à nos dépôts Git en utilisant toujours Rugged
.
Certaines librairies sont nécessaires au bon fonctionnement de Rugged
:
Installons les :
(Mac OSX)
$ brew install cmake
$ brew install pkg-config
(Debian)
$ sudo apt-get install ruby-dev
$ sudo apt-get install cmake
$ sudo apt-get install pkg-config
Pour pouvoir récupérer des dépôts Git distants nous devons avoir ces librairies d’installées :
$ brew install openssl
$ brew install libssh2
$ sudo apt-get install openssl
$ sudo apt-get install libssh2-1
$ sudo apt-get install libssh2-1-dev
Rugged
Une fois toutes les dépendances installées nous allons pouvoir passer à l’installation de la gem en elle-même. Lors de l’installation de la gem, une version packagée de libgit2 fournie dans la gem sera elle aussi installée.
$ gem install rugged
Lors de l’utilisation de cette gem, si le message d’erreur suivant apparait:
Rugged::NetworkError: This transport isn't implemented. Sorry.
Il vous manque certainement une des librairies listées dans la partie Pré-requis.
Avant de nous lancer dans son utilisation, nous allons configurer Rugged
en y ajoutant l’accès à notre identité SSH.
Vérifiez que vous posséder un jeu de clés SSH valide et autorisé sur vos dépôt Git distants.
Si vous ne disposez pas de clés SSH voici comment en créer : Création clé SSH.
Il faut tout d’abord ajouter votre identité ssh à l’agent ssh actuel :
$ ssh-add
credentials = Rugged::Credentials::SshKeyFromAgent.new(username: 'git')
username
représente l’utilisateur ssh auquel nous allons nous connecter, prenons le cas de l’un de nos dépôts:
git@github.com:synbioz/pbtd.git
L’utilisateur se trouve avant le @
sur les adresses ssh, sur Github l’utilisateur est git
.
Nous donnons directement à Rugged
le chemin vers notre jeu de clés SSH.
credentials = Rugged::Credentials::SshKey.new(username: 'git', publickey: "/home/synbioz/.ssh/key.pub", privatekey: "/home/synbioz/.ssh/key")
repository_url = "git@github.com:synbioz/pbtd.git"
path = "pbtd"
@repository = Rugged::Repository.clone_at(repository_url, path, credentials: credentials)
repository_url
contient l’url du dépôt distant
path
est le chemin où le dépôt va être cloné
credentials
sont les accès ssh que nous avons définis précédemment.
Prenons le cas de l’ajout d’un fichier sur notre projet :
# 'DOCUMENTATION.md' est un fichier non versionné
# Nous voulons l'ajouter au dépôt
oid = Rugged::Blob.from_workdir @repository, "DOCUMENTATION.md"
index = @repository.index
index.read_tree(@repository.head.target.tree)
index.add(path: "DOCUMENTATION.md", oid: oid, mode: 33188)
# Auteur du commit
author = { email: "tdelaune@synbioz.com", name: "tdelaune@synbioz.com", time: Time.now }
# Ce commit aura un seul parent, le précédent commit
parents = [@repository.head.target.oid]
# ajout de notre fichier à l'arborescence git
tree = index.write_tree(@repository)
Rugged::Commit.create(@repository,
:author => author,
:message => "Ajout de DOCUMENTATION.md",
:committer => author,
:parents => parents,
:tree => tree,
:update_ref => "HEAD")
Pour ce faire nous devons récupérer le HEAD de notre dépôt local.
reference = @repository.head
remote = @repository.remotes['origin']
@repository.push(remote, [reference.name], {credentials: credentials})
Nous avons envoyé sur notre dépôt distant le HEAD de notre dépôt local, n’oubliez pas d’utiliser vos accès SSH.
remote = @repository.remotes['origin']
remote.fetch(credentials: credentials)
Pour ce faire nous allons avoir besoin d’accéder à l’adresse distante du dépôt qui est généralement origin
.
Il nous faut préciser à Rugged
les informations SSH pour accéder au dépôt distant.
@repository.checkout('my-branch')
Nous venons de passer sur la branche my-branch
si elle existe.
Nous voulons merger my-branch
dans develop
.
@repository.checkout("develop")
other_branch_commit = @repository.branches["my-branch"].target
@repository.references.update(@repository.head, other_branch_commit.oid)
La commande git pull
se décompose comme suit:
git fetch
git merge FETCH_HEAD
Il nous faut donc fetch et merge depuis notre dépôt distant :
@repository.checkout("develop")
# fetch
remote = @repository.remotes['origin']
remote.fetch(credentials: credentials)
# merge
distant_commit = @repository.branches["origin/develop"].target
@repository.references.update(@repository.head, distant_commit.oid)
Successeur de grit, Rugged
se révèle indispensable pour utiliser Git simplement en Ruby. Mais la gem manque encore cruellement de documentation.
L’équipe Synbioz. Libres d’être ensemble.