Partager sur :
Facebook,
Twitter
La plupart des opérations, si ce n'est toutes, peuvent être utilisées avec TortoiseGit qui est un gestionnaire intégré à l'explorateur de Windows. Cet outil est un véritable confort parfaitement indispensable pour votre productivité personnelle.
Lorsque vous n'avez pas cet outil, il faut alors connaître les quelques commandes pratiques ci-dessous.
Pour afficher sommairement les dernières modifications :
git log
Pour afficher toutes les opérations en cours et retrouver du code modifié :
git diff
Pour lister les fichiers modifiés :
git diff --name-only
Pour créer un patch collectif dans un fichier transférable vers un autre ordinateur :
git diff > patch.diff
Pour appliquer un patch reçu par fichier :
git apply patch.diff
Pour annuler toutes les modifications en cours, et revenir au dernier commit connu localement :
git reset --hard
Lorsqu'un projet vous plaît sur GitHub, vous en créez un projet dérivé rattaché à votre compte. Via l'interface GitHub, cela revient indirectement à cloner un projet existant et à le pousser vers une nouvelle origine dont vous êtes le propriétaire.
Dans la vie avec ce fork, il se passe que vous repartez de la copie à l'instant T du projet d'origine. Vos commits sont affectés à votre projet dérivé et lorsque vous poussez les modifications sur le serveur, le projet d'origine (en rouge) n'est pas affecté.
Comme le projet d'origine continue sa vie, vous voulez sûrement bénéficier périodiquement des mises à jour. Qu'on se le dise, travailler sur une copie n'a d'intérêt que :
Pour tirer les mises à jour, il faut que votre projet ait 2 sources : celui du projet dérivé évidemment, et celui du projet d'origine dont vous n'êtes pas l'auteur. Éditez localement le fichier .git/config de votre projet dérivé selon le modèle suivant :
[remote "official"] url = https://github.com/exterieur/origine.git fetch = +refs/heads/*:refs/remotes/origin/* [remote "origin"] url = https://github.com/interieur/derive.git fetch = +refs/heads/*:refs/remotes/origin/*
Pour mettre à jour votre copie locale depuis toutes ses sources :
git pull
Pour tirer les modifications depuis le projet d'origine seulement :
git pull -v --progress "official" master
Tant que les données tirées du projet d'origine n'interfèrent pas avec des modifications dérivées, vous pouvez tirer sans problème, car Git reliera les commits entre eux pour garder la consistence.
Vous réalisez des modifications pour le projet d'origine, donc vous créez un pull request pour demander à intégrer votre travail dérivé :
D'abord, poussez vos modifications locales vers le projet dérivé (vous n'avez pas l'écriture pour le projet d'origine) :
git push -v --progress "origin" master:master
La création du pull request se fait sur le site GitHub et vous y mettrez les informations descriptives. Le pull request ne causera pas de problème de fusion si les fichiers modifiés ne l'ont pas été entre temps sur le projet d'origine.
Situation : vous et votre collègue avez créé un commit localement mais seul votre collègue a réussi à le pousser vers le serveur, car il a été le premier à le faire. C'est un cas du travail à plusieurs, car dans une même branche, il ne peut y avoir qu'un seul commit sans successeur : il faut donc créer un merge pour fermer cette structure en Y. Dans l'idéal, il est toujours bon de faire un "git pull" avant de faire son commit, car ça permet de tout gérer directement.
Pushing to https://github.com/ecrucru/demo.git To https://github.com/ecrucru/demo.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://github.com/ecrucru/demo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. git did not exit cleanly (exit code 1)
Et pour ne rien arranger aux choses, il s'agit du même fichier qui est modifié. On commence donc par tirer la modification distante qui génère un conflit à résoudre :
git pull
remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/ecrucru/demo c256ab2..baf51aa master -> origin/master Auto-merging hello.txt CONFLICT (content): Merge conflict in hello.txt Automatic merge failed; fix conflicts and then commit the result.
On identifie les fichiers avec conflit :
git diff --diff-filter=U
diff --cc hello.txt index c183262,8cf2be8..0000000 --- a/hello.txt +++ b/hello.txt @@@ -1,1 -1,1 +1,5 @@@ ++<<<<<<< HEAD +... very nice world ! ++======= + ... nice world ! ++>>>>>>> baf51aafc9d468c29471611399f0df9bf6c999f1
On édite le fichier pour le mettre dans son état final attendu.
On indique que le fichier a été traité :
git add hello.txt
On peut alors faire le commit qui résoud tout. Utilisez ":x" pour sauvegarder l'éditeur Vim/Nano qui s'affiche :
git commit
Puis on pousse vers le serveur :
git push
Pour soumettre plusieurs modifications indépendantes sur GitHub, vous devez utiliser des branches séparées. Ce sont des branches qu'on fusionne entre les projets, pas des commits individuels. Lors de l'opération de commit, vous choisissez à quelle branche la modification se rattache (généralement celle courante).
En présence de plusieurs branches, il faut toujours préciser laquelle est poussée vers le serveur :
git push origin master git push origin branche_2
Pour supprimer une branche locale une fois le PR accepté :
git branch -d branche_2
git branch -D branche_2
Pour supprimer une branche distante qui ne soit pas la branche courante (ça évite de pouvoir tout supprimer) :
git push origin --delete branche_2
Il se peut que la suppression de la branche ne soit pas possible. Dans ce cas, remettez-vous sur la branche principale, puis recommencez :
git checkout master
Git est décentralisé au sens où il vous est possible d'avoir votre arbre de commits pour gérer le code. En poussant vers le serveur, vous publiez uniquement le chemin direct d'une branche nommée. Ainsi, tant que vous ne poussez pas, vous pouvez reculer le curseur de la branche locale, recommitter, puis pousser (le commit annulé restant perdu dans votre copie locale). Faire un amend ne suffit pas, car ça ajoute un commit et cache faussement le précédent.
git reset --hard HEAD~1
Si vous aviez déjà poussé, vous pourrez écraser le serveur en forçant. Mais si quelqu'un avait déjà tiré, vous ne pourrez rien faire sauf lui causer un conflit (à résoudre avec un merge).
git push --force
La trace récente des modifications est visible avec :
git reflog
452c3a0 HEAD@{0}: reset: moving to HEAD~1 ba2d71e HEAD@{1}: commit: Voluntarily bad commit to undo 452c3a0 HEAD@{2}: commit (initial): Initial
git show ba2d71e
commit ba2d71ea3adca2de716af24b589d4c05a029ba45 Author: ecrucru Voluntarily bad commit to undo diff --git a/hello.txt b/hello.txt index a14b2df..5859618 100644 --- a/hello.txt +++ b/hello.txt @@ -1 +1 @@ -... world ! \ No newline at end of file +... bad? world ! \ No newline at end of file
Supposons que nous avons ces commits avec un tag mal placé :
Il faut d'abord supprimer le tag localement :
git tag -d "0.1"
Ensuite, on taggue le commit désiré :
git tag -a "0.1" 5c7d02a
Pour pousser le tag unitairement :
git push origin refs/tags/0.1 --force
Pour pousser les tags collectivement :
git push --tags --force
L'objet release de GitHub n'est pas propre à git, donc il faudra ensuite contrôler le résultat des opérations sur le site web.
Pour exporter le dépôt au format ZIP :
git archive --format zip --output master.zip master
Pour compresser le dépôt local et n'en faire qu'un seul fichier pack, y compris s'il y a des modifications en cours :
git gc
Dernière modification le 18 juillet 2022 à 22:12