+++ title = "Git" date = 2020-02-22T16:26:07+01:00 weight = 1 +++
GIT LOG¶
$ git log -p -2 $ git log --stat $ git log --pretty=format:"%h - %an, %ar : %s" $ git log --pretty=oneline
synchro fetch upstream¶
git fetch upstream
git rebase upstream/master
git push origin master
Git - Checkout local d'une Merge-Requests¶
Méthode 1 - Configuration globale¶
Alias à mettre dans la conf locale¶
Fichier de conf ~/.gitconfig
[alias]
mr = !sh -c 'git fetch $1 merge-requests/$2/head:mr-$1-$2 && git checkout mr-$1-$2' -
Utilisation¶
Exemple, remote origin et merge-requests 123
git mr origin 123
Cela la créer la branche locale mr-origin-123
Méthode 2 - Configuration d'un dépôt spécifique (avec fetch possible)¶
Exemple actuel de la conf du dépôt local (dans le fichier .git/config
) :
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-foss.git
fetch = +refs/heads/*:refs/remotes/origin/*
Modifier le fichier de conf ou l'éditer avec la commande :
git config -e
Ajouter la configuration suivante :
fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
Ce qui donne la configuration complète suivante :
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-foss.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
Maintenant avec un fetch
nous avons la possibilité de voir les merge-requests :
git fetch origin
...
From https://gitlab.com/gitlab-org/gitlab-foss.git
* [new ref] refs/merge-requests/1/head -> origin/merge-requests/1
* [new ref] refs/merge-requests/2/head -> origin/merge-requests/2
...
Et pour faire un checkout :
git checkout origin/merge-requests/1
% Git diff, Git patch et Git email
Diff¶
-
Afficher les changements entre le dernier commit et les changements locaux
git diff
-
Afficher les changements entre deux commit
git diff tag1..tag2
Git Patch¶
Le but du présent tuto est de faire un patch d'un coté, puis de l'appliquer ailleur.
Exemple, un serveur possède des clés de déploiement, mais pas de push possible, alors que l'admin a les droit pour.
Création du patch¶
Sur le serveur, faire les modifications, add et commit, puis :
# Patch généré par rapport au dernier commit
git format-patch -o output HEAD^
# Patch généré entre plusieurs commit
# note, le patch est généré entre les deux ID, ce qui est dans ID_commit_debut n'est pas pris en compte
git format-patch <ID_commit_debut>..<ID_commit_fin>
-----
# Exemple - patch pour les commit 101 et 102
# Version n°3 du patch
# - commit 102 (intégré dans le patch)
# - commit 101 (intégré dans le patch)
# - commit 100 (non intégré dans le patch)
#
# Création des fichier suivants :
# - 0000-description
# - 0001-patch_commit_101
# - 0002-patch_commit_102
git format-patch --cover-letter -v3 -o output 100..102
-k
,--keep-subject
: Ne pas ajouter [PATCH] dans le sujet--stdout
: afficher la sortie dans la sortie standatd (stdout) au format mbox au lieu de créer un fichier de patch--cover-letter
: Ajouter un patch 0000 pour décrire les patch qui suivent (fichier à éditer ensuite)-o <dir>
,--output-directory <dir>
: répertroire de sortie-v<version>
: spécifier la version du patch (dans le cadre d'une demande de modif après refus de fusion)
Application du patch¶
Sur la station de l'admin, pour importer le patch avant de faire le push
# Méthode 1 - Application simple du patch en intégrant le commit (dont son numéro de commit)
git am file.patch
# Méthode 2 - Application du patch sans prendre en compte le commit
git apply mypatch.patch
-k
,--keep-subject
: Ne pas prendre en compte [PATCH] dans le sujet-3
,--3way
,--no-3way
: En cas d'échec, application du patch en 3 étapes (voir git-config)
Git email¶
Envoyer le patch précédent créé via email
Paquet requis¶
- git
- git-email
Envoyer le mail¶
git send-email --from <expéditeur> --to <destinataire> --cc <copie> <patch_a_envoyer>
git send-email --from me@example.com --to dest@example.com --cc dest-cc@example.com output/000*
# Once your commits are ready to be sent to the mailing list, run the following commands:
# $ git format-patch --cover-letter -M origin/master -o outgoing/
# $ edit outgoing/0000-*
# $ git send-email outgoing/*
Man à voir¶
- man git-diff
- man git-am
- man git-apply
- man git-config
- man git-mailinfo
- man git format-patch
- man git send-mail
% GIT - Options de clone
Cloner juste une branche¶
git clone --single-branch --branch social_contract_french https://salsa.debian.org/albanvidal-guest/debian-flyers.git
--branch <branche>
: indique la branche que l'on souhaite cloner--single-branch
: clone seulement la branche sélectionnée
Clone partiel (shallow clone)¶
# Cloner qu'un certain nombre de commit
git clone --depth 2 https://salsa.debian.org/debian/debian-flyers.git
# Cloner après une date
git clone --shallow-since=2019-02-01 https://salsa.debian.org/debian/debian-flyers.git
--depth <nombre>
: spécifie le nombre de commit que l'on veut synchroniser (shallow clone)--shallow-since=<date>
: clone partiel après la date (format AAAA-MM-JJ)
% GIT et la synchro d'un fork via le dépot amont
Nous avons :
- 1 dépot d'origine : https://git.example.com/projet/depot.git
- 1 dépôt de fork : https://git.example.com/my_name/depot.git
- On clone le dépôt de travail, le fork
git clone https://git.example.com/my_name/depot.git
- On a fait des modifications... ou non
- On veut synchroniser le dépôt amont (upstream) dans notre fork
-
Étapes :
-
Ajouter le dépôt upstream
git remote add upstream https://git.example.com/projet/depot.git
-
fetch
git fetch upstream
-
Au cas ou, on retourne dans la branche master
git checkout master
-
Deux solutions
- On merge la branche master upstream avec notre branche master
git merge upstream/master # ou git merge upstream/master master
-
On écrase la branche locale par la branche upstream
git rebase upstream/master
-
Synchro du dépôt distant avec la branche master mise à jour
% Sauvegarde fichiers sensiblesgit push origin master
Création du git local¶
mkdir /srv/.local-git
cd /srv/.local-git
git init
git config user.name "$HOSTNAME"
git config user.email "systemd-path@$HOSTNAME"
Commit initial¶
mkdir /srv/.local-git/etc
cp /etc/fstab /etc/hosts /srv/.local-git/etc
cd /srv/.local-git
git add .
git commit -m "Initial commit"
systemd.service git-crit-files.service¶
[Unit]
Description=Watch admin files alert
#Documentation=
[Service]
Type=oneshot
ExecStart=/usr/local/bin/git-crit-files
systemd.path git-crit-files.path¶
[Path]
PathChanged=/etc/fstab
PathChanged=/etc/hosts
[Install]
WantedBy=default.target
Script /usr/local/bin/git-crit-files¶
#!/bin/bash
# TODO :
# - vérifier si existe dans /etc
# - vérifier si existe sur le dépôt
local_git_dir="/srv/.local-git"
#list_files="
#/etc/fstab
#/etc/hosts
#"
list_files=$(awk -F'=' '/PathChanged/ {print $2}' /etc/systemd/system/git-crit-files.path)
cd $local_git_dir
for file in $list_files ; do
if ! diff -q $file ${file#/} ; then
# LOG
logger -t system-file-alert -p warning "File '$file' was changed"
# Copie dans le depot
cp $file $local_git_dir/$file
# Commit
git add $local_git_dir/$file
git commit -m "Update $file
Last 10 ssh logs:
$(journalctl --identifier=ssh-wrapper --no-pager --lines=10)
"
else
logger -t system-file-alert -p debug "File '$file' NOT changed"
fi
done
sshrc (/etc/ssh/sshrc)¶
ip=`echo $SSH_CONNECTION | cut -d " " -f 1`
# Test if ip arealy present
if ! grep $ip /tmp/list_ip_ssh_$USER >/dev/null 2>&1
then
#logger -t ssh-wrapper $USER login from $ip
logger -t ssh-wrapper -p warning $USER login from unknown ip: $ip - $(host $ip|awk '{print $5}')
#echo "User $USER just logged in from $ip - $(host $ip|awk '{print $5}')" |mail -s "New SSH Login to $USER in $(hostname)" admin-s3@zordhak.fr
# add the ip in temporary list
echo "$(date) - $ip" >> /tmp/list_ip_ssh_$USER
else
logger -t ssh-wrapper -p info $USER login from known ip: $ip
fi
Activation systemd.path¶
systemctl enable --now git-crit-files.path
% Annuler des commit avec GIT
Commit locaux (pas encore pushé)¶
- Annuler le dernier commit local
git log commit 101: bad commit # latest commit, this would be called 'HEAD' commit 100: good commit # second to last commit, this is the one we want # To restore everything back to the way it was prior to the last commit, # we need to reset to the commit before HEAD: git reset --soft HEAD^ # use --soft if you want to keep your changes git reset --hard HEAD^ # use --hard if you don't care about keeping the changes you made # Now git log will show that our last commit has been removed.
Annuler plusieurs commit locaux¶
git log
commit 102 : HS
commit 103 : HS
commit 104 : OK
# On veut annuler les commits jusqu'au 104
git reset --soft 104 # Annule les commit jusqu'au 104 mais garde les modifications
git reset --hard 104 # Annule les commit jusqu'au 104 ET SUPPRIME LES MODIFICATIONS
Commit public¶
# If you have already made your commits public,
# you will want to create a new commit which will "revert"
# the changes you made in your previous commit (current HEAD).
git revert HEAD
# Your changes will now be reverted and ready for you to commit:
git commit -m 'restoring the file I removed by accident'
git log
commit 102: restoring the file I removed by accident
commit 101: removing a file we don't need
commit 100: adding a file that we need
Plus d'info, voir :
Suppression d'un sous module¶
git submodule deinit lib/custom_submodule
git rm lib/custom_submodule
rm -Rf .git/modules/lib/custom_submodule
Signer ses clés avec git¶
git config --global commit.gpgsign true
git config --global tag.gpgsign true
git config --global user.signingkey KEY