{{tag>Brouillon git}} # Notes GIT Voir : * [[Notes git - Convention commit - Bien nommer ses commits]] Voir aussi : * [Git-lint](https://www.alchemists.io/projects/git-lint/) Clients graphiques : * gitg * gitk * qgit * tig (console) * git-cola ## Basic Voir : * https://www.youtube.com/playlist?list=PLPoAfTkDs_JbMPY-BXzud0aMhKKhcstRc * https://ndpsoftware.com/git-cheatsheet.html * https://confluence.atlassian.com/bitbucketserver094/basic-git-commands-1489801692.html?utm_campaign=in-app-help&utm_medium=in-app-help * [7 Git articles every open source practitioner should read](https://opensource.com/article/23/1/git-articles) * https://developers.redhat.com/cheat-sheets/git-cheat-sheet * Oh My Git! * http://bayledes.free.fr/systeme/git.html Git Undo uncommited ~~~bash git checkout -f ~~~ will remove any non-committed changes. Par exemple pour annuler un pb de merge ### Undo commit IF you have NOT pushed your changes to remote ~~~bash git reset HEAD~1 ~~~ Check if the working copy is clean by `git status` ELSE you have pushed your changes to remote ~~~bash git revert --no-commit HEAD ~~~ This command will revert/remove the local commits/change and then you can push #### Revert multiple commits ~~~bash git log --oneline ~~~ ~~~ A <-- B <-- C <-- D <-- master <-- HEAD ~~~ ~~~bash git revert --no-commit D git revert --no-commit C git revert --no-commit B git commit -m "the commit message for all of them" ~~~ ou ~~~bash git reset --hard A git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D git commit ~~~ ou ~~~bash git revert --no-commit HEAD~3.. git revert master~3..master # Revert all commits from and including B to HEAD, inclusively git revert --no-commit B^..HEAD git commit -m 'message' ~~~ ou ~~~bash git reset --hard git push -f ~~~ ### check before git push ~~~bash #git diff --stat --cached [remote/branch] git diff --stat --cached origin/master ~~~ or ~~~bash git push --dry-run ~~~ For the code diff of the files to be pushed, run: ~~~bash git diff [remote repo/branch] ~~~ To see full file paths of the files that will change, run: ~~~bash git diff --name-only [remote repo/branch] # Ou encore git diff --name-status [remote repo/branch] git diff --numstat [remote repo/branch] ~~~ ## Git workflow Voir : * https://www.nicoespeon.com/fr/2013/08/quel-git-workflow-pour-mon-projet/#le_github_flow * https://www.atlassian.com/fr/git/tutorials/comparing-workflows * Git-flow ## Configurer son environnement `~/.bashrc` ~~~bash export PS1='\u@\h:\w$(__git_ps1) \$ ' export GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 GIT_PS1_SHOWUNTRACKEDFILES=1 export GIT_PS1_SHOWUPSTREAM=verbose GIT_PS1_DESCRIBE_STYLE=branch ~~~ ~~~bash git config --global status.submoduleSummary true ~~~ ## Create a new repository on the command line ~~~bash touch README.md git init git add README.md git commit -m "first commit" git remote add origin git@git.acme.fr:jean/docker-dokuwiki.git git push -u origin master ~~~ ## Push an existing repository from the command line ~~~bash git remote add origin git@git.acme.fr:jean/docker-dokuwiki.git git push -u origin master ~~~ ## Change remote location ~~~bash git remote set-url ssh://gogs@new.acme.fr/user/projet git remote set-url origin ssh://git@new.acme.fr/user/projet ssh://git@old.acme.fr/user/projet git remote set-url --push origin ssh://git@new.acme.fr/user/projet ~~~ ## Git grep Search the working directory for `foo()` ~~~bash git grep "foo()" ~~~ ## Branches et merge Créer une nouvelle branche locale ~~~bash # Créer la branch git branch bugfix1 # Travailler dans la branch spécifiée git checkout bugfix1 ~~~ ou ~~~bash git checkout -b bugfix1 ~~~ Checkout a remote Git branch ~~~bash $ git fetch $ git branch -v -a ... remotes/origin/dev $ git checkout dev ~~~ By using the `--track` parameter, you can use a remote branch as the basis for a new local branch; this will also set up a "tracking relationship" between the two: ~~~bash git checkout -b new-branch --track origin/develop ~~~ git add plop git commit -m "+ plop" Commiter la nouvelle branche / créer une branche distante ~~~bash git push --set-upstream origin bugfix1 ~~~ Revenir à la branche master ~~~bash git checkout master ~~~ Clonner une branche spécifique ~~~bash git clone -b bugfix1 https://gogs.belaris.fr/BELARIS/test01 ~~~ git reflog avec date ~~~bash git reflog --date=iso git reflog --pretty=short --date=iso ~~~ Merge without autocommit ~~~bash git merge mabranch --no-commit --no-ff #ou git merge mabranch --squash ~~~ ### Merge - rebase Voir * https://www.atlassian.com/fr/git/tutorials/comparing-workflows * [Recover from an unsuccessful git rebase with the git reflog command](https://opensource.com/article/23/1/git-reflog) Merge vs Merge : https://git-flow.readthedocs.io/fr/latest/presentation.html ~~~bash git pull --rebase ~~~ Ou pour configurer le rebase par défaut après un **pull** ~~~bash git config --global pull.rebase true ~~~ Si conflits ~~~bash git add plop git rebase --continue ~~~ Si trop compliqué annuler : ~~~bash git rebase --abort ~~~ ### Annuler un merge Jetez un oeil ~~~bash git reflog --date=iso # ou git log -g ~~~ Puis ~~~bash git reset --hard # Retour au commit précedent git reset --hard HEAD~1 #Ou pour une branche git reset --hard origin/mabranch ~~~ ## Autre Connaître la version du dépôt - Current version ~~~bash git describe --tags ~~~ Log history ~~~bash git log --oneline --graph --color --all --decorate ~~~ Autres ~~~ git push warning: push.default n'est pas défini ; sa valeur implicite a changé dans Git 2.0 de 'matching' vers 'simple'. Pour supprimer ce message et maintenir le comportement actuel après la modification de la valeur de défaut, utilisez : git config --global push.default matching Pour supprimer ce message et adopter le nouveau comportement maintenant, utilisez : git config --global push.default simple Quand push.default vaudra 'matching', git poussera les branches locales sur les branches distantes qui existent déjà avec le même nom. Depuis Git 2.0, Git utilise par défaut le comportement plus conservatif 'simple' qui ne pousse la branche courante que vers la branche distante correspondante que 'git pull' utilise pour mettre à jour la branche courante. Voir 'git help config' et chercher 'push.default' pour plus d'information. (le mode 'simple' a été introduit dans Git 1.7.11. Utilisez le mode similaire 'current' au lieu de 'simple' si vous utilisez de temps en temps d'anciennes versions de Git) ~~~ ~~~ warning: Pulling without specifying how to reconcile divergent branches is discouraged. You can squelch this message by running one of the following commands sometime before your next pull: git config pull.rebase false # merge (the default strategy) git config pull.rebase true # rebase git config pull.ff only # fast-forward only You can replace "git config" with "git config --global" to set a default preference for all repositories. You can also pass --rebase, --no-rebase, or --ff-only on the command line to override the configured default per invocation. ~~~ https://www.grafikart.fr/tutoriels/checkout-revert-reset-586 https://www.youtube.com/watch?v=rP3T0Ee6pLU&feature=emb_rel_end https://www.youtube.com/watch?v=2zAtE4hnBao&list=PLtAnN3kwIVucWlr1pyfnmw8qCNaq0tusi&index=2 https://ohshitgit.com/ https://perso.liris.cnrs.fr/pierre-antoine.champin/enseignement/intro-git/ https://rogerdudler.github.io/git-guide/index.fr.html https://delicious-insights.com/fr/articles/bien-utiliser-git-merge-et-rebase/ git pull --rebase git rebase origin/master postconf -e smtpd_client_restrictions='permit_mynetworks, check_client_access hash:/etc/postfix/client_checks, check_sender_access hash:/etc/postfix/sender_checks' dontreply@mass.datingfactory.com https://www.miximum.fr/blog/enfin-comprendre-git/ https://www.miximum.fr/blog/git-rebase/ Les branches https://git-scm.com/book/fr/v2/Les-branches-avec-Git-Les-branches-en-bref https://git-scm.com/book/fr/v2/Les-branches-avec-Git-Branches-et-fusions%C2%A0%3A-les-bases RESET https://www.atlassian.com/fr/git/tutorials/undoing-changes https://makina-corpus.com/blog/metier/archives/git-annuler-proprement-un-commit-apres-un-push https://alexgirard.com/git-book/intermediaire/repair-reset-checkout-revert/ https://opensource.com/article/18/6/git-reset-revert-rebase-commands https://docs.gitlab.com/ee/university/training/topics/rollback_commits.html STASH https://git-scm.com/book/fr/v2/Utilitaires-Git-Remisage-et-nettoyage REBASE https://openclassrooms.com/fr/courses/5641721-utilisez-git-et-github-pour-vos-projets-de-developpement/6113081-modifiez-vos-branches-avec-rebase https://riptutorial.com/fr/git/example/3282/rebase-interactif https://delicious-insights.com/fr/articles/bien-utiliser-git-merge-et-rebase/ Un `git pull` revient à * `git fetch` * `git merge` ~~~bash git add . # Idem mais en plus inclus des supression git add --all ~~~ ~~~bash # Checkout the stable branch and find just the latest tag git checkout master git describe --abbrev=0 --tags git tag --sort ~~~ undo git add ~~~bash git reset HEAD -- plop # ou git reset -- plop # ou git rm --cached plop # Suprimer le stagging git reset # Ou git restore --staged ... ~~~ Status ~~~bash git status -s ~~~ Git log pour toutes les branches locales ~~~bash git reflog git log --all ~~~ Historique des modifications pour un fichier précis. ~~~bash git log --oneline -p README.md ~~~ Information sur un commit précis ~~~bash git show 3717 ~~~ Modifier le dernier message du commit ~~~bash git commit --amend ~~~ Diff de la branche avec master ~~~bash git diff origin/master ~~~ Diff entre branches ~~~bash git diff --name-only dev1..dev2 git difftool -y -t vimdiff dev1 dev2 .gitlab-ci.yml ~~~ Annuler proprement un commit sans altérer l'historique des commits ~~~bash git revert --no-commit 55dbdf ~~~ Une alternative ~~~bash git checkout git checkout -b new_branch_name ~~~ Autre une alternative Normalement ne marche que dans une branche. Permet de changer l'history, de squash, effacer... ~~~bash git rebase -i HEAD~3 ~~~ Rejouer un commit spécifique / undo `git revert` ~~~bash git cherry-pick 55dbdf ~~~ Effacer une branche distante ~~~bash git push origin --delete branchy ~~~ Plop ~~~bash git checkout master git pull origin master git checkout my-branch git merge master ~~~ ### submodule Voir * https://www.hexotech.fr/blog/le-blog-hexotech-2/comment-gerer-efficacement-un-projet-multi-depot-git-123 * https://delicious-insights.com/fr/articles/git-submodules/ * [Git subtree: une alternative à Git submodule](https://gauthier.frama.io/post/git-subtree/) ~~~bash git clone git@acme.fr:toto/plop.git cd plop git submodule update --init --recursive # Ou git clone --recurse-submodules git@acme.fr:toto/plop.git ~~~ Mise à jour submodule ~~~bash git submodule update module/ cd module git pull origin master ~~~ Si commit par erreur d'un submodule ~~~bash git submodule update --force ~~~ Affichage plus explicite de la commande `git status` ~~~bash git config --global status.submoduleSummary true ~~~ Mise à jour - faire pointer le submodule sur la branche master ~~~bash git submodule foreach git pull origin master ~~~ Avec Gitlab CI Voir : https://docs.gitlab.com/ee/ci/git_submodules.html `.gitlab-ci.yml` ~~~yaml variables: GIT_SUBMODULE_STRATEGY: recursive ~~~ ## Diagnostique ~~~bash export GIT_TRACE=2 export GIT_CURL_VERBOSE=2 export GIT_TRACE_PERFORMANCE=2 export GIT_TRACE_PACK_ACCESS=2 export GIT_TRACE_PACKET=2 export GIT_TRACE_PACKFILE=2 export GIT_TRACE_SETUP=2 export GIT_TRACE_SHALLOW=2 ~~~ ## Autres Lol / Lola ~~~bash git config --global alias.lol "log --graph --decorate --pretty=oneline --abbrev-commit" git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all" ~~~ ~~~bash clone --depth 1 $URL fetch --unshallow $URL ~~~ ## Python Voir aussi : * pygit2 `reuirements.txt` ~~~ GitPython ~~~ ~~~python #! /usr/bin/python3 import os import urllib.parse from git import Repo mdp=urllib.parse.quote('P@ssw0rd!', safe=`) if os.path.isdir('/tmp/clone'): repo = Repo('/tmp/clone') repo.remotes.origin.pull() else: repo = Repo.clone_from(f'https://user1:{mdp}@git.acme.local/user1/test01.git', '/tmp/clone', depth=1) repo.index.add('plop.txt') repo.index.commit('commit msg') #origin = repo.remotes[0] #origin = repo.remotes['origin'] origin = repo.remotes.origin origin.push() ~~~