22
0
Fork 0
wiki/HowtoGit.md

753 lines
19 KiB
Markdown
Raw Normal View History

2016-12-17 21:06:03 +01:00
---
categories: git
title: Howto Git
...
* Documentation: <https://git-scm.com/doc>
* À lire : <https://progit.org/>
* À voir : <https://youtu.be/4XpnKHJAok8>
2016-12-18 01:07:31 +01:00
[Git](https://git-scm.com/) est un logiciel de gestion de code source, créé en 2005 par Linus Torvalds.
2016-12-17 21:06:03 +01:00
## Installation
~~~
2016-12-20 23:35:24 +01:00
# apt install git gitg
2016-12-17 21:06:03 +01:00
~~~
2016-12-20 23:35:24 +01:00
Configuration minimale via `~/.gitconfig` :
2016-12-17 21:06:03 +01:00
~~~
[user]
2016-12-20 23:35:24 +01:00
name = John Doe
2016-12-17 21:06:03 +01:00
email = jdoe+git@example.com
[pull]
rebase = true
[push]
default = simple
[core]
editor = vim
2016-12-17 21:06:03 +01:00
~~~
## Commandes de base
2016-12-20 23:35:24 +01:00
### Utilisation et pages de manuel
2016-12-18 01:12:24 +01:00
2016-12-20 23:35:24 +01:00
Les commandes Git s'utilisent sous la forme `git <commande> [options]`
Pour chaque commande, une page de manuel *git-<commande>* est disponible. Par exemple pour `git add` faire `man git-add`.
2016-12-18 01:12:24 +01:00
2016-12-17 21:06:03 +01:00
### Créer un dépôt
~~~{.bash}
$ mkdir foo
$ cd foo
$ git init
~~~
2016-12-18 01:01:05 +01:00
### Cloner un dépôt
2016-12-17 21:06:03 +01:00
2016-12-20 23:35:24 +01:00
Plusieurs méthodes d'accès pour récupérer un dépôt : ssh://, http(s)://, git://, file:// etc.
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git clone ssh://git.example.com/path/projet.git
2016-12-17 21:06:03 +01:00
$ git clone https://git.example.com/path/projet
$ git clone git://git.example.com/path/projet.git
$ git clone file:///path/projet
~~~
### Travailler sur un dépôt local
Ajouter un nouveau fichier :
~~~{.bash}
$ touch main.c
$ git add main.c
$ git commit -v
~~~
Modification d'un fichier existant :
~~~{.bash}
$ vi main.c
$ git add main.c
$ git commit -v
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
2016-12-20 23:35:24 +01:00
*Note* : si l'on souhaite faire un commit de l'ensemble des fichiers modifiés (et suivis) par git, on peut utiliser la commande `git
commit -a` sans avoir à utiliser `git add`. Néanmoins c'est une habitude à éviter car on risque d'inclure dans le commit des modifications non souhaitées.
2016-12-17 21:06:03 +01:00
Voir l'état du dépôt local (fichiers non commités, etc.) :
~~~{.bash}
$ git status
2016-12-20 23:35:24 +01:00
$ git status -s -b
2016-12-17 21:06:03 +01:00
~~~
Voir les derniers commits du dépôt local :
~~~{.bash}
$ git log
~~~
2016-12-20 23:35:24 +01:00
### pull/push avec un dépôt distant
2016-12-17 21:06:03 +01:00
Si l'on a cloné un dépôt existant, un lien est automatiquement créé entre le dépôt local créé et le dépôt distant (référencé comme *origin*).
Pour récupérer en local les derniers changements du dépôt distant :
~~~{.bash}
$ git pull --rebase origin
~~~
*Note* : l'option `--rebase` est désormais le défaut mais par pédagogie on conseille de la mettre explicitement.
Pour envoyer ses modifications locales vers le dépôt référencé comme distant :
~~~{.bash}
$ git push origin
~~~
### Gestion des branches
Par défaut, certains outils utilisent une branche nommée *master*.
Cette branche existe donc souvent au sein d'un dépôt, mais il faut
garder en tête que c'est une convention, rien n'oblige à en avoir une.
2016-12-17 21:06:03 +01:00
Lister les branches existantes et connaître sa branche courante :
~~~{.bash}
$ git branch -a
~~~
2016-12-20 23:35:24 +01:00
Passer d'une branche à une autre dans son dépôt local :
2016-12-17 21:06:03 +01:00
~~~{.bash}
2016-12-20 23:35:24 +01:00
$ git checkout myfeature
$ git checkout master
2016-12-17 21:06:03 +01:00
~~~
2016-12-20 23:35:24 +01:00
Créer une branche *myfeature* à partir de la branche *master* :
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git checkout master
2016-12-20 23:35:24 +01:00
$ git branch myfeature master
2016-12-17 21:06:03 +01:00
~~~
2016-12-20 23:35:24 +01:00
Travailler sur la branche *myfeature* puis [merger](#git-merge) son travail dans la branche *master* :
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git checkout master
$ git merge --no-ff myfeature
~~~
Pousser une branche locale vers le dépôt référencé comme distant :
~~~{.bash}
2016-12-18 01:01:05 +01:00
$ git push origin myfeature
2016-12-17 21:06:03 +01:00
~~~
2016-12-18 01:01:05 +01:00
Supprimer une branche locale et distante :
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git branch -d myfeature
$ git push origin :myfeature
~~~
## Commandes avancées
2016-12-18 01:01:05 +01:00
### Afficher l'historique
Affichage de l'historique de différentes façons :
~~~{.bash}
$ git log
$ git log -p
$ git log --stat
$ git log --summary
$ git log --color
$ git log --graph
$ git log --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
~~~
On peut notamment combiner toutes ces options dans un alias à mettre dans `.gitconfig` :
~~~
[alias]
2016-12-18 00:10:01 +01:00
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
~~~
2016-12-20 23:35:24 +01:00
On peut aussi utiliser *whatchanged* qui va lister tout ce qui a changé :
~~~{.bash}
$ git whatchanged
$ git whatchanged -p
~~~
2016-12-20 23:35:24 +01:00
Voir l'avant-dernier commit :
~~~{.bash}
$ git show HEAD~1
~~~
2016-12-20 23:35:24 +01:00
Voir le fichier *foo/bar* tel qu'il était dans l'avant-dernier commit :
~~~{.bash}
$ git show HEAD~1:foo/bar
~~~
Pour voir ce qu'il s'est passé entre deux commits :
~~~{.bash}
$ git show HEAD~8..HEAD
$ git show -p HEAD~8..HEAD
~~~
2016-12-20 23:35:24 +01:00
On peut voir graphiquement l'historique avec différents outils, par exemple *gitg* ou *gitk* :
~~~
# apt install gitk gitg
2016-12-20 23:35:24 +01:00
$ gitg
$ gitk --all
~~~
2016-12-17 21:06:03 +01:00
### Modifier l'historique
2016-12-20 23:35:24 +01:00
/!\\ Les modifications de l'historique ne doivent avoir lieu que si cela n'a pas été pushé vers un dépôt partagé !
2016-12-17 21:06:03 +01:00
Modifier son dernier message de commit :
~~~{.bash}
$ git commit --amend
~~~
Modifier son dernier commit :
~~~{.bash}
$ vi main.c
$ git add main.c
$ git commit --amend
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
Modifier son avant-dernier commit :
~~~{.bash}
$ git rebase -i HEAD^^
2016-12-22 14:29:13 +01:00
… remplacer « pick » par « edit » pour le commit à modifier
2016-12-17 21:06:03 +01:00
$ vi main.c
$ git add main.c
$ git commit --amend
$ git rebase --continue
~~~
*Note* : On peut remonter au Nième commit en utilisant *HEAD~N*
### Picorer un commit d'une autre branche (cherry-pick)
2016-12-17 21:06:03 +01:00
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-cherry-pick>
Récupérer un commit d'une autre branche dans master :
2016-12-18 01:01:05 +01:00
~~~{.bash}
2016-12-20 23:35:24 +01:00
$ git checkout master
2016-12-17 21:06:03 +01:00
$ git cherry-pick <SHA1 du commit>
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### gitignore
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/gitignore>
2016-12-17 21:06:03 +01:00
Créer un fichier `.gitignore` à la racine pour ignorer certains fichiers/chemins :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~
$ cat .gitignore
test.php
htdocs/foo/bar
2016-12-20 23:35:24 +01:00
foo/bar*
2016-12-17 21:06:03 +01:00
~~~
2016-12-22 14:30:17 +01:00
*Note* : le fichier `.gitignore` se commit dans le dépôt
2016-12-17 21:06:03 +01:00
### Ranger temporairement son travail (git stash)
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-stash>
2016-12-22 14:29:13 +01:00
Cela permet d'avoir un buffer pour mettre « en pause » des modifications non commitées :
2016-12-17 21:06:03 +01:00
~~~{.bash}
…hack…hack…
$ git stash save
~~~
On peut lister ce buffer :
~~~{.bash}
$ git stash list
stash@{0}: WIP on dev: fb1fa70… m
stash@{1}: WIP on dev: fb1fa70… m
~~~
Et ré-appliquer les modifications stockées :
~~~{.bash}
$ git stash apply stash@{0}
~~~
Pour purger le buffer sans l'appliquer :
~~~{.bash}
$ git stash clear
~~~
### git diff
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-diff>
Voir les modifications locales non commitées et non stagées :
~~~{.bash}
$ git diff
~~~
2016-12-20 23:35:24 +01:00
Voir les modifications locales *suivies* (ajoutées avec *git add*) :
~~~{.bash}
$ git diff --cached
~~~
Voir les modifications entre deux commits, ou entre deux branches :
~~~{.bash}
$ git diff HEAD^ HEAD
$ git diff HEAD~8 HEAD^^
$ git diff myfeature master
~~~
2016-12-22 14:29:13 +01:00
*Note* : si le 2ᵉ commit est *HEAD* on peut ne pas le mentionner, `git diff HEAD^` montrera les modifications du dernier commit
2016-12-20 23:35:24 +01:00
Voir les modifications entre deux commits, mais uniquement pour un fichier *foo* :
2016-12-20 01:50:15 +01:00
~~~{.bash}
$ git diff HEAD~8..HEAD^^ -- foo
~~~
Avoir un diff inversé (pratique pour faire préparer un revert partiel par exemple) :
~~~{.bash}
$ git diff -R
~~~
2016-12-20 23:35:24 +01:00
### git pull/fetch
<https://git-scm.com/docs/git-pull>
`git pull` est une commande qui effectue un rapatriement des données (`git fetch`) puis l'intégration de ces données via `git rebase` (par défaut) ou `git merge`.
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-fetch>
Dans certains cas il est pratique de faire un simple `git fetch`, notamment si l'on veut faire des manipulations complexes ou si l'on veut avoir toutes les données pour travailler hors ligne sans rien changer à l'état actuel de sa *working copy*.
### git push
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-push>
Pousser toutes ses branches d'un coup (ce qui est déconseillé en général) :
~~~{.bash}
$ git push --all origin
~~~
2016-12-20 23:35:24 +01:00
Si l'on a une branche locale nommée *foo* et que l'on veut la pousser dans la branche nommée *bar* du dépôt distant :
~~~{.bash}
$ git push origin foo:bar
~~~
/!\\ Attention, il ne faut jamais modifier un historique qui a été pushé vers un dépôt partagé. Néanmoins dans certaines situations exceptionnelles (un mot de passe ou un email qui aurait été mis par erreur) on peut être amené à faire un `push --force` :
~~~{.bash}
$ git push -f origin
~~~
2016-12-20 23:35:24 +01:00
Il faudra ensuite que chaque utilisateur du dépôt soit prévenu et accepte d'écraser leur dépôt local (en faisant ou vérifiant les modifications d'historiques) :
~~~{.bash}
$ git fetch
$ git reset origin
~~~
### git checkout
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-checkout>
Pour avoir le dépôt tel qu'il était à un commit :
~~~{.bash}
$ git checkout <SHA1 du commit>
~~~
2016-12-22 14:29:13 +01:00
Pour se remettre sur la version courante :
~~~{.bash}
$ git checkout master
~~~
2016-12-18 01:34:27 +01:00
Pour créer une branche et switcher directement dans cette nouvelle branche, on utilise l'option `-b` :
~~~{.bash}
$ git checkout -b myfeature
~~~
Pour annuler toutes les modifications d'un fichier foo/ non stagé :
~~~{.bash}
$ git checkout foo/
~~~
### git branch
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-branch>
Une branche est en fait la création une déviation, un commit qui a deux *enfants*.
On peut ainsi créer une branche à partir de n'importe quel commit :
~~~{.bash}
$ git branch newbranch e150b8517a694a2d4816cff95ef612086d644f67
~~~
Pour supprimer la branche *foo* sur un dépôt distant non cloné :
~~~{.bash}
$ git push ssh://git.example.com/projet.git :foo
~~~
Pour récupérer une nouvelle branche depuis le dépôt référencé comme distant :
~~~{.bash}
$ git remote update
~~~
2016-12-20 23:35:24 +01:00
### git reset/clean
<https://git-scm.com/docs/git-reset>
<https://git-scm.com/docs/git-clean>
/!\\ Certaines commandes peuvent provoquer une perte de données !
Pour supprimer toutes les modifications non commitées et les fichiers/répertoires non trackés :
~~~{.bash}
$ git reset --hard
$ git clean -f -d
~~~
2016-12-20 23:35:24 +01:00
On peut aussi `git reset` sur des commits précédents (*HEAD^*,*HEAD~N*,*<SHA1 du commit>*).
Ou même sur une branche distante comme *origin/master* par exemple (ce qui est pratique si l'historique de la branche distante a été modifié).
### git add
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-add>
Pour ajouter tout un répertoire et son contenu :
~~~{.bash}
$ git add foo/
~~~
Pour choisir ce que l'on veut ajouter pour le prochain commit :
~~~{.bash}
$ git add -p
~~~
### git merge
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-merge>
Un merge consiste à créer un commit qui aura deux parents, et permet ainsi de fusionner deux branches existantes.
2016-12-22 14:29:13 +01:00
Quand un merge est très simple, cest-à-dire que cela rajoute simplement des commits sur une branche qui n'a pas bougé entre temps, on n'a pas besoin de créer un commit pour fusionner, on appelle cela un merge **fast-forward**. Cela se fait automatiquement avec la commande `git merge`. Notons que l'on peut vouloir tout de même avoir un commit pour marquer le coup et forcer un commit de merge avec l'option `git merge --no-ff`.
Quand un merge n'est pas simple, Git peut adopter plusieurs stratégies (resolve, recursive, ours, theirs, patience, etc.). Il est probable que cela génère des conflits qui devront être résolus manuellement.
### git apply
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-apply>
`git apply` permet d'appliquer un diff.
On peut utiliser une option pour exclure l'application de certain fichier du diff :
~~~{.bash}
$ git apply --exclude=debian/changelog /tmp/foo.diff
~~~
### git blame
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-blame>
Pour voir qui a modifié les lignes d'un fichier *foo/bar* :
~~~{.bash}
$ git blame foo/bar
~~~
### .git/config
2016-12-20 23:35:24 +01:00
<https://git-scm.com/docs/git-config>
La configuration d'un dépôt se trouve dans le fichier `.git/config`
On peut éditer ce fichier ou utiliser des commandes pour le faire.
Pour ajouter un dépôt distant :
~~~{.bash}
$ git remote add origin2 ssh://git.example.com/path/projet.git
~~~
Pour lister les dépôts distants configurés :
~~~{.bash}
$ git remote
~~~
2016-12-22 14:29:13 +01:00
### Échanger des commits sous forme de patchs Git
2016-12-17 21:06:03 +01:00
Pour transmettre ses 3 derniers commits, on peut générer 3 patches qui contiendront les diffs ainsi que les messages de commit :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git format-patch -3
~~~
Si l'on a ces 3 patches, on peut les appliquer sur son dépôt local ainsi :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git am 000*.patch
~~~
2016-12-18 01:01:05 +01:00
### hooks
On peut gérer des hooks à différents moments (pre-commit, post-commit, pre-push, post-push, etc.),
par exemple pour générer des emails de notification.
Voir dans le répertoire `.git/hooks/`.
2016-12-22 14:29:13 +01:00
### dépôt « bare »
2016-12-22 14:29:13 +01:00
Un dépôt classique possède un répertoire `.git/` qui contient toutes les données et méta-données, ainsi qu'une *working copy* de la branche courante.
Quand on crée un dépôt ayant vocation à servir de dépôt central, il est préférable de ne pas avoir de *working copy* : il s'agira alors d'un **bare repository** que l'on peut initier avec la commande :
~~~{.bash}
$ mkdir foo
$ cd foo
$ git init --bare
~~~
2016-12-17 21:06:03 +01:00
## Workflow de travail
Il existe plusieurs workflows possibles en travaillant avec Git.
### Le modèle Git branching
Voir <http://nvie.com/posts/a-successful-git-branching-model/>
2016-12-20 23:35:24 +01:00
L'idée est de ne jamais toucher à *master*, sauf hotfixes. Pour le reste on le fait dans *dev*.
2016-12-17 21:06:03 +01:00
Et pour les grosses features on le fait dans une branche, nommée avec le nom de la feature.
## Plomberie
<https://git-scm.com/book/fr/Git-Commands-Plumbing-Commands>
La plomberie de Git consiste à réaliser des commandes bas niveau
manipulant tout ce qui se trouve dans le répertoire `.git/` d'un dépôt.
2016-12-18 00:13:47 +01:00
Les données brutes sont dans le répertoire `.git/objects/` qui contient
de nombreux fichiers : à chaque commit correspond un fichier nommé en fonction
de l'empreinte SHA1 du commit et contenant les données compressées.
Les données comprennent notamment la référence au(x) commit(s) *parent*
2016-12-22 14:29:13 +01:00
ce qui permet davoir des liens entre les commits.
2016-12-18 00:13:47 +01:00
Observons `.git/refs/` qui contient des pseudos-pointeurs (fichier texte d'une seule ligne contenant un SHA1 ou une autre référence) :
2016-12-20 01:59:43 +01:00
2016-12-18 00:13:47 +01:00
* un tag est simplement un pointeur vers un commit ;
* une branche est également un pointeur vers un commit, la différence est qu'il se déplace à chaque nouveau commit dans la branche.
Directement dans `.git/` on a également *HEAD* (et *FETCH_HEAD*, *ORIG_HEAD*) qui sont aussi des pseudo-pointeurs, qui changent notamment quand on change de branche ou pendant un *rebase*.
Si l'on veut mettre à jour ces pseudo-pointeurs, il faut utiliser `git update-ref`.
Observons `.git/logs/` qui contient l'historique de ce qui a été fait dans le dépôt.
Cet historique est notamment accessible avec la commande `git reflog`.
2016-12-17 21:06:03 +01:00
## Astuces diverses
### Partager un dépôt avec plusieurs utilisateurs
2016-12-22 14:29:13 +01:00
Avec un dépôt *foo* existant, on autorisera les utilisateurs que sils appartiennent au groupe *git* :
2016-12-17 21:06:03 +01:00
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
# cd foo
# git config core.sharedRepository group
# addgroup git
# chgrp -R git .
# chmod g=rwXs,o= -R .
# chmod g=rwX -R . # astuce pour garder le +s sur les répertoires
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### Importer un dépôt SVN dans GIT
2016-12-22 14:29:13 +01:00
Ce script permet de récupérer la liste des auteurs SVN, modifiez-la comme voulu.
2016-12-17 21:06:03 +01:00
2016-12-18 01:01:05 +01:00
~~~{.bash}
2016-12-17 21:06:03 +01:00
#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
echo "${author} = Prenom Nom <jdoe@example.com>";
done
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
On lance ensuite la commande suivante :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git svn --authors-file=path/to/authors_file clone svn+ssh://svn.example.com/path/to/repo
~~~
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
### Importer un dépôt CVS dans GIT
Lancer la commande suivante :
~~~{.bash}
$ git cvsimport -C repo_git -r cvs -k -vA path/to/authors_file -d user@hostname:/path/to/cvsroot repo
~~~
### Importer un dépôt Arch dans GIT
Lancer la commande suivante :
~~~{.bash}
$ git-archimport -v foo@arch.example.com--branch
~~~
2016-12-17 21:06:03 +01:00
### Convertir un dépôt en utf8
Créer un fichier exécutable dans `/tmp/recode-all-files` :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~{.bash}
#!/bin/sh
find . -type f -print | while read f; do
mv -i "$f" "$f.recode.$$"
iconv -f iso-8859-1 -t utf-8 < "$f.recode.$$" > "$f"
rm -f "$f.recode.$$"
done
~~~
Puis exécuter la commande suivante dans votre dépôt :
~~~{.bash}
$ git filter-branch --tree-filter /tmp/recode-all-files HEAD
~~~
Exécuter ensuite la commande suivante pour convertir les messages de commit :
~~~{.bash}
$ git filter-branch --msg-filter 'iconv -f iso-8859-1 -t utf-8' -- --all
~~~
### Push vers un non-bare repository
Ceci est évidemment déconseillé, car cela mettra aussi à jour les fichiers, ce qui nécessite
de faire un `git reset --hard`. Mais si l'on veut tout de même le forcer :
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
$ git push
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 618 bytes, done.
Total 4 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
2016-12-18 01:01:05 +01:00
remote: error:
2016-12-17 21:06:03 +01:00
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
2016-12-18 01:01:05 +01:00
remote: error:
2016-12-17 21:06:03 +01:00
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
! [remote rejected] master -> master (branch is currently checked out)
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
2016-12-22 14:29:13 +01:00
Il faut ajouter dans la config du repository « distant » :
2016-12-17 21:06:03 +01:00
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
[receive]
denyCurrentBranch = warn
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### Transformer un non-bare repository en bare repository
2016-12-22 14:30:17 +01:00
Il suffit de supprimer tous les fichiers sauf le `.git`, par exemple :
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ rm -rf *
~~~
Puis d'indiquer dans la config du repository :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~
bare = true
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### Mettre en place des notifications de push
Sous Debian, pour envoyer des notifications par email à git@example.com :
~~~
# chmod a+x /usr/share/doc/git-core/contrib/hooks/post-receive-email
$ cd /path/path/to/your/repository.git
$ ln -sf /usr/share/doc/git-core/contrib/hooks/post-receive-email hooks/post-receive
$ git hooks.mailinglist git@example.com
~~~
Pour recevoir les patches :
2016-12-18 01:01:05 +01:00
2016-12-17 21:06:03 +01:00
~~~{.bash}
$ git config hooks.showrev "git show -C %s; echo
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### Ignorer les vérifications SSL
2016-12-20 23:35:24 +01:00
(à éviter autant que possible bien sûr)
2016-12-18 01:48:34 +01:00
2016-12-20 23:35:24 +01:00
~~~{.bash}
2016-12-17 21:06:03 +01:00
$ git config --global http.sslverify "false"
2016-12-18 01:01:05 +01:00
~~~
2016-12-17 21:06:03 +01:00
### Nettoyage d'un dépôt Git
Quand on supprime des commits, ils ne sont pas vraiment supprimés du dépôt.
Cela offre l'avantage de pouvoir les retrouver en cas de besoin.
Si l'on veut gagner de la place, on peut aussi faire un nettoyage :
~~~{.bash}
$ git repack
$ git gc
~~~
### Migrer un dépot git
2016-12-17 21:06:03 +01:00
Il se peut qu'on change de forge (passage de gitolite à gitlab par
exemple) et il faut alors migrer les dépots. Un moyen de faire :
~~~{.bash}
$ for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do rbranch=$(echo $branch | tr '/' ' ' | awk '{print $3}') ; git checkout -b $rbranch $branch ; done
$ git remote add gitlab gitlab@gitlab.example.com:group/repo.git && git push gitlab --all && git remote remove origin && git remote rename gitlab origin && git push --set-upstream origin master
~~~