technique:git:git_avancees

Ceci est une ancienne révision du document !


Git : fonctionnalités avancées

Pour pouvoir utiliser pleinement Git, il peut être utile de s'approprier la notion de branches. Une branche est une fonctionnalité ou une option que l'on souhaite ajouter et tester sans qu'elle vienne pour l'instant impacter le coeur du projet.

On crée une nouvelle branche au projet, à partir de la branche master

git branch nouvellebranche

On passe sur la branche nouvellebranche

git checkout nouvellebranche

ou plus directement :

git checkout -b nouvellebranche

On peut faire des commits (git add & git commit) sur cette branche. On peut aussi repasser sur la branche principale et en faire d'autres.

git checkout master

Il est aussi possible de venir se placer sur un commit, une branche ou un tag précédent :

git checkout nomcommit
git checkout vieillebranche
git checkout nomtag

(Voir git checkout -h)

On repasse sur la branche master

git checkout master

Et on fusionne la branche souhaitée vers la branche en cours (master)

git merge nouvellebranche

Puis on peut supprimer la branche en cours :

git branch -d nouvellebranche # Si status est à jour
ou
git branch -D nouvellebranche # si pas fusionnée

En cas de merge conflictuel, il faut résoudre le confilt en éditant les fichiers fusionnés qui contiennent les diff.

Il faut éditer les fichiers en conflit et finir avec un :

git add fichiers_en_conflit
git commit

Il est possible d'utiliser des outils comme :

git mergetool fichier_en_conflit

Il est possible de merger sans créer de nouveau commit :

git merge --no-commit nouvellebranche

Puis modifier/corriger les fichiers et enfin d'ajouter et de commiter les changements manuellement

Il est alors aussi possible d'annuler un merge avec un :

git merge --abort

Récupérer un dépot distant avec :

git clone url_distant

Dans ce cas, l'origine du dépot distant est mémorisé dans “origin”.

git fetch permet de récupérer les branches distantes. Attention, git pull <⇒ git fetch

git pull # récupère les sources et merge les différences
git fetch # récupère les sources sans fusionner

git pull = git fetch + git merge FETCH_HEAD

Pour voir les différences avec le dépot distant :

git remote -v
git branch -r # pour voir les branches distantes connues localement
git branch -vv # si la branche loclae est trackée
git remote add nomchoisi urldepot.git

git fetch nomchoisi

Et pour mettre à jour le dépot local vers ce dépot distant :

git push -u nomchoisi master

Attention, il faudra mettre à jour les 2 dépots de manière manuelle. Par exemple :

git push heroku master

git push -u nomchoisi master

1) Ajouter sa clef SSH publique dans son profil du dépot distant (github, framagit…)

2) Définir par défaut l'utilisation de sa clef pour ce type de dépot dans ~/.ssh/config :

Host github.com
 IdentityFile ~/.ssh/id_rsa

3) définir pour le dépot git local que l'accès se fait en ssh dans dossiergit/.git/config et changer l'adresse du dépot distant :

[remote "origin"]
        url = ssh://git@github.com/depotperso/monprojet.git

Et c'est tout. Au prochain git push, la passphrase de la clef sera demandée (sauf si elle est mémorisée dans le ssh-agent).

Cas fréquent : on veut contribuer à un projet existant :

  1. On forke le projet existant depuis la plateforme
  2. On clone ce projet localement sur son PC (git clone)
  3. On crée une nouvelle branche locale de développement (git branch nouvbranche && git checkout nouvbranche)
  4. on ajoute cette branche distante
  5. On modifie le code, on commite (git commit -m “blabla”) et on push à distance (git push)
  6. On retourne sur la plateforme et on crée une PR Pull Request

Problème : que faire si le projet a évolué après, puisque localement on a un clone du fork, mais pas du projet original ?

Il faut définir un dépot upstream du dépot existant :

git remote add upstream git@github.com:nomdepot/nomprojet.git
git fetch upstream # on se calle sur upstream et on affiche les branches disponibles
git checkout master # pour se mettre localement sur la branche master
git reset --hard upstream/master # pour faire un reset local de la branche master

On n'oublie pas de recréer une nouvelle branche pour faire une nouvelle PR :

git checkout -b nouvellebranche

La fois suivante, pour remettre à jour :

git checkout master # pour se mettre localement sur la branche master
git reset --hard upstream/master # pour faire un reset local de la branche master
git fetch upstream

Se placer dans la branche qui contient les anciens commits :

git checkout anciennebranche
git log # pour afficher les commits du plus récent au plus ancien idcommit3, idcommit2, idcommit1
git checkout master # pour repasser dans la branche master
git checkout -b nouvellebranche # pour créer et se placer dans la nouvelle branche
git cherry-pick idcommit1 idcommit2 idcommit3
git log # pour afficher les commits récupérés
git branch --track master origin/master # pour se reconnecter à une branche existante (passer de dev à master)

Editer le .git/config et ajouter son username (avec %40 au lieu de @) et password dans l'URL :

[remote "origin"]
url = https://USERNAME:PASSWORD@code.cemea.org/francois.audirac/raspitv.git

Ceci peut être définié au moment du clone :

git clone https://<USERNAME>:<PASSWORD>@github.com/path/to/repo.git

On peut aussi stocker ces infos dans les credentials (.git-credentials)

git config credential.helper store # pour les activer globalement ou
git config --global credential.helper store # pour les activer localement dans chaque dépot

Et au pull ou push suivant, les infos de connexions sont mémorisées !

git bisect permet de faire ça : Trouver par recherche binaire la modification qui a introduit un bogue. (cf doc git-bisect)

Technique par dichotomie entre 2 commits : l'un avec le bug (bad), l'autre sans le bug (good).

Exemple :

git bisect start # démarrage de git bisect
git bisect bad                 # La version actuelle est mauvaise
git bisect good v2.6.13-rc2 # la version v2.6.13-rc2

Et se laisser guider.

git bisect reset # pour revenir au HEAD d'origine.

Marche aussi avec un script de test qui doit renvoyer 0 pour être valide :

git bisect run mon_script arguments
  • technique/git/git_avancees.1632166633.txt.gz
  • Dernière modification : 2021/09/20 21:37
  • de francoisa