====== Git ====== La base de la base, en gros et en français ;) => http://rogerdudler.github.io/git-guide/index.fr.html Un tuto en français qui va bien => https://www.miximum.fr/blog/enfin-comprendre-git/ ===== Installation ===== apt-get install git-core Interface graphique si besoin apt-get install gitk ===== Configuration ===== Première chose à faire, s'identifier. $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com Toute la config global est stocké dans votre répertoire utilisateur dans le fichier **.gitconfig** Pour avoir un peu de couleur git config --global color.ui true Pour définir un éditeur de texte spécifique git config --global core.editor vi Pour avoir un historique plus sympathique, tapez cette ligne pour avoir un aperçu git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit Perso je me suis fait celui la car je fait des commit sur plusieurs lignes et c'est donc plus lisible comme ça git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d %Cgreen(%ci - %cr) %C(bold blue)<%an>%Creset %n%B%Creset' --all Sauvegardez cette commande dans un alias git config --global alias.hist "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d %Cgreen(%ci - %cr) %C(bold blue)<%an>%Creset %n%B%Creset' --all" Ainsi vous n'aurez qu'a taper pour avoir tout l'histoire / ou l'historique d'un fichier git hist git hist nom_du_fichier Et pour avoir le détails des modifications / ou des modifications d'un fichier git hist -p git hist -p nom_du_fichier Pour voir les fichiers ajoutés, modifiés, supprimés git hist --name-status Pour voir les fichiers avec les + et - git hist --stat Plus de personnalisation sur => http://git-scm.com/book/fr/Personnalisation-de-Git-Configuration-de-Git et, **très important**, forcer le rebase lorsque l'on fait un pull pour éviter les merge et avoir un historique propre git config --global pull.rebase true Pour avoir un prompt sympa qui affiche votre branche et l'état de votre dépôt. * https://github.com/magicmonty/bash-git-prompt ===== Interface graphique ===== **gitg** ou **giggle** semble correcte. Une liste complète * https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Graphical_Interfaces Un outils à installer avec npm, ungit * https://github.com/FredrikNoren/ungit ===== Le principe git ===== FIXME Un modèle de branche pour le dev => http://nvie.com/posts/a-successful-git-branching-model/ Le même modèle traduit en français => https://www.occitech.fr/blog/2014/12/un-modele-de-branches-git-efficace/ ===== Quelques commandes utiles ===== L'essentiel => http://wiki.spheredev.org/Git_for_the_lazy Voir ou on en est git status Voir les différences entre le dernier commit et les modifications en cours git diff Voir les différences entre 2 branches git diff branch1..branch2 Voir les différences d'un fichier entre 2 branches git diff branch1..origin/master fichier Ou si vous êtes sur la branch1 et que vous voulez comparer votre fichier avec le origin/master (le master du dépôt) git diff ..origin/master fichier Voir les modifications faites par le dernier commit git show ou par un commit spécifique git show euioeoe Faire un commit vite fait git commit -a -m 'vite fait' Ajouter au commit tous les fichiers modifiés suivi et non suivi 'untracked' git add . Ajouter au commit seulement les fichiers suivi git add -u **Le git reset** Revenir à l'état d'un commit tout en gardant vos modification local en unstage git reset git reset --mixed Revenir à l'état d'un commit tout en gardant vos modification local en stage git reset --soft Revenir à l'état d'un commit en supprimant toutes vos modifications en local !! (pas de retour possible !!!) git reset --hard Enlever un fichier du commit ou plutot, désindexer un fichier git reset lefichier équivalent de git reset --mixed HEAD lefichier Annuler le dernier commit non encore propagé (n'affecte pas le contenu des fichiers, fait comme si vous n'aviez pas fait git commit) git reset HEAD^ Annuler votre dernier commit non propagé (supprime vos modifications et le dernier commit). git reset --hard HEAD^ Le **git revert** (pas de perte d'historique) Pour annuler un commit en particulier. Crée un nouveau commit git revert Pour annuler un commit sur un fichier en particulier git revert Plus d'info sur git reset => https://git-scm.com/book/fr/v2/Utilitaires-Git-Reset-d%C3%A9mystifi%C3%A9 Supprimer les modifications faite sur un fichier git checkout -- nom_du_fichier Modifier le message du dernier commit git commit --amend Si vous avez déjà pushé votre commit sur origin/master git commit --amend git push -f Sauf que maintenant sur la prod vous avez un message du style $ git status Sur la branche master Votre branche et 'origin/master' ont divergé, et ont 1 et 1 commits différents chacune respectivement. (utilisez "git pull" pour fusionner la branche distante dans la vôtre) rien à valider, la copie de travail est propre Utilisez alors la commande git reset --hard origin/master ==== Les branches ==== Voir les branches git branch === Création === Créer une branche git checkout -b nom_de_la_nouvelle_branche ou git branch nom_de_la_nouvelle_branche git checkout nom_de_la_nouvelle_branche Note : si vous avez des modifications en cours avant de créer une branche, elles seront dispo sur les 2 branches (master et la nouvelle). Commité vos modifs sur la nouvelle branche supprimera vos modifs sur master. Si vous avez plusieurs branch, vous pouvez spécifier à partir de quelle branche créer la nouvelle branche git branch nouvelle_branche depuis_cette_branche Changer de branche git checkout nom_dune_branche Renommer une branche git branch -m ancien_nom nouveau_nom Pour pousser votre branche sur le dépôt afin qu'elle soit accessible à tout le monde git branch --set-upstream nom_dune_branche origin/nom_dune_branche === Modification === Pour fusionner votre nouvelle branche sur la branche master, faites vos commit, placez-vous sur la branche master puis fusionner une autre branche sur celle-ci git commit -a git checkout master git merge nom_de_la_branche_a_fusionner_avec_master Pour garder l'historique de votre branche sans mélanger vos commits avec la branche de destination, spécifiez l'option ''--no-ff'' no fast forward git merge --no-ff branche_a_fusionner Pour copier un fichier d'une autre branche sur la branche en cours $ git checkout master $ git branch * master twitter_integration $ git checkout twitter_integration fichier1 fichier2 Si vous avez une branche feature et que vous voulez intégrer les derniers commit de master sur cette branche $ git checkout feature $ git pull origin master === Suppression de branches === Pour supprimer la branche qui ne sert plus à rien et vérifier qu'elle a été mergé git branch -d nom_branche_qui_sert_plus Pour supprimer une branche qui n'a pas été mergé git branch -D nom_branche_obsolète Après avoir supprimé votre branch, il est possible qu'en utilisant ''git checkout '' + tab vous voyez encore de vieille branch dans l'autocompletion. Utilisez la commande suivante pour purger ces restes $ git remote prune origin Pour supprimer la branch sur origin git push origin --delete nom_branche_qui_sert_plus === tester un merge === git checkout master git merge --no-commit --no-ff branche_a_merger Pour voir ce qui a changé git diff --cached Pour abandonner le merge git merge --abort Pour valider le merge git commit == Méthode alternative à l'ancienne == Pour tester votre merge, faite un test sur une branche temporaire git checkout master git checkout -b temp_merge git merge feature_branch Après avoir réglé les conflits ou autre problème, vous pouvez comparer les différences avec le master git diff master Quand c'est fait, supprimez votre banche temporaire git checkout master git branch -D temp_merge === appliquer un commit d'une autre branche === On est sur notre branche v2 git checkout v2 On veut appliquer notre commit a2a2a2 sur notre branche master git checkout master git cherry-pick a2a2a2 Si vous rencontrez des conflits, tout est bien expliqué $ git cherry-pick 19c0c1d error: impossible d'appliquer 19c0c1d... commentaire du commit astuce: après résolution des conflits, marquez les chemins corrigés astuce: avec 'git add ' ou 'git rm ' astuce: puis validez le résultat avec 'git commit' $ git status Sur la branche v2 Vous êtes actuellement en train de picorer le commit 19c0c1d. (réglez les conflits puis lancez "git cherry-pick --continue") (utilisez "git cherry-pick --abort" pour annuler le picorage) Modifications qui seront validées : modifié : mon-fichier.php modifié : mon-fichier2.php Chemins non fusionnés : (utilisez "git add ..." pour marquer comme résolu) modifié des deux côtés : mon-fichier-en-conflit.php Fichiers non suivis: (utilisez "git add ..." pour inclure dans ce qui sera validé) mon-fichier-non-suivi.php ==== Gestion de conflit ==== Si il y a un conflit CONFLICT (content): Merge conflict in app/controllers/AdminController.php Automatic merge failed; fix conflicts and then commit the result. Un git status listera les fichiers en conflit par un both modified # Unmerged paths: # (use "git add/rm ..." as appropriate to mark resolution) # # both modified: app/controllers/AdminController.php # Pour voir le conflit git diff Le conflit sera présenté comme ça ++<<<<<<< HEAD + mon code sur le master ++======= + mon code sur la branche à merger ++>>>>>>> branche_a_merger Vous pouvez utiliser un outils graphique tel que vimdiff pour corriger le problème avec la commande git mergetool Pour passer d'un conflit à un autre utilisez cette séquence '']c'' ou ''[c''\\ Une fois placé sur un conflit, utilisez la commande '':diffget LO'' pour remplacer le conflit par ce qu'il y a dans la fenêtre LOCAL. ( ''BA'' pour BASE, ''RE'' pour REMOTE)\\ Sauvegardez et quittez toutes les fenêtres par '':xa'', votre fichier sera automatiquement ajouté dans votre prochain commit.\\ Supprimez le copie de sauvegarde laissez par vimdiff rm fichier_en_conflit.orig Sinon corrigez à la main le fichier et ajoutez le git add fichier_en_conflit ==== Checkout ==== Liste des fichiers modifiés git checkout Permet une interactivité sur la modification d'un fichier git checkout -p Discard this hunk from worktree [y,n,q,a,d,/,s,e,?]? ? y - discard this hunk from worktree n - do not discard this hunk from worktree q - quit; do not discard this hunk nor any of the remaining ones a - discard this hunk and all later hunks in the file d - do not discard this hunk nor any of the later hunks in the file g - select a hunk to go to / - search for a hunk matching the given regex j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk ? - print help git pull = git fetch + git merge Supprimer un fichier de l'arborescence et le supprimer de l'index git rm fichier Supprimer un fichier uniquement de l'index sans le supprimer physiquement git rm --cached fichier Pour supprimer le fichier de tout l'historique git filter-branch --index-filter 'git rm --cached (file)' HEAD Supprimer tous les fichiers pourris de iOS (échapper l'astérisk est important sinon le shell l'interprètera et seul les fichiers de 1er niveau seront supprimés) git rm \*/.DS_Store Supprimer un dossier git rm -r dossier Récupérer un fichier supprimé git checkout HEAD fichier Récupérer un fichier d'un ancien commit git checkout hashDuCommit fichier Remet dans l'état précédent tous les fichiers git reset --hard HEAD Remet dans l'état d'un commit précédent git reset --hard hashDuCommit Abandonner le suivi de fichiers pour les fichiers de config par exemple git update-index --assume-unchanged config.php Si c'est un répertoire, terminé par un / git update-index --assume-unchanged app/config/ Pour revenir en arrière git update-index --no-assume-unchanged config.php Pour afficher les fichiers qui ont été marqué avec un --assume-unchanged git ls-files -v | grep -e "^[hsmrck]" Pour annuler les modifications d'un commit spécifique git revert b12caf55 Pour annuler les 3 derniers commits git revert HEAD~3..HEAD� ==== Tag ==== Créer un tag léger (pour les versions mineures, git crée un pointeur) git tag v1.0.1 ou un tag lourd avec un message (pour les releases, git crée un objet avec des metadatas) git tag -a v1.0 -m 'blabla' Pousser ses tags sur le remote git push --tags Lister les tag git tag Supprimer un tag (en local) git tag -d v1.0 Supprimer un tag en remote après l'avoir supprimé en local git push origin :refs/tags/v1.0 Switcher sur un tag git checkout v1.0 Switcher sur un commit (pour par exemple revoir un vieux fichier qu'on aurait supprimé...) git checkout 2e6bc6f Revenir sur l'état courant git checkout master ==== Stash ==== Si on a fait une modification qu'on ne veut pas commiter, on peut la mettre de côté, faire par exemple un git pull et réappliquer la modif git stash Pour mettre en stash uniquement un fichier git stash push -- path/to/file.txt pour voir les modifs en stash git stash list Pour voir quelles sont les fichiers modifiés par un stash git stash show ou git stash show stash@{0} Pour appliquer vos modifs stockées dans le stash et les supprimer du stash git stash pop Pour appliquer vos modifs stockées dans le stash et les laisser dans le stash git stash apply Le reste dans git stash help ===== Faire un dépôt git vite fait ===== Créer un répertoire qui contiendra votre projet git. Ex: projet.git cd /var/git/projet.git Initialisez le dépôt vide git init --bare --shared Allez dans votre projet cd /var/www/projet Créez votre projet git git init Ajoutez les fichier git add . Créez votre 1er commit git commit -m 'Mon 1er commit' Spécifiez le dépôt à votre projet git remote add origin /var/git/projet.git Poussez tout ça en spécifiant origin et la branche master git push origin master Spécifié les infos de suivi... git branch --set-upstream master origin/master Ce qui devrait vous faire un fichier de config comme suit [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = /var/git/projet.git/ fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master et voila :) Si vous avez oubliez l'option --shared qui permet de permettre à d'autres utilisateurs system de pouvoir faire des push, ajoutez ceci dans votre fichier de config du dépôt [core] sharedrepository = 1 [receive] denyNonFastforwards = true et tapez ces quelques commandes dans votre dépôt pour les permissions chgrp -R votreGroupe . find . -type d | xargs chmod g+ws find refs -type f | xargs chmod g+w ===== Explication git add ===== git add -A is equivalent to git add .; git add -u. The important point about git add . is that it looks at the working tree and adds all those paths to the staged changes if they are either changed or are new and not ignored, it does not stage any 'rm' actions. git add -u looks at all the already tracked files and stages the changes to those files if they are different or if they have been removed. It does not add any new files, it only stages changes to already tracked files. git add -A is a handy shortcut for doing both of those. You can test the differences out with something like this (note that for Git version 2.x your output for git add . git status will be different): git init echo Change me > change-me echo Delete me > delete-me git add change-me delete-me git commit -m initial echo OK >> change-me rm delete-me echo Add me > add-me git status # Changed but not updated: # modified: change-me # deleted: delete-me # Untracked files: # add-me git add . git status # Changes to be committed: # new file: add-me # modified: change-me # Changed but not updated: # deleted: delete-me git reset git add -u git status # Changes to be committed: # modified: change-me # deleted: delete-me # Untracked files: # add-me git reset git add -A git status # Changes to be committed: # new file: add-me # modified: change-me # deleted: delete-me ===== Cas simple ===== ==== Serveur ==== Créer un répertoire et tapez la commande git init Si le répertoire contient déjà tout un projet, ajoutez les fichiers que vous voulez suivre avec la commande git add . Vérifiez l'état avec la commande git status Faite un commit pour commencer git commit A ce moment là, votre éditeur de texte par défaut s'ouvre pour vous demander un commentaire sur ce commit. Ce commentaire est obligatoire, sinon l'action ne continuera pas. ==== Client ==== Récupérez le projet du serveur avec la commande git clone ssh://user@serveur/var/www/monProjet ou en notation scp git clone user@serveur:/var/www/monProjet Si vous voulez mettre votre projet sur le serveur, assurez-vous de créer un git vide sur le serveur, faite un clone, ajoutez tous vos fichiers, faite un **git add.** puis un commit. ===== Cas de dev web ===== Environnement de dev : placez vous dans votre répertoire de dev **/home/toto/dev** et taper la commande [local]$ cd /home/toto/dev [local:/home/toto/dev]$ git init Si vous voulez suivre tous vos fichiers dans git tapez [local:/home/toto/dev]$ git add . Sinon spécifiez le fichier à suivre [local:/home/toto/dev]$ git add test.php Faites votre 1er commit [local:/home/toto/dev]$ git commit -m "1er commit" Place au serveur distant de prod et test Créer un dépot pour gérer tout ça [serveur.com]$ mkdir /var/www/hub.git [serveur.com]$ cd /var/www/hub.git [serveur.com:/var/www/hub.git]$ git init --bare Sur la machine de dev [local:/home/toto/dev]$ git remote add origin ssh://root@serveurProd/var/www/hub.git Synchroniser la branche master sur votre serveur git **origin** [local:/home/toto/dev]$ git push origin master Vérifier sur le serveur de prod [serveur.com:/var/www/hub.git]$ git log Créer sur le serveur de prod un répertoire prod et test [serveur.com:/var/www/hub.git]$ git clone hub.git prod [serveur.com:/var/www/hub.git]$ git clone hub.git test [serveur.com:/var/www/hub.git]$ cd hub.git/hook [serveur.com:/var/www/hub.git/hook]$ vi post-update #!/bin/bash echo "***** Mise en production *****" cd /var/www/prod unset GIT_DIR git pull origin master echo "***** Mise en test *****" cd /var/www/test unset GIT_DIR git pull origin dev Rendre exécutable [serveur.com:/var/www/hub.git/hook]$ chmod +x post-update De retour sur la machine de dev, nous allons créer une branche de dev pour différencier la prod de test [local:/home/toto/dev]$ git branch dev Pour vérifier sur quelle branche nous nous trouvons [local:/home/toto/dev]$ git branch dev * master Nous sommes sur la branche master, pour se mettre sur la branche dev [local:/home/toto/dev]$ git checkout dev On vérifie [local:/home/toto/dev]$ git branch * dev master On définie les fichiers à suivre dans cette branche dev [local:/home/toto/dev]$ git add . Et on commit [local:/home/toto/dev]$ git commit -m "1er commit de la branche dev" La 1ère fois, spécifier la nouvelle branche **dev** dans la commande push pour la créer sur le serveur git [local:/home/toto/dev]$ git push origin dev Fusionner votre branche de dev sur le master.\\ Mettez vous sur la branche master [local:/home/toto/dev]$ git checkout master Fusionner la branche dev avec la branche en cours (master) [local:/home/toto/dev]$ git merge dev Faites un push pour mettre à jour le serveur git [local:/home/toto/dev]$ git push origin Pour ignorer la mise à jour de certains répertoire, utiliser un fichier **.gitignore** et placer les dossiers à ignorer [local:/home/toto/dev]$ vi .gitignore /repertoire/a/eviter D'autre exemple de .gitignore # un commentaire, cette ligne est ignorée # pas de fichier .a *.a # mais suivre lib.a malgré la règle précédente !lib.a # ignorer les fichier finissant par ~ *.~ # ignorer les fichier finissant par .a et .o *.[ao] # ignorer uniquement le fichier TODO à la racine du projet /TODO # ignorer tous les fichiers dans le répertoire build build/ # ignorer doc/notes.txt, mais pas doc/server/arch.txt doc/*.txt # ignorer tous les fichiers .txt sous le répertoire doc/ doc/**/*.txt Bon dev :) Pour éviter de taper **origin** à chaque pull ou push, éditer votre fichier **.git/config** sur votre machine de dev et adaptez en conséquence [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = user@serveur.com:/var/www/projet.git/ [branch "master"] remote = origin merge = refs/heads/master --- source : http://www.siteduzero.com/informatique/tutoriels/gerez-vos-codes-source-avec-git/travailler-avec-des-branches --- Doc complète : http://git-scm.com/book/fr/D%C3%A9marrage-rapide --- Doc vidéo sur le cas de dev web : http://www.grafikart.fr/blog/deployer-site-git --- Une autre petite doc : http://www.miximum.fr/tutos/1546-enfin-comprendre-git --- http://doc.ubuntu-fr.org/git --- Doc en anglais http://gitimmersion.com ===== Le cas des fichiers de config ===== On va supposer un projet web avec plein de fichiers de config dans **/app/config/** Créer un fichier **.gitignore** avec comme contenu /app/config/ Ce qui aura pour effet d'ignorer le répertoire de config lors d'un push ou d'un pull. Pushez ce .gitignore sur votre dépôt ou votre git source. Faite un clone de votre projet git clone projet.git projet_dev Spécifiez que vous ne voulez pas indexer les changements de notre dossier de config git update-index --assume-unchanged app/config/*.* Modifiez vos fichiers de config, puis vérifions ce qu'il se passe. # git status # On branch master nothing to commit (working directory clean) ---- Maintenant supposons qu'un utilisateur ait modifié les fichiers de config de base et les aient pushé sur le dépôt.. \\ Dans ce cas la, lorsque vous allez faire un pull, vous pouvez être confronté à divers messages d'erreurs... git pull remote: Counting objects: 9, done. remote: Compressing objects: 100% (5/5), done. remote: Total 5 (delta 4), reused 0 (delta 0) Unpacking objects: 100% (5/5), done. From edmc73.com:/var/www/dev/dashboard 0060f1f..e1f3b16 master -> origin/master Updating 0060f1f..e1f3b16 error: Your local changes to 'app/config/app.php' would be overwritten by merge. Aborting. Please, commit your changes or stash them before you can merge. git status # On branch master # Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. # nothing to commit (working directory clean) Et la, c'est la panique complète !!! SOLUTION : changer la reférence HEAD à la main... Récupérer le hash du dernier commit git log --all -n5 --pretty=format:'%H - %d' e1f3b16a476415ff1be102beec8643f208996d7b - (origin/master) 0060f1fbc299e8c6c9bcd123a490edc9446dce44 - (HEAD, master) f8136204dd67a8a8336da3fb83ce2cf2b91343dc - 07cac380a96eba82e1c69f96a616d86b9b545f03 - 92586834ee358c57ceb01d11875efe672c043c14 - On voit ici que dans notre git local, notre HEAD est à la 2eme place alors que celui du dépôt distant est sur la 1ère. Vous pouvez consulter le contenu du commit avec la commande git cat-file -p e1f3b16a476415ff1be102beec8643f208996d7b Si on vérifie le contenu du fichier **.git/refs/heads/master** on retrouve bien notre hash précédent en 2ème position cat .git/refs/heads/master 0060f1fbc299e8c6c9bcd123a490edc9446dce44 Editez le fichier **.git/refs/heads/master** et placer le 1er hash echo e1f3b16a476415ff1be102beec8643f208996d7b > .git/refs/heads/master Notre fichier de config ressort maintenant comme étant modifié git status # On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # modified: app/config/app.php # Désindexer le fichier avec la commande proposé par git git reset HEAD app/config/app.php Unstaged changes after reset: M app/config/app.php git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: app/config/app.php # no changes added to commit (use "git add" and/or "git commit -a") Ignorer le changement git update-index --assume-unchanged app/config/app.php git status # On branch master nothing to commit (working directory clean) Résultat git pull Already up-to-date. ===== Configurer Apache ===== Pour interdire l'accès aux fichiers **git** depuis le web, ajouter ce bout de code dans votre config apache Order allow,deny Deny from all Satisfy all Profitez-en pour limiter l'accès à votre fichier **README.md** Order Deny,Allow Deny from all ===== Faire le ménage dans son historique ===== La docs officiel * https://git-scm.com/book/fr/v1/Utilitaires-Git-R%C3%A9%C3%A9crire-l-historique Un super article sur git rebase, git reflog * http://putaindecode.io/fr/articles/git/log-bisect-rebase-reflog/ Virer la branch temporaire (supprime le cache du remote et donc vire le pointeur du remote origin dans l'historique des commits) git update-ref -d refs/original/refs/heads/master En voir plus dans les logs comme l'autheur et le commiteur git log --format=fuller Voir toutes les actions faites dans le moindre détail git reflog Modifier l'autheur et le commiteur de tous les commits git filter-branch --commit-filter \ 'if [ "$GIT_AUTHOR_NAME" = "OldAuthor Name" ]; then \ export GIT_AUTHOR_NAME="Author Name";\ export GIT_AUTHOR_EMAIL=authorEmail@example.com;\ export GIT_COMMITTER_NAME="Commmiter Name";\ export GIT_COMMITTER_EMAIL=commiterEmail@example.com;\ fi;\ git commit-tree "$@"' Reprendre tout depuis le début git rebase --root -i Cette commande permet de partir du 1er commit ( --root ) et de tomber sur un mode interactif ( -i ) permettant de bouger, supprimer re éditer des commits Cette manip peut être long si le début est chaotique avec des branches de merge qui trainent à droite à gauche, dans ce cas, git vous dira de vérifier et valider les commits. Voici quelques commande à faire git status git add . git rebase --continue Si vous êtes perdu git rebase --abort Maintenant, quand on regarde un peu l'historique, on peut voir que toutes les dates de commit on changé, ce qui peut être embêtant. Heureusement, la date de l'autheur est toujours intact, on va donc pouvoir tout mettre à jour avec la commande suivante git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE' Maintenant que notre historique est bon, on va se créer un dépot tout propre et faire encore un peu de ménage sur notre espace de travail.\\ Supprimer le dépot git remote remove origin Supprimer le cache du remote git update-ref -d refs/original/refs/heads/master Vider tous les reflog qui ne servent à rien git reflog expire --expire=now --all git gc --agressive --prune=now Pour le grand nettoyage => http://blog.ostermiller.org/git-remove-from-history Maintenant, soit on recrée un dépot tout neuf et on push dedans, soit on force git push --force --all ===== Rebrancher un depot git sur un dossier de travail sans git ===== Par exemple, nous avons un dépôt git sur http://git/projet Notre répertoire de travail ( ~/projet ) contient le même contenu avec des modifications, mais aucune information de git (pas de dossier .git) Nous voulons connecté ce répertoire de travail avec le dépôt git afin de pouvoir commité nos modifications. ATTENTION: à faire uniquement si votre répertoire de travail est plus à jour que le dépôt git, sinon vous écraserez les modifs du dépôt git. $ cd ~/projet $ git init Dépôt Git vide initialisé dans ~/projet $ git remote add origin http://git/projet $ git fetch remote: Décompte des objets: 33, fait. remote: Compression des objets: 100% (31/31), fait. remote: Total 33 (delta 3), reused 0 (delta 0) Unpacking objects: 100% (33/33), done. Depuis http://git/projet * [nouvelle branche] master -> origin/master # dans mon cas, seul le fichier README.md a été modifié par rapport au dépôt git $ git reset origin/master Modifications non indexées après reset : M README.md # ajoutez vos fichiers ou commitez vos modifs de fichiers déjà suivi $ git commit -a $ git push -u origin/master Counting objects: 5, done. Writing objects: 100% (3/3), 255 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To http://git/projet 217fd11..78c825e master -> master La branche master est paramétrée pour suivre la branche distante master depuis origin. ===== Monter son serveur git ===== * https://wiki.auto-hebergement.fr/serveurs/git * https://git-scm.com/book/fr/v1/Git-sur-le-serveur-Installation-de-Git-sur-un-serveur * https://git-scm.com/book/fr/v1/Git-sur-le-serveur-GitWeb ===== Monter son github perso avec gogs ===== * https://gogs.io/ : un clone de github mais en auto hébergé ==== Features ==== * Activity timeline * SSH and HTTP/HTTPS protocols * SMTP/LDAP/Reverse proxy authentication * Reverse proxy with sub-path * Account/Organization/Repository management * Add/Remove repository collaborators * Repository/Organization webhooks (including Slack) * Repository Git hooks/deploy keys * Repository issues, pull requests and wiki * Migrate and mirror repository and its wiki * Web editor for repository files and wiki * Gravatar and Federated avatar with custom source * Mail service * Administration panel * Supports MySQL, PostgreSQL, SQLite3 and TiDB (experimental) * Multi-language support (19 languages) ==== Alternatives ==== * https://gitea.io : Gitea is a community fork of the popular self-hosted Git service Gogs. * https://rhodecode.com : Unified Tools for Mercurial, Git and Subversion * https://kallithea-scm.org : source code management system that supports two leading version control systems, Mercurial and Git * https://www.slant.co/topics/1440/~best-self-hosted-web-based-git-repository-managers ==== Installation ==== On peut installer **gogs** soit à partir : * des sources => https://gogs.io/docs/installation/install_from_source * d'un binaire => https://dl.gogs.io/ * d'un paquet (non dispo dans les paquets debian) => https://packager.io/gh/pkgr/gogs J'ai testé via les binaires et ça marche très bien, il faut juste penser à créer un utilisateur git qui servira à stocker les dépôts et les clés ssh pour faire le lien avec les utilisateurs Sur un serveur de prod je préfère que tout soit intégré comme le reste, je vais donc faire l'installation sur une debian 8 via le paquet deb proposé. Les commandes sont expliquées sur cette page https://packager.io/gh/pkgr/gogs/install?bid=535#debian-8-gogs wget -qO - https://deb.packager.io/key | sudo apt-key add - echo "deb https://deb.packager.io/gh/pkgr/gogs jessie pkgr" | sudo tee /etc/apt/sources.list.d/gogs.list sudo apt-get update sudo apt-get install gogs gogs tourne en local sur le port 3000, nous allons utiliser le module proxy d'apache pour y accéder sur le port HTTP classique # a2enmod proxy # a2enmod proxy_http # service apache2 restart Ensuite nous allons créer une config apache Define HOSTNAME git.edmc73.com AssignUserId gogs gogs ServerName ${HOSTNAME} Order allow,deny Allow from all ProxyPass / http://127.0.0.1:3000/ ProxyPassReverse / http://127.0.0.1:3000/ ErrorLog /var/log/apache2/${HOSTNAME}_error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/${HOSTNAME}_access.log combined a2ensite git.edmc73.com.conf service apache2 reload et maintenant via votre navigateur vous allez tomber sur la page d'installation de gogs. Créer au préalable une base de données **gogs** avec comme interclassement utf8_general_ci Spécifiez le **domaine** et le **root_url**, au pire vous pourrez modifier le fichier /etc/gogs/conf/app.ini Profitez-en pour changer le HTTP_ADDR pour que gogs ne soit accessible que en local par apache. [server] PROTOCOL = http DOMAIN = git.edmc73.com ROOT_URL = https://git.edmc73.com/ HTTP_ADDR = 127.0.0.1 HTTP_PORT = 3000 Validez et voila ;) Maintenant on peut créer un certificat via let's encrypt debian:~/letsencrypt# ./certbot-auto certonly --webroot -w /opt/gogs/public/ -d git.edmc73.com Créer la config apache qui va bien et forcer la redirection vers https Redirect permanent / https://git.edmc73.com/ Pour la configuration des mails, si vous avez un postfix en smtp en local sans certificat valide, modifier la config en ajoutant true pour SKIP_VERIFY et le HOST = 127.0.0.1:25 [mailer] ENABLED = true ; Buffer length of channel, keep it as it is if you don't know what it is. SEND_BUFFER_LEN = 100 ; Name displayed in mail title SUBJECT = %(APP_NAME)s ; Mail server ; Gmail: smtp.gmail.com:587 ; QQ: smtp.qq.com:465 ; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used. HOST = 127.0.0.1:25 ; Disable HELO operation when hostname are different. DISABLE_HELO = ; Custom hostname for HELO operation, default is from system. HELO_HOSTNAME = ; Do not verify the certificate of the server. Only use this for self-signed certificates SKIP_VERIFY = true N'oubliez pas de redémarrer gogs après des modifs dans le fichier de config service gogs restart