Salut ! Je sors de deux jours de hackathon pendant lequel j’ai rapidement passé sur le côté multilingue de l’appli pour me concentrer sur d’autres fonctionnalités.
Du coup, j’ai cherché, j’ai trouvé, je partage 😉 .

Configuration

Tu vas d’abord modifier ton fichier app/config/config.yml :

parameters:
    locale: en
    app.locales: en|fr

framework:
    translator: { fallbacks: ["%locale%"] }
    default_locale:  "%locale%"

A quoi servent ces modifications ?

  • locale est déjà utilisée avec translator et default_locale. Elle définit la langue de ton appli.
  • app.locales va nous servir à définir les langues de notre application, on y reviendra lorsqu’on créera une route.
  • translator active le service de traduction de Symfony, fallbacks indique quelle langue utiliser s’il ne trouve pas de fichier de traduction. Ici, il va chercher notre parametre locale (définie précédemment), soit, « en » (english)
  • default_locale définit une langue par défaut, s’il ne trouve pas la langue de l’utilisateur.

Les routes

C’est dans une url qu’on va définir la langue utilisée dans la page. Tu vas donc aller modifier les routes, par exemple dans src/Bundle/config/routing.yml :

nom_de_la_route:
  path: /{_locale}
  defaults: { _controller: Bundle:Controller:action } //ça doit avoir la forme BlogBundle:Post:index
  requirements:
    _locale: %app.locales% 

On a donc passé en paramètre dans l’url la variable _locale, et dans requirements, on limite les valeurs que peut prendre _locale à ce qu’on a définit précédemment avec nos parameters dans le fichier app/config/config.yml.

Création des fichiers de traduction

Lorsque translator, le service que l’on a activé tout à l’heure, est appelé, il prend la chaîne de caractères à traduire et cherche dans des fichiers précis la traduction.
Ces fichiers sont nommés messages.langue.extension, par exemple, pour la traduction française : messages.fr.xlf.
Il faut savoir que par défaut, 3 extensions sont possibles :

  • xlf (celle qui est fortement recommandée par Symfony, et que nous allons utiliser
  • yml
  • php

Pour notre exemple, nous allons donc créer le fichier de traduction française, app/Resources/translations/messages.fr.xlf :

<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="bundle_controller_action_place_id">
                <source>Hello</source>
                <target>Bonjour</target>
            </trans-unit>
        </body>
    <file>
<xliff>

La partie en bleue sera celle qui sera répétée pour chaque chaîne de caractères à traduire.
Analysons la :

  • trans-unit est donc ce qui définit un bloc de traduction, l’id qu’on lui donne doit permettre au traducteur d’avoir un contexte.
    J’ai choisi cette convention avec le nom du bundle, le controller, l’action, la place de la chaine de caractère (nav, footer, etc…), et une identification propre.
    Par exemple :
    id="blog_post_index_nav_title"
  • source est la chaîne de caractère à traduire
  • target est la traduction

A noter que le fichier peut se trouver dans 3 emplacements, et que le translator les parcours dans cet ordre :

  • app/Resources/translations
  • app/Resources/bundle/translations
  • src/Bundle/Resources/translations

Il est donc possible d’override la traduction d’un bundle à partir des deux autres emplacements.

Traduire un template

Tu vas maintenant aller dans ton template de base app/Resources/views/base.html.twig pour déclarer les chaînes de caractères à traduire :

<h1>{% trans %}My page's title{% endtrans %}</h1>

Tu déclares dans ton fichier .xlf les source et target, respectivement « My page’s title » et « Titre de ma page ».

Une dernière chose, à chaque fois que tu créé un fichier de traduction, tu dois faire un :

php app/console cache:clear

Et voilà ! Tu as maintenant une traduction fonctionnelle !
Si tu te rends sur /en, tu auras un titre « My page’s title » et sur /fr, tu auras « Titre de ma page » !

Bonus : Créer plusieurs fichiers de traduction

Actuellement, toute ta traduction se trouverait dans messages.fr.xlf. Sur un gros site, ça peut poser problème, tu t’en doutes…

Voici donc comment faire pour avoir d’autres fichiers de traduction, et ainsi pouvoir découper en fonction de l’application :

1 . Contrôleur

Dans l’action de ton contrôleur src/Bundle/Controller/ExempleController.php :

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Translation\Loader\XliffFileLoader;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
class ExempleController extends Controller
{
    public function testAction(){
        $translator = new Translator('fr', new MessageSelector()); //création d'un nouvel objet Translator
        $translator->addLoader('xlf', new XliffFileLoader()); //utilisation du loader pour lire les fichiers xlf
        $translator->addResource('xlf', 'nav.fr.xlf', 'fr', 'nav'); //déclaration du fichier de traduction avec pour paramètres l'extension, le nom du fichier, la langue, et le domaine
        $return $this->render('Bundle:Exemple:index.html.twig');
    }
}

2 . Vue

Et dans ta vue src/Bundle/Resources/views/index.html.twig :

{% trans from 'nav'%}chaîne de caractère à traduire{% endtrans %}

Enfin, n’oublie pas de créer ton fichier src/Bundle/Resources/translations/nav.fr.xlf !

Quelques ressources pour aller plus loin

symfony_sonata05-300x230

Salut à toi ! Oui, changement de format, aujourd’hui, je te tutoies ! J’ai rencontré plein de personnes du web cette semaine, et on se tutoie très souvent, alors, pourquoi pas ici ?

Aujourd’hui, je vais te parler d’un sujet un peu épineux :
Comment intégrer un backoffice avec Sonata à ton projet Symfony2 ?

Si tu ne t’es pas encore plongé dans la doc, à essayer encore et encore d’intégrer Sonata par toi-même, je te conseille d’y aller tout de suite, c’est par ici !

Si tu es encore là, c’est que justement, la doc, tu y es allé, mais ça ne fonctionne toujours pas.
Je vais donc te faire une petite intro, en reprenant ce que j’ai tiré de la doc (en effet, j’ai rien inventé) !

Prérequis

Une fois n’est pas coutume, pour l’article d’aujourd’hui, il y a des pré-requis !
En effet, on ne va pas démarrer un projet Symfony2 « from scratch », et je vais donc considérer que :

  • Tu sais démarrer un projet Symfony2
  • Tu es en version lts (actuellement, c’est la 2.8)
  • Tu as généré ton propre bundle avec une config en yml
  • Tu as généré au moins 2 entités
  • Tu as généré un « Crud » en read-only, c’est à dire sans les fonctions d’écritures

Si tu n’as pas ces pré-requis, fonce sur la doc officielle de Symfony2, et fais au moins le « Getting Started » ici !

Télécharger et déclarer Sonata

Tu vas donc commencer par deux commandes console:

composer require sonata-project/admin-bundle

puis, selon ton moyen de stockage, le bundle de sonata qui va se charger de travailler avec la base de données.
Ici, je vais supposer que tu travailles avec DoctrineORM :

composer require sonata-project/doctrine-orm-admin-bundle

Tu vas ensuite déclarer tous les bundles dont nous aurons besoin dans app/AppKernel.php, en ajoutant juste après la déclaration de ton bundle :

new Sonata\CoreBundle\SonataCoreBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
new Sonata\AdminBundle\SonataAdminBundle(),

Configurer Sonata pour pouvoir afficher le backoffice

Maintenant, tu vas te rendre dans app/config/config.yml, et décommenter :

framework:
    translator: { fallbacks: ["%locale%"] }

Sonata a besoin du translator pour afficher des mots à la place de variables dans notre futur back-office.

Ensuite, toujours dans app/config/config.yml, tu vas ajouter :

sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts:   [admin]

Puis, tu retournes dans la console, installer les assets de tes bundles et vider le cache (toujours une bonne idée après l’installation d’un bundle) :

php app/console assets:install
php app/console cache:clear

Enfin, tu vas définir les routes, dans app/config/routing.yml et tu ajoutes :

admin:
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
    prefix: /admin

_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin

Et voilà ! Tu peux maintenant accéder à ton backoffice via :

ton_adresse_locale/admin/dashboard

Ok, il est vide, mais il est là !

Générer les fonctions d’écriture du CRUD

On va remplir un peu le backoffice !
J’ai créé un bundle nommé BlogBundle et deux entités : Article et Category.
Pense à adapter ton code en fonction de tes entités!

Tu vas donc créer un dossier Admin dans ton bundle, puis un fichier ArticleAdmin.php :

#src/BlogBundle/Admin/ArticleAdmin.php

namespace BlogBundle\Admin;


use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;

class ArticleAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        //ici tu ajoutes TOUTES les propriétés qui existent dans ton entité, on a donc au minimum : add("propriété")
        $formMapper
            ->add('title', 'text', array(
                'label' => 'Titre de l\'article'
            ))
            ->add('description', 'text', array(
                'label' => 'Contenu de l\'article'
            ))            
        ;
    }

    // La liste des champs à partir desquels on pourra filtrer
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('title')
            ->add('description')
        ;
    }

    // Les champs que l'on veut voir dans la liste
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('title')
            ->add('description')
        ;
    }

}

Ensuite, tu vas créer le fichier BlogBundle/Resources/config/admin.yml :

services:
    app.admin.post:
        class: BlogBundle\Admin\ArticleAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: "Blog", label: "Article" }
        arguments:
            - ~
            - BlogBundle\Entity\Article
            - ~

Puis tu vas faire en sorte que ton bundle charge ce fichier admin.yml, en créant BlogBundle/DependencyInjection/AppExtension.php :

namespace BlogBundle\DependencyInjection;


use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class AppExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));        
        $loader->load('admin.yml');
    }
}

Enfin, tu vas ajouter ce fichier dans app/config/config.yml :

- { resource: "@BlogBundle/Resources/config/admin.yml" }

Et voilà ! Tu peux maintenant t’amuser à ajouter de nouveaux articles, les modifier, les supprimer !

Petit bonus

Tu peux modifier le titre du dashboard en ajoutant à app/config/config.yml :

sonata_admin:
    title:      MonBlog

ember

Dans cet article, je vais créer une application très simple avec Ember JS.
Le but est de tester rapidement le fonctionnement d’Ember, ou tout du moins, sa mise en place.

Installation

Pour commencer, vous devez vous assurer de la présence de Node.js et npm sur votre machine :
node -v
npm -v
Si vous n’avez pas l’un ou l’autre, je vous invite à vous rendre ici pour remédier à cela. C’est un guide pour MAC et Linux.

Ensuite, vous pouvez installer Ember avec la commande :
npm install -g ember-cli@2.8

On va maintenant créer une application :
ember new nom_de_l'application

Et voilà !

Tester l’application

On va maintenant lancer le serveur propre à Ember.
On se place d’abord dans le répertoire de l’application :
cd nom_de_l'application
puis :
ember server

A ce stade, il faut quelques secondes pour lancer le serveur (pour info, il m’a fallu 33s).
Une fois que c’est terminé, vous devez avoir un ligne avec :

Serving on http://localhost:4200/

Vous allez donc vous rendre sur cette adresse dans votre navigateur favori, et vous devriez avoir une page qui vous confirme la construction de l’application !

Créer notre premier contenu

On va commencer par générer notre premier template :
ember generate template application

Maintenant, si vous retournez sur votre navigateur, la page est devenue blanche.
On vient en effet de générer un nouveau template, et il est vide !
Ouvrez-le, il se trouve dans app/templates/application.hbs puis, à l’intérieur, insérer du contenu, par exemple :

<h1>Mes langages de programmation</h1>
{{outlet}}

Définir une route

On va créer une page qui va nous permettre de visualiser une liste de différents langages web.
Dans la console, on va utiliser :
ember generate route languages
On va ensuite modifier le fichier app/templates/languages.hbs:

{{outlet}}
<h2>Liste</h2>

Maintenant, rendez vous sur :

http://localhost:4200/languages

Votre h2 est apparu en dessous du h1 !
En effet, vous l’aurez deviné, {{outlet}} a permis à languages.hbs d’hériter de application.hbs .

Allons plus loin, ajoutons des données à notre liste !

On va modifier le fichier app/routes/languages.js :

import Ember from 'ember';

export default Ember.Route.extend({
	model(){
		return ['HTML 5', 'CSS 3', 'PHP', 'Javascript'];
	}
});

On a ajouté un « model » dans lequel on renvoie un tableau composé de nos langages.

Maintenant, modifions notre languages.hbs :

{{outlet}}
<h2>Liste</h2>
<ul>
    {{#each model as |language|}}
        <li>{{language}}</li>
    {{/each}}
</ul>

Et voilà ! Vous avez inséré des données dans une application EmberJS !

git-logo-svg_

Coder, versionner, créer des branches, c’est bien. Mais à plusieurs, c’est encore mieux ! Nous allons voir comment travailler en groupe sereinement avec GitHub, sans mettre en danger la partie commune.

Débuter un projet

Pour débuter un projet, un membre du groupe va créer localement les fichiers initiaux et le repository (avec git init).
Deux branches vont aussi être créées :

  • la branche principale (souvent nommée « master »)
  • la branche de développement

La branche principale est le reflet de la production.
La branche de développement est celle sur laquelle travaillera l’équipe entre chaque mise en production.

Le créateur du repository va ensuite lier celui-ci au remote repository(dépôt distant), avec la commande :
git remote add nom_que_l'on_veut_donner_au_remote_repository adresse_du_remote_repository

Généralement, le remote est nommé « origin ». Par la suite, dans cette page, nous l’appellerons donc origin.

Il va ensuite envoyer son travail vers le remote repository, avec la commande :
git push origin nom_de_la_branche

Une fois l’opération terminée, les autres développeurs vont pouvoir récupérer le projet avec un :
git clone adresse_du_remote_repository.

Chacun va ensuite créer une nouvelle branche à partir de la branche de développement, et travailler sur sa fonctionnalité.

Exemple :

Nous avons une équipe de 2 développeurs chargés de développer une application web pour gérer un concours des plus belles chaussettes.

L’un d’entre eux va donc créer les fichiers initiaux et faire un premier commit pour créer la branche master :
github-1
Puis il va créer une nouvelle branche dev :
github-2
Ensuite, il push son travail vers le remote repository :
github-3
Enfin, l’autre membre du groupe clone le repository :
github-4
Chacun crée ensuite sa propre branche pour travailler sur sa tâche :
github-5

Partager son travail

Lorsque chacun travaille sur sa branche, on versionne ses fichiers à l’aide de commit. On en fait le plus souvent possible, afin d’avoir des versions auxquelles retourner pour ne pas perdre trop de temps.
En plus de ça, on peut faire une sauvegarde sur Github en utilisant la commande :
git push origin nom_de_la_branche.
La branche sera ainsi partagée avec les autres, qui pourront déjà jeter un oeil à votre travail.
Mais pour vraiment demander aux autres d’examiner votre code, que ce soit parce que vous avez fini votre fonctionnalité, ou parce que vous êtes bloqués, la bonne solution est de faire un pull-request !
Cette fonction permet aux autres de revoir votre code et d’engager des discussions.

Quand votre pull-request est ouverte, vous pouvez toujours faire des push sur votre branche, la pull-request permettra de voir ces différences !

Une fois que les changements apportés par votre branche sont acceptés par les autres membres de l’équipe, l’un d’entre eux peut merge cette branche avec la branche de développement.
Toute l’équipe va ensuite, localement, se positionner sur la branche de développement, et lancer la commande :
git pull origin nom_de_la_branche_de_développement pour mettre à jour leur propre branche de développement.

Vous ne devriez jamais merge votre propre branche, pour être sûr que tout le monde est d’accord avec ces changements.

Chacun va ensuite mettre la branche sur laquelle il travaille à jour en se positionnant dessus et en tapant la commande :
git merge nom_de_la_branche_de_développement.

Il reste à chacun à régler les conflits qui pourraient apparaître, puis à continuer de travailler sur sa branche !

Exemple :

Nos deux précédents développeurs ont chacun avancé sur leurs branches respectives :

github-6

Le premier a terminé sa fonctionnalité et fait un push :

github-7

Il fait ensuite une pull-request, le second développeur regarde le code, accepte les modifications et merge sur la branche dev :

github-8

Les deux développeurs font ensuite ces commandes :
git checkout dev pour se positionner sur leur branche dev locale, puis :
git pull origin dev pour la mettre à jour :

github-9

Enfin, le second développeur va se remettre sur sa branche de travail et la mettre à jour :
git merge dev :
github-10

Ainsi se termine cette introduction au fonctionnement de Git !

Quelques ressources pour aller plus loin :

Un dernier conseil : Soyez rigoureux dans vos changements de branches ! Un git status ne coûte rien et peut vous faire éviter pas mal d’erreurs !

git-logo-svg_

Maintenant, nous allons voir les branches pour pouvoir travailler sereinement en groupe.
Pour les exemples, nous allons garder le même dossier que l’introduction au fonctionnement de Git : versionner un fichier.

Le pointeur HEAD

Avant de parler des branches, on va parler du pointeur HEAD.
Git utilise un pointeur pour savoir où l’on est positionné et quelle est la branche active. C’est lui que l’on déplace lorsqu’on utilise la commande git checkout.

Exemple

Nous avons deux commits, et nous sommes actuellement sur la branche master (notez le sens de la flèche, en effet, un commit pointe vers son parent) :

head-1

Nous allons maintenant nous positionner sur le premier commit :
git checkout f92ad7

head-2

Le pointeur HEAD s’est déplacé sur le premier commit.
Ensuite, on se déplace sur le second commit :
git checkout 80311e

head-3

On a ramené le pointeur HEAD sur le second commit, mais Git ne l’a pas repositionné sur la branche master.
Pour revenir dans l’état initial, et continuer de travailler, on devra effectuer :
git checkout master

head-1

Les branches

On créé des branches pour travailler sans mettre en péril l’intégrité du travail commun.
Lorsqu’on travaille à plusieurs, on créé chacun une branche, ça permet de faire son travail sans altérer la partie commune.

Pour créer une branche, on utilise la commande :
git branch nom_de_la_branche

A noter que l’on donne à la branche un nom identifiable par le groupe. Pas question de mettre votre nom, ou « branche12 » !
On préférera nommer la branche d’après la fonctionnalité que l’on développe, le bug que l’on corrige, etc…

Ensuite, on doit utiliser git checkout nom_de_la_branche_créée pour positionner HEAD dessus.
On est maintenant prêts à travailler sur notre fonctionnalité, correction de bug, etc… !

Pour fusionner notre travail avec le tronc commun, une fois que c’est testé et validé, il faut se positionner sur la branche principale, et fusionner notre travail dessus avec un git merge nom_de_la_branche_fonctionnalité.
On peut ensuite supprimer notre branche de travail devenue inutile à l’aide de git branch -d nom_de_la_branche.

Exemple

Pour l’exemple, nous avons rajouté les fichiers index.html et style.css. On a fait deux commits, histoire d’avoir une branche master un peu plus conséquente.
Voici l’état actuel du repository :

branches-1

Nous devons développer une carte intégrant l’identité de l’auteur de la page.
On va donc créer une nouvelle branche :
git branch id_card

branches-2

Et on va maintenant se positionner dessus avec git checkout id_card :

branches-3

Je peux maintenant modifier mes fichiers html et css pour créer ma fonctionnalité.

Un premier git commit :

branches-3-2

Un second git commit:

branches-4

Imaginons maintenant qu’on me demande de rapidement changer le titre de ma page (voyez ça comme un bugfix), je dois me repositionner sur la branche master git checkout master :

branches-5

Puis je créé une nouvelle branche git branch title_change :

branches-6

Et je me positionne dessus git checkout title_change :

branches-7

Puis je code mon bugfix, et créé un nouveau git commit :

branches-8

Je vais ensuite repasser sur master git checkout master :

branches-8-2

Puis fusionner mon bugfix avec master git merge title_change :

branches-9

Ma branche master est maintenant à jour, avec le titre modifié, je peux donc supprimer la branche inutile git branch -d title_change :

branches-9-2

Pour intégrer ma fonctionnalité « card », je fais un git merge id_card :

branches-10

Ensuite, si je veux continuer, je peux créer un nouveau git commit :

branches-11

Les conflits

Il se peut que vous ayez des conflits lors d’un git merge.
En effet, imaginons que vous modifiez un fichier sur votre branche, lorsque vous fusionnerez celle-ci dans la branche principale, il se peut que sur une même ligne, le code soit différent entre les deux versions.
Git ne va alors pas pouvoir fusionner les deux versions, et vous le fera savoir !
En effet, le fichier en question va avoir quelques indications rajoutées, pour vous pointer quel(s) passage(s) demande(nt) votre attention.
A vous alors de faire les choix pour régler le problème.
Ensuite, vous devrez faire un git add nom_du_fichier, puis un git commit pour terminer la fusion.

Exemple

On va merge une branche feature dans master.

conflict-1

Sur chacune des branches, on a modifié le css au même endroit, et ça provoque un conflit :

conflict-2

Un git status (notez au passage qu’une fois de plus, Git vous dit quoi faire !):

conflict-3

Jetons un coup d’oeil au fichier css :

conflict-4

Le conflit est séparé en deux par une ligne de =.
Dans la partie supérieure, la branche où HEAD est positionné, ici la branche master.
Dans la partie inférieure, la branche feature.
On choisit donc ce qu’on veut conserver, puis on sauvegarde.
On utilise ensuite un git add :

conflict-5

Et on termine par un git commit !

Et voilà, vous savez maintenant utiliser des branches, et régler des conflits !

La prochaine fois, on terminera avec Github cette introduction au fonctionnement de Git !

git-logo-svg_

Git, ça sert à quoi ?

Git est un DVCS, pour Distributed Version Control System, soit un logiciel de gestion de versions décentralisé.
Il sert donc à :

  • conserver les différentes versions des fichiers.
  • suivre l’évolution du code au fil du développement.
  • permettre le travail en équipe, puisque Git n’écrase pas les versions différentes, il les fusionne.

Super, ça a l’air cool, par quoi on commence ?

Deux choix s’offrent à nous :

  1. On part de rien, et on utilisera dans notre dossier de travail la commande git init (qui va créer un dossier .git)
  2. Il existe déjà un remote repository (dépôt distant), et on le clonera à l’aide de la commande git clone adresse_du_repository

A savoir que ce sont des commandes que l’on utilisera une seule fois (normalement), pour la durée du projet !

Exemple :

Je débute un nouveau projet « git-tuto », je me place dans le dossier adéquat, par exemple :
cd /var/www/html/git-tuto

Celui-ci est vide pour le moment:

git-tuto-1

Ensuite, on utilise git init :

git-tuto-2

Concrètement, cette commande vient de créer un dossier .git, contenant le squelette du dépôt :

git-tuto-3

Comment versionner un fichier ?

Pour conserver les différentes versions de nos fichiers, on demande à git de prendre un « snapshot » (un instantané) des fichiers voulus. Il faut avant tout lui préciser quel fichier doit
être versionné ou non.
Les fichiers de notre dossier vont avoir des statuts différents, dont deux principaux :

  • suivi (faisant parti du précédent snapshot).
  • non suivi.

Un fichier suivi peut avoir plusieurs états :

  • non modifié (il n’apparaîtra pas dans le git status)
  • modifié (il apparaîtra dans le git status en rouge)
  • prêt à être validé (il apparaîtra dans le git status en vert)

Pour passer le statut d’un fichier de « non suivi » à « suivi », on utilise la commande :
git add nom_du_fichier

Cette commande permet de passer directement le fichier à l’état « prêt à être validé ».
Pour passer le statut d’un fichier de « suivi » à « non suivi », on utilise la commande :
git rm --cached nom_du_fichier

Une fois qu’on a nos fichiers prêts à être validés, on va prendre le snapshot et ainsi conserver leur version actuelle.
Pour ce faire, on utilise la commande :
git commit

L’éditeur par défaut va s’ouvrir pour qu’on attache un message à notre commit, décrivant les changements apportés par cette version.
/!\ ATTENTION : Ne pas mettre de message annulera le commit !

Sinon, on peut directement écrire le message :
git commit -m "changements_apportés_par_cette_version"

Exemple :

On créé un fichier README.md : nano README.md
Pour l’exemple, on écrit « #Bienvenue dans le tutoriel Git »
Si on effectue un git status :

git-tuto-4

Ajoutons ce fichier dans la liste des fichiers suivis :
git add README.md
Un git status :

git-tuto-5

Que s’est-il passé concrètement dans notre dossier .git ?

git-tuto-6

Un objet ? Mais on a pas encore fait de commit ?!
Ce long numéro est un checksum (cliquez ici pour en savoir plus).
Regardons ça en détail avec un git cat-file -p numéro_de_l'objet qui permet de lire ces objets:

git-tuto-7

Il a donc pris en compte notre git add !
Cependant, il n’a pas encore vraiment sauvegardé cette version du fichier, on va s’en rendre compte tout de suite.
Modifions README.md en ajoutant un point d’exclamation par exemple : « #Bienvenue dans le tutoriel Git! »
Un git status :

git-tuto-8

On a une nouvelle version « modifiée », en plus de celle que l’on a ajouté tout à l’heure !
On a donc deux versions d’un même fichier. On a donc deux choix :

  • On ne veut pas conserver l’ancienne version, et on fait git add README.md et on supprime l’ancienne version (preuve qu’il ne l’a pas encore vraiment sauvegardé.
  • On veut conserver les deux versions, et on fait d’abord un git commit pour créer un snapshot.

Pour l’exemple, on va supposer qu’on veut conserver les deux versions.

on commence donc par :
git commit -m "ajout d'un fichier README.md"

git-tuto-9

Que s’est-il passé concrètement ?

git-tuto-10

On a 3 objets qui ont été ajoutés ! Pour un seul commit ??
Regardons dans le détail :

git-tuto-11

L’un nous apprend l’état du dépôt lors du commit, l’autre les fichiers (ainsi que leur checksum) qui en font partie.
Les 3 objets combinés permettent à git de connaitre l’état exact du dépôt lors du snapshot.
Pour avoir accès à la liste des commits, la commande git log permet de voir les commits du repository.

git-tuto-12

Un git status :

git-tuto-13

Et oui, il reste toujours cette version modifiée, on va donc faire un git commit pour conserver aussi cette version de ce fichier :

git-tuto-14

Enfin, un git log pour se rendre compte de la présence de deux versions différentes :

git-tuto-15

Voilà, on vient de versionner README.md, on a donc deux versions différentes de notre fichier !

Très bien, comment on y accède maintenant ?

C’est très simple, il suffit de faire git checkout code_du_commit pour revenir sur une ancienne version !

Exemple

git-tuto-16

On a donc appris à versionner un fichier, et à naviguer entre les versions de celui ci.

La prochaine fois, on verra comment travailler à plusieurs, avec des branches, et en utilisant github !