From eca846a0c3f99e3324e023b0a86d489668766366 Mon Sep 17 00:00:00 2001 From: Lucien Cartier-Tilet Date: Wed, 2 Sep 2020 23:15:49 +0200 Subject: [PATCH] Add Drone CI automatic deployment --- .drone.yml | 37 ++ content/.gitignore | 1 - content/better-custom-ids-orgmode.md | 299 +++++++++ content/tutoriel-git-et-github.md | 865 +++++++++++++++++++++++++++ publish | 2 +- 5 files changed, 1202 insertions(+), 2 deletions(-) create mode 100644 .drone.yml delete mode 100644 content/.gitignore create mode 100644 content/better-custom-ids-orgmode.md create mode 100644 content/tutoriel-git-et-github.md diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..61ccf4c --- /dev/null +++ b/.drone.yml @@ -0,0 +1,37 @@ +kind: pipeline +name: default + +steps: +- name: prepare + image: alpine + commands: + - apk add git + - git submodule update --init --recursive + +- name: build + image: alpine + commands: + - apk add hugo + - mkdir blog + - hugo -d blog + +- name: deploy + image: appleboy/drone-scp + settings: + host: + from_secret: ssh_host + target: + from_secret: ssh_target + source: blog/* + username: + from_secret: ssh_username + password: + from_secret: ssh_password + port: + from_secret: ssh_port + when: + branch: + - master + event: + exclude: + - pull_request diff --git a/content/.gitignore b/content/.gitignore deleted file mode 100644 index dd44972..0000000 --- a/content/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.md diff --git a/content/better-custom-ids-orgmode.md b/content/better-custom-ids-orgmode.md new file mode 100644 index 0000000..7bafa83 --- /dev/null +++ b/content/better-custom-ids-orgmode.md @@ -0,0 +1,299 @@ ++++ +title = "[EN] Automatic Meaningful Custom IDs for Org Headings" +author = ["Lucien “Phundrak” Cartier-Tilet"] +date = 2020-06-06 +tags = ["emacs", "orgmode"] +categories = ["emacs", "linux", "conlanging", "orgmode"] +draft = false +[menu.main] + weight = 2001 + identifier = "en-automatic-meaningful-custom-ids-for-org-headings" ++++ + +Spoiler alert, I will just modify a bit of code that already exists, go +directly to the bottom if you want the solution, or read the whole post if +you are interested in how I got there. + +
+
+ +- [The issue](#the-issue) +- [A first solution](#a-first-solution) +- [These headers are not meaningful](#these-headers-are-not-meaningful) + +
+ + + +## The issue {#the-issue} + +About two to three years ago, as I was working on a project that was meant +to be published on the internet, I looked for a solution to get fixed anchor +links to my various headings when I performed HTML exports. As some of you +may know, by default when an Org file is exported to an HTML file, a random +ID will be generated for each header, and this ID will be used as their +anchor. Here’s a quick example of a simple org file: + +```org +#+title: Sample org file +* First heading + Reference to a subheading +* Second heading + Some stuff written here +** First subheading + Some stuff +** Second subheading + Some other stuff +``` + +
+ Code Snippet 1: + Example org file +
+ +And this is the result once exported to HTML (with a lot of noise removed +from ``): + +```html + + + + Sample org file + + + + + +
+

Sample org file

+
+

1 First heading

+
+

+ Reference to a subheading +

+
+
+
+

2 Second heading

+
+

+ Some stuff written here +

+
+
+

2.1 First subheading

+
+

+ Some stuff +

+
+
+
+

2.2 Second subheading

+
+

+ Some other stuff +

+
+
+
+
+ + + +``` + +
+ Code Snippet 2: + Output HTML file +
+ +As you can see, all the anchors are in the fomat of `org[a-f0-9]{7}`. First, +this is not really meaningful if you want to read the anchor and guess where +it will lead you. But secondly, these anchors will change each time you +export your Org file to HTML. If I want to share a URL to my website and to +a specific heading,… well I can’t, it will change the next time I update the +document. And I don’t want to have to set a `CUSTOM_ID` property for each +one of my headings manually. So, what to do? + + +## A first solution {#a-first-solution} + +A first solution I found came from [this blog post](https://writequit.org/articles/emacs-org-mode-generate-ids.html), where Lee Hinman +described the very same issue they had and wrote some Elisp code to remedy +that (it’s a great read, go take a look). And it worked, and for some time I +used their code in my Emacs configuration file in order to generate unique +custom IDs for my Org headers. Basically what the code does is it detects if +`auto-id:t` is set in an `#+OPTIONS` header. If it is, then it will iterate +over all of the Org headers, and for each one of them it will insert a +`CUSTOM_ID`, which is made from a UUID generated by Emacs. And tada! we get +for each header a +`h-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}` custom ID +that won’t change next time we export our Org file to HTML when we save our +file, and only for headings which don’t already have a `CUSTOM_ID` property. +Wohoo! + +Except… + + +## These headers are not meaningful {#these-headers-are-not-meaningful} + +Ok, alright, that’s still a huge step forward, we don’t have to type any +CUSTOM\_ID property manually anymore, it’s done automatically for us. But, +when I send someone a link like +`https://langue.phundrak.com/eittland#h-76fc0b91-e41c-42ad-8652-bba029632333`, +the first reaction to this URL is often something along the lines of “What +the fuck?”. And they’re right, this URL is unreadable when it comes to the +anchor. How am I supposed to guess it links to the description of the vowels +of the Eittlandic language? (That’s a constructed language I’m working on, +you won’t find anything about it outside my website.) + +So, I went back to my configuration file for Emacs, and through some trial +and error, I finally found a way to get a consistent custom ID which is +readable and automatically set. With the current state of my code, what you +get is the complete path of the Org heading, all spaces replaced by +underscores and headings separated by dashes, with a final unique identifier +taken from an Emacs-generated UUID. Now, the same link as above will look +like +`https://langue.phundrak.com/eittland#Aperçu_structurel-Inventaire_phonétique_et_orthographe-Voyelles_pures-84f05c2c`. +It won’t be more readable to you if you don’t speak French, but you can +guess it is way better than what we had before. I even added a safety net by +replacing all forward slashes with dashes. The last ID is here to ensure the +path will be unique in case we’d have two identical paths in the org file +for one reason or another. + +The modifications I made to the first function `eos/org-id-new` are minimal, +where I just split the UUID and get its first part. This is basically a way +to simplify it. + +```emacs-lisp +(defun eos/org-id-new (&optional prefix) + "Create a new globally unique ID. + +An ID consists of two parts separated by a colon: +- a prefix +- a unique part that will be created according to + `org-id-method'. + +PREFIX can specify the prefix, the default is given by the +variable `org-id-prefix'. However, if PREFIX is the symbol +`none', don't use any prefix even if `org-id-prefix' specifies +one. + +So a typical ID could look like \"Org-4nd91V40HI\"." + (let* ((prefix (if (eq prefix 'none) + "" + (concat (or prefix org-id-prefix) + "-"))) unique) + (if (equal prefix "-") + (setq prefix "")) + (cond + ((memq org-id-method + '(uuidgen uuid)) + (setq unique (org-trim (shell-command-to-string org-id-uuid-program))) + (unless (org-uuidgen-p unique) + (setq unique (org-id-uuid)))) + ((eq org-id-method 'org) + (let* ((etime (org-reverse-string (org-id-time-to-b36))) + (postfix (if org-id-include-domain + (progn + (require 'message) + (concat "@" + (message-make-fqdn)))))) + (setq unique (concat etime postfix)))) + (t (error "Invalid `org-id-method'"))) + (concat prefix (car (split-string unique "-"))))) +``` + +Next, we have here the actual generation of the custom ID. As you can see, +the `let` has been replaced by a `let*` which allowed me to create the ID +with the variables `orgpath` and `heading`. The former concatenates the path +to the heading joined by dashes, and `heading` concatenates `orgpath` to the +name of the current heading joined by a dash if `orgpath` is not empty. It +will then create a slug out of the result, deleting some elements such as +forward slashes or tildes, and all whitespace is replaced by underscores. It +then passes `heading` as an argument to the function described above to +which the unique ID will be concatenated. + +```emacs-lisp +(defun eos/org-custom-id-get (&optional pom create prefix) + "Get the CUSTOM_ID property of the entry at point-or-marker POM. + +If POM is nil, refer to the entry at point. If the entry does not +have an CUSTOM_ID, the function returns nil. However, when CREATE +is non nil, create a CUSTOM_ID if none is present already. PREFIX +will be passed through to `eos/org-id-new'. In any case, the +CUSTOM_ID of the entry is returned." + (interactive) + (org-with-point-at pom + (let* ((orgpath (mapconcat #'identity (org-get-outline-path) "-")) + (heading (replace-regexp-in-string + "/\\|~\\|\\[\\|\\]" "" + (replace-regexp-in-string + "[[:space:]]+" "_" (if (string= orgpath "") + (org-get-heading t t t t) + (concat orgpath "-" (org-get-heading t t t t)))))) + (id (org-entry-get nil "CUSTOM_ID"))) + (cond + ((and id + (stringp id) + (string-match "\\S-" id)) id) + (create (setq id (eos/org-id-new (concat prefix heading))) + (org-entry-put pom "CUSTOM_ID" id) + (org-id-add-location id + (buffer-file-name (buffer-base-buffer))) + id))))) +``` + +The rest of the code is unchanged, here it is anyway: + +```emacs-lisp +(defun eos/org-add-ids-to-headlines-in-file () + "Add CUSTOM_ID properties to all headlines in the current file +which do not already have one. + +Only adds ids if the `auto-id' option is set to `t' in the file +somewhere. ie, #+OPTIONS: auto-id:t" + (interactive) + (save-excursion + (widen) + (goto-char (point-min)) + (when (re-search-forward "^#\\+OPTIONS:.*auto-id:t" + (point-max) + t) + (org-map-entries (lambda () + (eos/org-custom-id-get (point) + 'create)))))) + +(add-hook 'org-mode-hook + (lambda () + (add-hook 'before-save-hook + (lambda () + (when (and (eq major-mode 'org-mode) + (eq buffer-read-only nil)) + (eos/org-add-ids-to-headlines-in-file)))))) +``` + +Note that you **will need** the package `org-id` to make this code work. You +simply need to add the following code before the code I shared above: + +```emacs-lisp +(require 'org-id) +(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) +``` + +And that’s how my links are now way more readable **and** persistent! The only +downside I found to this is when you move headings and their path is +modified, or when you modify the heading itself, the custom ID is not +automatically updated. I could fix that by regenerating the custom ID on +each save, regardless of whether a custom ID already exists or not, but it’s +at the risk an ID manually set will get overwritten. + +
+
+ + +
+ +
diff --git a/content/tutoriel-git-et-github.md b/content/tutoriel-git-et-github.md new file mode 100644 index 0000000..4ae723b --- /dev/null +++ b/content/tutoriel-git-et-github.md @@ -0,0 +1,865 @@ ++++ +title = "[Fr] Tutoriel Git et Github" +author = ["Lucien “Phundrak” Cartier-Tilet"] +date = 2020-06-05 +tags = ["linux", "git", "tutorial", "tutoriel"] +categories = ["emacs", "linux", "conlanging", "orgmode"] +draft = false +[menu.main] + weight = 2001 + identifier = "fr-tutoriel-git-et-github" ++++ + +
+
+ +- [Git ? Qu'est-ce donc ?](#git-qu-est-ce-donc) +- [Ça a l’air cool, comment ça s’obtient ?](#ça-a-l-air-cool-comment-ça-s-obtient) +- [Ok très bien, comment on l’utilise maintenant ?](#ok-très-bien-comment-on-l-utilise-maintenant) +- [J’ai entendu parler de Github…](#j-ai-entendu-parler-de-github) +- [J’ai téléchargé un projet en zip](#j-ai-téléchargé-un-projet-en-zip) +- [Et si je veux créer mon propre dépôt sur Github](#et-si-je-veux-créer-mon-propre-dépôt-sur-github) +- [Et du coup, comment je met tout ça en ligne ?](#et-du-coup-comment-je-met-tout-ça-en-ligne) +- [Quelqu’un a fait des modifications depuis mon dernier commit, je récupère ça comment ?](#quelqu-un-a-fait-des-modifications-depuis-mon-dernier-commit-je-récupère-ça-comment) +- [Je suis en train de travailler sur le même fichier que Ginette](#je-suis-en-train-de-travailler-sur-le-même-fichier-que-ginette) +- [Github ne veut pas de mes pushs sur le dépôt de Gilberte, oskour !](#github-ne-veut-pas-de-mes-pushs-sur-le-dépôt-de-gilberte-oskour) +- [Fork ? Pull request ? Que font des fourchettes et des pulls dans ce tuto ?](#fork-pull-request-que-font-des-fourchettes-et-des-pulls-dans-ce-tuto) +- [J’ai remarqué un bug ou une erreur, mais je ne peux pas corriger ça moi-même](#j-ai-remarqué-un-bug-ou-une-erreur-mais-je-ne-peux-pas-corriger-ça-moi-même) +- [Les raccourcis et paramètres de Git](#les-raccourcis-et-paramètres-de-git) +- [Et c’est tout ?](#et-c-est-tout) + +
+ + + +## Git ? Qu'est-ce donc ? {#git-qu-est-ce-donc} + +Git est un logiciel de version de fichiers permettant de garder une trace de +toutes les modifications apportées au fichiers suivis dans un répertoire (un +dépôt) et ses sous-répertoires –sous couvert qu’ils n’aient pas été ignorés +explicitement. Il permet également de conserver plusieurs versions +parallèles du projet, comme par exemple une version stable et une version de +développement, et permet l’ajout de modifications d’une de ces versions +parallèles à une autre via des fusions partielles ou totales de branches, +avec une automatisation des fusions de fichiers lorsqu’il n’y a pas de +conflit entre ces derniers. + +Avant de continuer, sache que je suis bilingue français-sarcasme, si tu es +du genre à t’énerver pour un rien, cette page est à haut risque pour toi. + +Toujours là ? Tu auras été prévenu·e. + + +## Ça a l’air cool, comment ça s’obtient ? {#ça-a-l-air-cool-comment-ça-s-obtient} + + +### Et surtout, comment ça s’installe ? {#et-surtout-comment-ça-s-installe} + +Très bonne question Kevin. Tout d’abord, il faut t’assurer que git soit +installé sur ton système et utilisable depuis le terminal. Sous GNU/Linux, +tu peux l’installer via ton gestionnaire de paquet, ce qui rendra la +commande accessible directement depuis le terminal. Tu auras sans doute +besoin de préfixer la commande avec `sudo`. Si tu n’as pas les droits pour +utiliser `sudo`, demande à celui qui a les droits (ton administrateur +système ou ton papa). + +```sh +$ apt install git # Debian, Ubuntu et les distros basées dessus +$ yum install git # CentOS +$ dnf -y install git # Fedora +$ pacman -S git # ArchLinux et les distros basées dessus +$ emerge --ask --verbose dec-vcs/git # Gentoo +``` + +{{< figure src="/ox-hugo/install-gentoo.jpg" caption="Figure 1: >install gentoo" >}} + +Si tu n’es pas sous GNU/Linux mais que tu as au moins le goût d’être sous +un OS de type Unix, tu peux exécuter la commande correspondante à ton OS +suivant : + +```sh +$ pkg install git # FreeBSD +$ brew install git # macOS avec brew +$ port install git +svn +doc +bash_completion +gitweb # macOS avec MacPorts +``` + +Si tu es sous Windows, soit tu utilises le WSL (Windows Subsystem for +Linux), soit… bonne chance. Toutes les commandes seront en syntaxe Unix +dans ce tutoriel, mais si tu as bien deux neurones, tu devrais pouvoir tout +de même suivre le tutoriel. + + +### Ok c’est bon, et il y a une configuration à faire ? {#ok-c-est-bon-et-il-y-a-une-configuration-à-faire} + +Tu peux configurer Git si tu le souhaites, oui. En général, il est +recommandé de paramétrer au moins son nom et son e-mail. Tu peux les +paramétrer via la ligne de commande : + +```sh +$ git config --global user.name "Kévin Masturbin" +$ git config --global user.email "kevin.du.neuftrwa@hotmail.com" +``` + +Tu peux aussi éditer le fichier `~/.gitconfig` comme suit : + +```toml +[user] + email = ton@email.truc + name = Ton nom +``` + +Cela permettra d’associer ton nom et ton adresse mail à tes commits. Par +défaut, ceux qui sont enregistrés avec ton compte utilisateur de ton PC +sont mis par défaut dans ces paramètres, mais on met quasiment tous un nom +à la con quand on le créé. Et ça permet d’avoir les même paramètres si tu +es sur un autre ordinateur. + +Il y a encore pas mal de paramètres que tu peux gérer avec ce fichier, je +reparlerai de certains plus tard, mais pour le reste, la documentation en +ligne sur `gitconfig` ne manque pas. + + +## Ok très bien, comment on l’utilise maintenant ? {#ok-très-bien-comment-on-l-utilise-maintenant} + +Du calme Jean-Kevin, ralentis un peu. Comme le dit ce vieux dicton +Chinois : + +> Celui qui marche trop vite…… marche…………… trop… vite…? C’est compliqué les +> dictons chinois… + +De toutes façons, ce dicton est une contrefaçon, donc la qualité de la +citation n’est pas extraordinaire. Bref. + + +### Je commence comment ? {#je-commence-comment} + +Si tu souhaites créer un dépôt git, rien de plus simple : créé ton +répertoire dans lequel tu travailleras, et déplace-y-toi. Ensuite, tu +pourra initialiser ton dépôt via la commande `git init`. + +```text +$ mkdir monsuperprojet +$ cd monsuperprojet +$ git init +Initialized empty Git repository in /tmp/monsuperprojet/.git/ +``` + +Si tu obtiens à peu près le même message après la dernière commande, +félicitations ! Tu viens de créer ton premier dépôt git. En l’occurrence, +j’ai créé mon dépôt dans `/tmp`, mais toi tu peux voir un truc du genre +`/home/corentin/monsuperprojet` à la place. Tu peux vérifier que tout va +bien en rentrant la commande `git status`. + +```text +$ git status +On branch master + +No commits yet + +nothing to commit (create/copy files and use "git add" to track) +``` + +Parfait ! Ah, et ne met rien d’important dans `/tmp`, ce dossier est +réinitialisé à chaque redémarrage de ta machine. Ou alors, met-y uniquement +des fichiers que tu ne souhaites avoir que temporairement sur ta machine +(comme ce meme que tu télécharges depuis Reddit pour le reposter sur +Discord). + + +### Et pour rajouter des fichiers ? {#et-pour-rajouter-des-fichiers} + +Maintenant tu peux commencer à travailler sur ton projet. Mais tout +d’abord, on va voir ce qu’il se passe si jamais on créé un fichier dans le +dépôt. Créé un fichier `main.c` dans lequel tu vas entrer ce code : + +```c +#include + +int main(int ac, char* av[]) { + printf("Hello World!\n"); + return 0; +} +``` + +Bref, si tu exécutes à nouveau git status, tu obtients cette sortie : + +```text +$ git status +On branch master + +No commits yet + +Untracked files: + (use "git add ..." to include in what will be committed) + + main.c + +nothing added to commit but untracked files present (use "git add" to track) +``` + +Tu commences à comprendre un peu le bail ? Git vient de détecter qu’un +nouveau fichier a été créé qu’il ne connaissait pas avant. Suivons ses bon +conseils et ajoutons le fichier au dépôt. + +```text +$ git add main.c +$ git status +On branch master + +No commits yet + +Changes to be committed: + (use "git rm --cached ..." to unstage) + + new file: main.c +``` + +Super, maintenant git va surveiller les changements du fichier, mais +attention, il n’a pas encore enregistré son état. Pour l’instant il sait +juste que le fichier est là, dans un certain état, mais rien ne garanti +encore qu’on pourra retrouver cet état plus tard. On appelle ça le +_staging_. Pour ce faire, il faut créer ce qu’on appelle un _commit_. En +gros, il s’agit d’un enregistrement des modifications apportées à un ou +plusieurs fichiers (dans leur globalité ou partiellement, on verra ça plus +tard), le tout avec un commentaire. + +```text +$ git commit -m "Un petit pas pour moi, un grand pas pour mon projet" +[master (root-commit) 89139ef] Un petit pas pour moi, un grand pas pour mon projet + 1 file changed, 6 insertions(+) + create mode 100644 main.c +``` + +Parfait ! Certains éléments peuvent être un peu différent chez toi, comme +par exemple la référence du commit juste avant le message. Ça, c’est un +truc qui est géré automatiquement par git. Et voilà, on a l’état de notre +répertoire qui est enregistré et qui sera disponible plus tard. Maintenant, +tu sais comment enregistrer des état de ton dépôt via les commits. + + +### Cool, mais j’ai accidentellement mis un fichier en staging {#cool-mais-j-ai-accidentellement-mis-un-fichier-en-staging} + +Si jamais tu as un staging que tu veux annuler, tu peux utiliser la +commande `git reset HEAD nomdufichier` (ou plusieurs noms de fichiers) pour +annuler le staging. Une fois le fichier qui n’est plus dans ton staging, tu +peux même annuler toutes les modifications que tu as apporté au fichier +depuis ton dernier commit avec la commande `git checkout -- nomdufichier`, +et tu peux aussi mettre plusieurs noms de fichiers. Par exemple, si j’ai +modifié mon `main.c` en modifiant ainsi les arguments du `main()` : + +```c +#include + +int main(void) { + printf("Hello World!\n"); + return 0; +} +``` + +Je peux annuler tout ça via ces commandes : + +```text +$ git reset HEAD main.c +Unstaged changes after reset: +M main.c +$ git checkout -- main.c +$ git status +On branch master +nothing to commit, working tree clean +``` + +Si je fait un `cat main.c`, je vois qu’il est revenu à son état initial. + +Et petite remarque concernant les arguments de la fonction `main` en C : on +peut leur donner le nom que l’on souhaite (personellement j’aime bien +parfois metre `ac` et `av` au lieu de `argc` et `argv`), ça ne changera +strictement rien au comportement du code. Et si l’on ne souhaite pas +utiliser les arguments reçus par le `main`, on peut simplement déclarer la +fonction main comme `main(void)`. Au moins, c’est clair pour le compilateur +et le lecteur du code : on s’en fiche des arguments du `main`. + +Par contre, chose importante : mettre void en arguments du main est du C, +**et ce n’est pas valide en C++**. _Le C++ n’est pas du C avec des +fonctionnalités en plus_. + + +### En fait, j’ai juste oublié un truc dans mon commit précédent {#en-fait-j-ai-juste-oublié-un-truc-dans-mon-commit-précédent} + +Si jamais tu veux à la place ajouter la modification d’un fichier au +dernier commit (mettons, tu as oublié d’ajouter également un fichier +texte), tu peux utiliser l’option `--amend` lors du commit du fichier +oublié. + +```text +$ git add main.c # J’ai refait les modifications annulées plus tôt +$ git commit -m "second commit" +[master 97f698a] second commit +1 file changed, 1 insertion(+), 1 deletion(-) +$ echo "C’est un super projet !" > projet.txt +$ git add projet.txt +$ git commit --amend -m "second commit + oubli" +[master 9aff4c0] second commit + oubli +Date: Fri Oct 5 11:10:56 2018 +0200 +2 files changed, 2 insertions(+), 1 deletion(-) +create mode 100644 projet.txt +``` + +En gros, le commit que tu viens de faire a remplacé le précédent en +conservant les informations du commit précédent, mis à part son +commentaire. Si tu ne met pas l’option `-m "ton texte"` lors de +l’amendement du commit, ton éditeur texte par défaut va s’ouvrir pour que +tu puisses modifier le texte du commit précédent si tu le souhaite. Si +jamais vim s’ouvre et que tu n’as aucune idée de comment sortir de cet +enfant du démon, tu as juste à appuyer sur la touche Échap (au cas où), +puis à taper `:wq` (`w` pour écrire le fichier, `q` pour quitter), puis tu +appuie sur la touche Entrée. Si tu as Nano qui s’est ouvert, alors il faut +taper Ctrl-X. Dans tous les cas, tu aurais dû utiliser Emacs. + + +### Euh, j’ai oublié ce que j’ai changé lors du dernier commit {#euh-j-ai-oublié-ce-que-j-ai-changé-lors-du-dernier-commit} + +Pas de panique ! Tu peux entrer la commande `git diff` afin de voir ce que +tout ce que tu as modifié lors de ton dernier commit. Et si tu ne souhaite +voir les modifications que d’un certain fichier, tu peux ajouter le nom de +ton fichier à la fin de la commande. + +```text +$ echo "C’est un super projet !" > projet.txt +$ git diff +diff --git a/projet.txt b/projet.txt +index 03b0f20..b93413f 100644 +--- a/projet.txt ++++ b/projet.txt +@@ -1 +1 @@ +-projet ++C’est un super projet ! +``` + +Tu peux également voir les différences de fichiers entre deux commits en +entrant leur référence. Pour avoir la référence, tu peux rentrer la +commande `git log` pour avoir un petit historique des commits. + +```text +$ git log +commit 4380d8717261644b81a1858920406645cf409028 (HEAD -> master) +Author: Phuntsok Drak-pa +Date: Fri Oct 5 11:59:40 2018 +0200 + + new commit + +commit 59c21c6aa7e3ec7edd229f81b87becbc7ec13596 +Author: Phuntsok Drak-pa +Date: Fri Oct 5 11:10:56 2018 +0200 + + nouveau texte + +commit 89139ef233d07a64d3025de47f8b6e8ce7470318 +Author: Phuntsok Drak-pa +Date: Fri Oct 5 10:56:58 2018 +0200 + + Un petit pas pour moi, un grand pas pour mon projet +``` + +Bon, c’est un peu long et un peu trop d’infos d’un coup, généralement je +préfère taper `git log --oneline --graph --decorate` afin d’avoir un +affichage comme suit : + +```text +$ git log --oneline --graph --decorate +* 4380d87 (HEAD -> master) new commit +* 59c21c6 nouveau texte +* 89139ef Un petit pas pour moi, un grand pas pour mon projet +``` + +Plus propre, non ? Et les références sont plus courtes, ce qui est plus +agréable à taper. Allez, comparons les deux derniers commits. + +```text +$ git add . +$ git commit -m "new commit" +$ git log --oneline --graph --decorate +* 4380d87 (HEAD -> master) new commit +* 59c21c6 nouveau texte +* 89139ef Un petit pas pour moi, un grand pas pour mon projet +$ git diff 59c21c6 4380d87 +diff --git a/projet.txt b/projet.txt +index 03b0f20..b93413f 100644 +--- a/projet.txt ++++ b/projet.txt +@@ -1 +1 @@ +-projet ++C’est un super projet ! +``` + + +### Il y a des fichiers dont je me fiche dans mon dépôt {#il-y-a-des-fichiers-dont-je-me-fiche-dans-mon-dépôt} + +Dans ce cas, il est grand temps de te présenter le fichier `.gitignore`. +Comme son nom l’indique, il permet au dépôt d’ignorer des fichiers selon ce +que tu lui indiqueras. Par exemple, si tu veux ignorer tous les fichiers +qui se terminent en `.out` (ou `.exe` sous Windows), tu peux éditer (ou +créer) ton `.gitignore` et entrer ces lignes : + +```gitignore +*.out +*.exe +``` + +Maintenant, si tu créés un fichier en `.out` ou `.exe`, il sera +complètement ignoré par git et ne sera pas stocké dans l’historique des +versions. Il s’agit de ce qu’on appelle du globbing. En gros, l’étoile +indique que tu t’en fiches de ce qu’il y a devant `.out` ou `.exe` dans cet +exemple, si quelque chose se termine par ça, c’est ignoré. Pour ignorer +quelque chose dans un dossier, tu pourrais avoir quelque chose du genre +`mondossier/*` et POUF, tous les fichiers de `mondossier/` sont ignorés. En +gros, le globbing va fonctionner comme le globbing de ton shell (Bash, Zsh, +Fish,…) + +Par exemple, [voici un dépôt](https://labs.phundrak.com/phundrak/langue-phundrak-com/commit/f8ec1936f839e9e95a6badf4480589f5bc9d00a0) un peu plus complexe que ce qu’on est en train +de faire (figé lors d’un commit fixé). Tu peux voir dans mon `.gitignore` +qu’il y a pas mal d’extensions de fichiers qui sont ignorées, mais j’ai +aussi `_minted*` et `auto-generated*` qui sont des dossiers ignorés, et pas +juste leur contenu qui est ignoré (l’étoile est là pour ignorer tous les +dossiers dont le nom commence par ce qui précède l’étoile). J’ai aussi +ignoré le dossier `.dart_tool/` qui lui pour le coup n’a pas de globbing, +ainsi que le fichier `pubspec.lock`, sans globbing non plus. + + +### On est plusieurs dessus en fait… {#on-est-plusieurs-dessus-en-fait} + +Pas de panique ! Git a été créé pour ça, et il dispose d’une fonctionnalité +de branchage permettant d’avoir plusieurs versions coexistantes d’un même +fichier. Cela peut être très utile pour avoir soit plusieurs personnes +travaillant sur un même projet, soit pour une même personne travaillant sur +plusieurs fonctionnalités différentes, soit les deux. Ainsi, on a plusieurs +version indépendantes que l’on pourra fusionner plus tard. + +Par défaut une branche est créée lors de la création d’un dépôt qui +s’appelle `master`. Pour créer une nouvelle branche, on peut donc utiliser +la commande git checkout -b nomdelanouvellebranche. + +```text +$ git checkout -b nouvelle-branche +Switched to a new branch 'nouvelle-branche' +``` + +À partir d’ici, toute modification apportée aux fichiers du dépôt +n’affecteront que la branche courante, `nouvelle-branche` donc, et les +fichiers de la branche `master` resteront inchangés. Si jamais tu veux +retourner pour une quelconque raison sur la branche `master`, il te suffira +d’utiliser la commande `git checkout master`. + +Si tu souhaites avoir une liste des branches du dépôt, tu peux taper `git + branch --list`. La branche active sera marquée d’une étoile à côté de son +nom. + +```text +$ git branch --list + master +* nouvelle-branche +``` + + +### J’ai accidentellement modifié des fichiers sur la mauvaise branche, mais je n’ai pas encore fait de commits. {#j-ai-accidentellement-modifié-des-fichiers-sur-la-mauvaise-branche-mais-je-n-ai-pas-encore-fait-de-commits-dot} + +Tout va bien alors ! Tu vas simplement exécuter cette commande : + +```text +$ git stash +``` + +Ça va déplacer toutes tes modifications que tu n’as pas encore commit dans +le stash, qui est une sorte d’emplacement temporaire, en dehors des +branches. Normalement, ça va réinitialiser tes fichiers tels qu’ils étaient +lors du dernier commit. Maintenant, change la branche sur laquelle tu +travailles, par exemple tu si tu es sur la branche `kevin`, tu exécutes +ceci : + +```text +$ git checkout kevin +``` + +Tes modifications sont toujours dans ton stack, et pour les restaurer, tu +n’as plus qu’à exécuter + +```text +$ git stash pop +``` + +Et voilà, tu viens de déplacer tes modifications sur la bonne branche. Pour +information, si tu as créé un nouveau fichier ou un nouveau dossier avec +des fichiers, ils ne seront pas déplacés dans le stash, mais ils ne seront +pas supprimés lors de la première commande. Tu auras juste à les commit sur +ta nouvelle branche pour qu’ils cessent de se déplacer de branche en +branche. + + +### Du coup, Mathilde a bien avancé sur son code, et moi aussi, chacun sur notre branche. On fait comment maintenant ? {#du-coup-mathilde-a-bien-avancé-sur-son-code-et-moi-aussi-chacun-sur-notre-branche-dot-on-fait-comment-maintenant} + +Au bout d’un moment, tu vas sans doute vouloir fusionner deux branches, par +exemple tu as finis de développer une nouvelle fonctionnalité sur la +branche `nouvelle-branche` et tu souhaites l’ajouter à la version stable de +ton code qui se situe sur `master`. Dans ce cas, ce que tu peux faire, +c’est retourner sur ta branche `master`, puis tu vas effectuer ce qu’on +appelle un merge ; en gros, pour faire simple, tu vas appliquer les +modifications de la branche que tu souhaites fusionner avec ta branche +`master` sur cette dernière. + +```text +$ git checkout master +Switched to branch 'master' +$ git merge nouvelle-branche +Updating 133c5b6..2668937 +Fast-forward + projet.txt | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 projet.txt +``` + +Rappelle-toi que la commande `merge` ramène les commits de la branche +spécifiée vers ta branche active, et pas forcément vers le `master`. Du +coup, si tu est sur une branche `mathilde` et que tu effectues un `git + merge leon`, tu vas ramener tous les commits de leon vers la branche +mathilde. Ça peut être intéressant à faire si jamais un bug a été corrigé +dans une autre branche ou qu’une fonctionnalité a été ajoutée et que tu +veux en bénéficier dans ta branche active. N’oublie juste pas de tout bien +commit avant de faire ton merge. + + +## J’ai entendu parler de Github… {#j-ai-entendu-parler-de-github} + +Tu commences à me plaire Enzo ! Github est un site web sur lequel tu peux +héberger des projets libres ou open-source (si tu ne connais pas la +différence, voici un article pour t’aider à comprendre, et un autre pour la +route). C’est en particulier orienté pour les projets gérés par git, ce qui +tombe bien car c’est ce qu’on utilise. Cela a pour avantage de pouvoir +aisément partager ton code et d’assurer qu’il est bien sauvegardé quelque +part d’autre que ton disque dur (un `rm -rf` est si vite arrivé). Et +surtout, ça peut te permettre de collaborer avec d’autres personnes sur le +même projet sans te casser la tête. + +> Git est à Github ce que le porn est à Pornhub. + +J’aimerais tout de même te mettre au courant que Github n’est largement pas +le seul site de ce genre à exister. Le concurrent le plus célèbre de Github +est [Gitlab](https://about.gitlab.com/), et personnellement j’utilise [Gitea](https://gitea.io/en-us/). Ces deux derniers peuvent +même être hébergés en instances personnelles, comme [ce que je fais avec +Gitea](https://labs.phundrak.com/phundrak/langue-phundrak-com/commit/f8ec1936f839e9e95a6badf4480589f5bc9d00a0) (qui est beaucoup plus léger que Gitlab, mais avec quelques +fonctionnalités en moins), et il existe encore [plein d’autres alternatives](https://labs.phundrak.com/phundrak/langue-phundrak-com/commit/f8ec1936f839e9e95a6badf4480589f5bc9d00a0), +à toi de trouver les autres. + + +## J’ai téléchargé un projet en zip {#j-ai-téléchargé-un-projet-en-zip} + +Ou bien, tu peux télécharger le projet directement via git. Eh oui ! git +permet de gérer les dépôts dits distants, c’est à dire ceux qui sont +hébergés sur un serveur en ligne, comme par exemple sur Github. Pour cela, +il te faut te munir du lien vers le dépôt git, et le passer en argument de +git clone. Par exemple, si tu veux télécharger de dépôt du petit logiciel de +chat en réseau que j’ai codé durant ma L2 d’informatique, tu peux exécuter +ceci : + +```text +$ git clone https://github.com/noalien/GL4Dummies.git +Cloning into 'GL4Dummies'... +remote: Enumerating objects: 682, done. +remote: Counting objects: 100% (682/682), done. +remote: Compressing objects: 100% (455/455), done. +remote: Total 3516 (delta 354), reused 509 (delta 215), pack-reused 2834 +Receiving objects: 100% (3516/3516), 72.95 MiB | 2.13 MiB/s, done. +Resolving deltas: 100% (2019/2019), done. +``` + +Et c’est bon, tu as accès au répertoire `GL4Dummies` et au code source du +projet. (Courage aux élèves de Paris 8 qui feront de la programmation +graphique !) + + +## Et si je veux créer mon propre dépôt sur Github {#et-si-je-veux-créer-mon-propre-dépôt-sur-github} + +Dans ce cas là, c’est simple Brigitte. Il faut que tu te créés un compte sur +Github, puis tu cliques sur le bouton `+` et `New Repository`. Tu lui donnes +le nom que tu souhaites (en l’occurrence je le nomme `temporary-repo` car je +vais le supprimer cinq minutes après l’écriture de ces lignes), et tu +cliques sur `Create Repository`. Tu n’ajoutes rien avant, pas de +description, pas de `.gitignore`, RIEN. + +Et là, magie ! Github indique comment ajouter le dépôt distant à ton dépôt +local. + +```text +$ git remote add origin https://github.com/Phundrak/temporary-repo.git +``` + +Et voilà, ton dépôt est lié au dépôt distant. Oui, juste comme ça. + +Sinon, si tu souhaites d’abord créer ton dépôt sur Github puis sur ta +machine, tu peux aussi très bien le créer sur Github (logique) puis le +cloner sur ta machine comme je te l’ai montré avant. + + +## Et du coup, comment je met tout ça en ligne ? {#et-du-coup-comment-je-met-tout-ça-en-ligne} + +Bon ok, ce n’est pas aussi simple que ça. Une fois que tu as lié ton dépôt +au dépôt distant, il faudra que tu mettes en ligne tes commits quand tu en +auras l’occasion. Pour ce faire, tu n’as qu’à taper `git push` ; et la +première fois, il faudra que tu indiques à ton dépôt où mettre en ligne +précisément dans le dépôt distant, auquel cas tu ajoutes `-u origin master` +pour cette première fois. Git te demandera donc tes identifiants Github pour +pouvoir mettre tout ça en ligne. + +```text +$ git push -u origin master +Username for 'https://github.com': phundrak +Password for 'https://phundrak@github.com': +Enumerating objects: 10, done. +Counting objects: 100% (10/10), done. +Delta compression using up to 8 threads +Compressing objects: 100% (7/7), done. +Writing objects: 100% (10/10), 940 bytes | 313.00 KiB/s, done. +Total 10 (delta 0), reused 0 (delta 0) +remote: +remote: Create a pull request for 'master' on GitHub by visiting: +remote: https://github.com/Phundrak/temporary-repo/pull/new/master +remote: +To https://github.com/Phundrak/temporary-repo.git + * [new branch] master -> master +Branch 'master' set up to track remote branch 'master' from 'origin'. +``` + +Bon, là en nom d’utilisateur il y a le mien, faudra remplacer avec le tiens. +Et ouais, ma vitesse de mise en ligne n’est pas fameuse, je suis sur une +connexion 3G+ à l’heure où j’écris ces lignes, ne me juge pas. Bref, +toujours est-il que je viens de mettre en ligne les fichiers du dépôt sur +Github. Pas la peine de chercher le mien sur Github par contre, ça fera un +bail que je l’aurai supprimé au moment où tu liras ces lignes. + +Pour info, tu peux éviter d’avoir à taper ton identifiant et ton mot de +passe à chaque fois que tu fais un push sur ton dépôt si tu indiques à +Github ta clef SSH. Tu auras plus d’informations là (c’est à peu près la +même merde pour Gitlab, Gitea et Cie). + + +## Quelqu’un a fait des modifications depuis mon dernier commit, je récupère ça comment ? {#quelqu-un-a-fait-des-modifications-depuis-mon-dernier-commit-je-récupère-ça-comment} + +Pour faire un exemple, je viens de créer un `README.md` sur Github +directement. Ce type de fichiers est assez standard afin de présenter plus +ou moins en détails le dépôt et le projet qui y est lié, et son contenu +apparaîtra formaté sur la page du dépôt sur Github s’il est au format `.md` +(Markdown) ou `.org` (org-mode, le Markdown d’Emacs avec lequel est écrit ce +tutoriel, et qui est clairement supérieur à Markdown). Mais il n’est pas +présent dans mon dépôt local, du coup je vais devoir le récupérer. On va +donc entrer git pull. + +```text +$ git pull +remote: Enumerating objects: 4, done. +remote: Counting objects: 100% (4/4), done. +remote: Compressing objects: 100% (3/3), done. +remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 +Unpacking objects: 100% (3/3), done. +From https://github.com/Phundrak/temporary-repo + 4380d87..8bd4896 master -> origin/master +Updating 4380d87..8bd4896 +Fast-forward + README.md | 2 ++ + 1 file changed, 2 insertions(+) + create mode 100644 README.md +``` + + +## Je suis en train de travailler sur le même fichier que Ginette {#je-suis-en-train-de-travailler-sur-le-même-fichier-que-ginette} + +Là, c’est un problème qui aurait pu être évité avec l’usage des branches +dont je t’avais parlé plus haut, mais visiblement, vous êtes sur la même +branche. Pas bien. Dans ce cas-là, met-toi d’accord avec Ginette pour savoir +qui fait ses push en premier. Si le choix tombe sur Ginette, ou si elle a +imposé sa vision des choses et a fait son push avant toi, Github va râler +car tu n’es pas à jour. Dans ce cas ne panique pas, si tu n’as pas fait tes +commits, lance la commande `git stash` ; ça va sauvegarder tes modifications +dans un coin à part et va annuler tes modifications. + + +## Github ne veut pas de mes pushs sur le dépôt de Gilberte, oskour ! {#github-ne-veut-pas-de-mes-pushs-sur-le-dépôt-de-gilberte-oskour} + +Du calme Jean-Célestin. Cela veut tout simplement dire que tu n’as tout +simplement pas les droits d’écriture sur son dépôt. Du coup, soit tu peux +lui demander directement à ce qu’elle te donne les droits d’écriture si elle +a confiance en toi, soit tu peux créer un fork puis une pull-request sur +Github depuis ton fork où tu auras fait tes modifications. + + +## Fork ? Pull request ? Que font des fourchettes et des pulls dans ce tuto ? {#fork-pull-request-que-font-des-fourchettes-et-des-pulls-dans-ce-tuto} + +Ouhlà Billy, il va falloir remettre les choses au clair. Là il s’agit de +quelque chose de spécifique à Github qu’à Git (d’où le fait qu’on en discute +dans ce chapitre que le précédent). + +Sur Github, il est possible de copier vers ton profil le dépôt de quelqu’un +d’autre dans l’état où il est au moment du fork. Cela inclus les fichiers du +`master`, mais également de toutes les branches du dépôt. Tu peux y penser +en terme de super-branche dont tu deviens le propriétaire. Tu peux ainsi +travailler comme bon te semble sur le code source sans que son propriétaire +ne vienne t’engueuler car tu es en train de polluer sa base de code. + +Si jamais il y a une modification dont tu es particulièrement fier, tu peux +la soumettre au propriétaire du dépôt original (et à ses modérateurs et +contributeurs s’il y en a) via ce qu’on appelle une pull-request. Cela +signifie donc que tu demandes l’autorisation d’ajouter des commits à la base +de code, et ces commits peuvent être lus et commentés par le propriétaire ou +les modérateurs. Il peut y avoir une discussion entre toi et les autres +personnes qui ont leur mot à dire, le code peut être temporairement refusé, +auquel cas tu peux reproposer de nouveau commits sur la même pull-request +jusqu’à ce que ton code soit définitivement accepté ou refusé. Dans tous les +cas, cela mènera à la fermeture de ta pull-request, et tu pourras fièrement +annoncer que tu as participé à un projet sur Github, ou bien avouer avec +toute la honte du monde qu’il a été refusé. + + +## J’ai remarqué un bug ou une erreur, mais je ne peux pas corriger ça moi-même {#j-ai-remarqué-un-bug-ou-une-erreur-mais-je-ne-peux-pas-corriger-ça-moi-même} + +Eh bien dans ce cas-là, ouvre une _issue_ Bernadette ; _issue_ qui en +français veut dire _problème_. Il s’agit d’un système de Github te +permettant de signaler quelque chose aux propriétaires du dépôt, il peut +s’agir d’un bug, d’une demande de fonctionnalité ou de proposition de +modification d’autres fonctionnalités. Cela peut donner lieu à des +discussions menant à la compréhension du bug, ou à une amélioration de ta +proposition. + +Si tu soumets un bug, avant d’ouvrir une nouvelle issue, assure-toi de bien +savoir comment le bug se produit et peut se reproduire. Est-ce que le bug +apparaît si tu utilise ou ouvre le logiciel d’une autre façon ? Est-ce que +le bug apparaît ailleurs ? Est-tu sûr que le bug soit un bug ? Et si tu +décides de le partager, assure-toi de partager un maximum d’information et +tout ce que tu sais sur ce bug, en particulier les étapes et conditions pour +le reproduire. + + +## Les raccourcis et paramètres de Git {#les-raccourcis-et-paramètres-de-git} + +Comme j’en avais parlé plus haut, il est possible de configurer git de façon +un peu plus poussée que simplement déclarer notre nom et notre adresse +e-mail dans notre `~/.gitconfig`. Il est par exemple possible de déclarer +notre éditeur texte préféré, notre navigateur par défaut ou bien même des +raccourcis qui pourront t’être bien utile. Ci dessous je te met une partie +de mon fichier de configuration avec quelques-unes de mes préférences et pas +mal de mes alias. + +```toml +[core] + editor = emacsclient -c + whitespace = fix,-indent-with-non-tab,trailing-space +[web] + browser = firefox +[color] + ui = auto +[alias] + a = add --all + c = commit + cm = commit -m + cam = commit -am + co = checkout + cob = checkout -b + cl = clone + l = log --oneline --graph --decorate + ps = push + pl = pull + re = reset + s = status + staged = diff --cached + st = stash + sc = stash clear + sp = stash pop + sw = stash show +``` + +`a` +: Permet d’ajouter d’un coup tout nouveau fichier d’un dépôt en + préparation au commit. On peut faire la même chose avec `git add .` si on + est à la racine du dépôt. + +`c` +: Un raccourci pour commit, ça permet d’éviter quelques frappes de + clavier d’écrire `git c` plutôt que `git commit`. + +`cm` +: De même pour `cm` qui évite de devoir écrire `commit -m`. On n’a + plus qu’à écrire directement le message de commit après `cm`. + +`cam` +: Non, ce n’est pas un plan, c’est le même alias que `cm` mais qui + en plus met automatiquement tous les fichiers modifiés ou supprimés, donc + s’il n’y a pas de nouveau fichier à ajouter, même pas besoin de passer par + un `git a` avant le `git cam "j’aime les pâtes"`. + +`co` +: Pour aller plus vite quand on veut écrire `checkout`. + +`cob` +: Et pour en plus rajouter le flag `-b` pour la création d’une + nouvelle branche. + +`cl` +: Pour quand tu voudras télécharger ce tutoriel en tapant `git cl + https://github.com/Phundrak/tutoriel-git.git` plutôt que `git clone + https://github.com/Phundrak/tutoriel-git.git`. + +`l` +: Te permet d’avoir le log un peu plus sympa et compact dont j’avais + parlé plus haut. + +`ps` +: Pour faire un push plus rapidement. + +`pl` +: Et pour télécharger les derniers commits sur le dépôt plus + rapidement. + +`re` +: Pour réinitialiser plus rapidement. + +`s` +: Pour rapidement savoir où tu en es dans ton dépôt, savoir ce qui a + été modifié, ajouté, supprimé, déplacé, tout ça… + +`staged` +: Eh oui, Git n’a pas de fonction dédiée pour lister les + fichiers en staging, du coup la voilà. + +`st` +: Pour sauvegarder tes modifications sur le stash plus rapidement. + +`sc` +: Pour supprimer ton stash plus rapidement. + +`sp` +: Pour rétablir le stash sur la branche courante plus rapidement. + +`sw` +: Pour rapidement savoir ce qu’il y a sur le stash. + + +## Et c’est tout ? {#et-c-est-tout} + +C’est déjà pas mal ! Mais non, ce n’est certainement pas tout. Cependant, ce +tutoriel n’a pour but de t’apprendre que les bases de Git et de Github, pas +de tout t’apprendre ! Si tu souhaites aller plus loin, connaître plus de +commandes (comme `git blame` ou `git reset`), ou bien connaître plus +d’options, je ne peux que t’inviter à aller te documenter par toi-même sur +le site de Git qui se trouve ici, ou bien à consulter des pages de manuel +dans ton terminal via `man git`, `man git-apply` ou `man git-cherry-pick` +(oui, il faut lier `git` et le nom de la commande par un tiret d’union). + +Si jamais tu as une question, n’hésite pas à m’envoyer un mail à +[lucien@phundrak.com](mailto:lucien@phundrak.com). Si jamais tu trouves une erreur dans ce que je viens de +dire dans ce tutoriel, ou si tu as une suggestion, c’est justement le moment +de mettre en pratique ce que tu as lu un peu plus haut et d’ouvrir une issue +sur Github sur le [dépôt de ce tutoriel](https://github.com/Phundrak/tutoriel-git). + +
+
+ + +
+ +
diff --git a/publish b/publish index 0576cce..95e875e 100755 --- a/publish +++ b/publish @@ -2,7 +2,7 @@ printf "###############################################################################\n" printf "# Compiling blog #\n" printf "###############################################################################\n" -hugo -D +hugo printf "###############################################################################\n" printf "# Uploading blog #\n" printf "###############################################################################\n"