Ah ben j'ai pas mal d'alias, ou de fonctions bash, de workflow git chez moi.
J'ai même un .bashrc.git inclus dans le .bashrc général pour mettre ça dans un endroit séparé.
Par exemple, tu bosses sur ton clone gitlub, et tu fais des PR sur l'origine gitlub aussi, il faut régulièrement remettre ta branche master/main à jour depuis l'origine.
Alors :
function gitmaster(){
git status -bsuno | head -1 | sed -r 's/## ([^.]*).*/\1/'localmaster=main
git checkout master &&master=master || git checkout main
git fetch upstream
git rebase upstream/$master
git push
}
Qui s'adapte en fonction de master/main, et t'affiche en haut le nom de la branche d'où tu es parti.
Typiquement derrière tu peux faire un git checkout ma_branche_de_travail; git rebase/merge master
J'ai aussi des alias simples comme :
aliasgitdiff="git diff --ignore-space-change --ignore-blank-lines"aliasgitstatus="git status -bsuno"
Après, quand j'ai commencé à bosser sur mainster, et qu'il est temps de commiter, j'ai pas encore de branche, alors j'ai ça, avec sa version tout intégré une branche, un commit avec le même texte que le nom de la branche vaguement mis en forme, pas de choix des fichiers à commiter, ie tu commites tout ce que tu as modifié, un push, et yapluka faire la PR sur gitlub :
function gitnewbranch(){
git stash
gitmaster # la fonction plus haut pour synchro mon master avec celui de l'origine
git checkout -b "$1"
git stash pop
}function gitsimplebranch(){localbranchname="$(sed 's/*/⚹/g'<<<"$1")"
gitnewbranch "$branchname"
git commit -am "$(tr _ \ <<<"$1")"
git push --set-upstream origin "$branchname"}
Et pour le « oups j'ai commité/pushé trop tôt », j'ai aussi ça :
Cette fonction est un condensé de conneries à ne pas faire : déjà on ne reprend que la première ligne du commit, ensuite on commite tous les fichiers modifiés sans réfléchir, et enfin on écrase un commit déjà envoyé sur le dépôt central, donc public, un vrai bonheur de goret !
Ça se marie bien avec la gitsimplebranch de plus haut où le message ne fait qu'une ligne et équivaut au nom de la branche, et quand on pushe sur notre clone perso, c'est public mais pas trop, assez pratique pour débugger depuis le gitlub (des fois qu'il y ait une CICD automagique derrière) avant de faire la PR évidemment.
Il veut pouvoir mettre le caractère ⚹ dans un nom de branche en le tapant plus facilement en utilisant * qui est directement accessible sur le clavier mais ne veut pas que la commande git l'interprète comme un glob pattern.
Oh un copain qui fait beaucoup trop de choses avec git comme moi !
Tu me permet quelques remarques ? Je suis optimiste, je vais considérer que c'est oui.
function gitmaster(){
git status -bsuno | head -1 | sed -r 's/## ([^.]*).*/\1/'localmaster=main
git checkout master &&master=master || git checkout main
git fetch upstream
git rebase upstream/$master
git push
}
Je comprends pas le master=master, il sert à quoi ?
±a vaut le coup je trouve de faire git rev-parse --abbrev-ref HEAD pour avoir le nom de ta branche, c'est un peu ésothérique mais c'est plus solide que parser la sortie de git (quand on peut l'éviter).
Quand je peux j'évite de faire des checkout, du coup de fais simplement :
git fetch -a
git rebase origin/master
git force
git force est un alias git force = push --force-with-lease. Comme ça j'ai l'hébitude de faire git force et pas de push -f.
Ca permet de choisir avec quel commit de ma branche les changements en cours vont être fusionnés. Ca demande un coup de git rebase -i origin/master pour être appliqué ensuite (j'ai l'option rebase.autoStash = true activé).
Dernier trucs pour le fun. Si j'ai un git wip qui commit les changements en cours dans un commit wip. J'ai un alias ragequit = !sh -c 'git commit -am wip && shutdown -h now' plus expéditif encore.
localmaster=main
git checkout master &&master=master || git checkout main
Il faut voir les deux lignes :
* on crée une variable $master qui vaut "main" ;
* on tente de checkout master ;
* si ça fonctionne on remplace la valeur de $master par "master" ;
* sinon on checkout main ;
* ça permet juste après de faire le git rebase upstream/$master avec le bon nom de branche.
À la fin la variable $master vaut le nom de ta branche de base, soit master pour les vieux dépôts, soit main pour les plus récents.
Vu que master n'est plus politiquement correct, même en dehors de la terminologie douteuse de master/slave.
Bref, c'est pragmatique, pas politique, j'ai affaire à des dépôts où la branche main s'appelle master et d'autres où la branche master s'appelle main. Enfin un truc du genre.
git rev-parse --abbrev-ref HEAD : T'as raison, ça marche bien, c'est plus propre !
Concernant le checkout plutôt que fetch, ici je fais ça :
* afficher le nom de la branche courante pour référence visuelle ;
* basculer sur mainster ;
* mettre à jour depuis origin/mainster ;
* pousser la mise à jour sur son dépôt gitlub.
Donc on bascule sur mainster, et on synchronise son dépôt perso avec l'origine. On pourrait aller sur l'interface de gitlub et faire une synchro là-bas, puis fetch/checkout localement, mais là c'est une seule commande dans mon terminal qui fait tout.
Ça évite d'aller clicouiller sur un site web…
Ok, en général je refais un checkout de ma branche et je rebase/merge depuis mainster, mais disons que jusqu'à présent j'ai jugé que l'automatisation de l'étape de synchro/mise à jour de mainster était suffisante pour mon besoin.
Ça me sert souvent pour mettre à jour des dépôts sur lesquels je bosse peu, mais dont je peux avoir besoin de la version à jour. Je suis en général déjà sur mainster, et je pourrais faire du fetch/checkout directement, mais faudrait vérifier qu'on n'est pas par hasard sur une branche, etc.
Disons que la commande gitmaster me ramène dans un état nominal permettant de démarrer un développement, et est la seule que j'adapte à la polémique master/main.
gitrepush: Ouaip, la fonction est pas clean. Je n'ai jamais cherché le --amend mais en effet ça sert pile à ça.
On pourrait donc simplifier en :
function gitrepush(){
git commit -a --amend --no-edit
git force
}# Ou plus simplealiasgitrepush="git commit -a --amend --no-edit && git force"
J'aime bien ton ragequit :)
J'aurais plutôt mis un loginctl suspend :)
À la fin la variable $master vaut le nom de ta branche de base, soit master pour les vieux dépôts, soit main pour les plus récents.
Aaaah ! Je comprends et je comprends du coup "mainster".
Pour les problématiques "multi dépôts". J'avoue ne pas trop avoir le besoin. Tous les dépôts où je travaille sont configurés de manière identique et les autres je les manipule tellement peu que je m'en fou de devoir taper des commandes un peu plus longues.
Après comme ça s'appuie sur des usages ça s'appuie aussi beaucoup sur tout un tas d'autres configurations git, mais aussi de mon shell qui m'affiche le nom des branches dans les quels je suis dans le prompt.
Après j'essaie de garder des automatisations plus petites et de m'appuyer massivement sur mon shell (mais je suis entrain de voir pour faire une exception avec un outil qui intéragis avec git, mais aussi les apis de gitlab pour générer pour moi les noms de branches comme je veux).
C'est pour ça que je préfère garder :
git ff && git force
mais c'est une question de goût.
J'aurais plutôt mis un loginctl suspend :)
J'éteins toujours mes machines, mais je fais plus "systemctl poweroff" que shutdown maintenant.
Si je comprend bien ta fonction gitmaster(), c'est pour synchroniser la branche master/mainsur laquelle tu ne travaille pas (bonne pratique importante pour le code suivant) avec upstream.
Si cela est le cas, tu peux le faire sans faire un checkout (et donc de façon plus pratique):
# Fetch from upstream
git fetch upstream
# get hash of upstream/masterhash="$(git rev-parse upstream/master)"# update 'master' without doing a checkout
git push . "$hash:refs/heads/master"# push to origin
git push origin master
Ben ça peut aussi être pour démarrer un nouveau développement.
Je me met sur une master propre et bien mise à jour et de là je crée une branche de travail.
J'ai indiqué la fonction gitnewbranch plus haut, qui en interne fait en gros git stash && gitmaster && git checkout -b ma_branche && git stash pop.
Et parfois juste pour voir où en est master, lire le code d'un dépôt sur lequel je ne travaille pas.
Bon, faut dire, dans mon boulot on a une centaine de repo actif en 2023, sur 170 au total (bigre, tout de même ? je pensais pas avant de regarder, doit y'avoir pas mal de déchets quand même), et je bosse sur quelques-uns, et j'ai de temps en temps à regarder le code de quelques autres, j'en ai 40 clonés à un moment où à un autre, et 22 forkés sur mon gitlub interne, donc pour lesquels j'ai fait au moins une PR à un moment où à un autre.
À noter que gitmaster fonctionne aussi si on a simplement cloné upstream sans fork perso, ça va râler sur le fetch upstream et le rebase, le push n'aura rien à faire, mais on aura fait notre checkout de master, et sans savoir si on a un fork perso ou pas :)
Autant dire que la commande « mets-moi ce dépôt localement à jour, sur la branche de base, dans un état synchronisé avec un éventuel fork perso, et prêt pour un nouveau dev » sans poser d'autres questions, elle est bien pratique…
Mon commentaire était pour indiquer qu'on peut détourner la commande 'push' pour modifier/mettre à jour une branche locale sans être obligé de faire un checkout (qui peut être pénible et lent si la branche courante a pas mal divergé) et que cette solution (que peu connaissent), qui peut être adaptée pour gérer ton 2ème cas, est beaucoup plus performante car l'update de la branche est instantané (seul le fetch et push final prennent du temps) et a moins de chance d'échouer (car on a pas à gérer les cas particuliers du checkout --changes local, merge conflicts,… --)
on peut détourner la commande 'push' pour modifier/mettre à jour une branche locale sans être obligé de faire un checkout (qui peut être pénible et lent si la branche courante a pas mal divergé)
J'avoue que je ne connaissais pas. Généralement j'évite les checkout en me référençant à la branche distante du genre :
git fetch
git rebase origin/${branch}
git push --force-with-lease
J'ai pas trouvé la description du point dans la doc de git push, j'imagine que ça représente le "remote" local ?
'ai pas trouvé la description du point dans la doc de git push, j'imagine que ça représente le "remote" local ?
Comme remote, on peut donner l'url d'un depot qui peut être un chemin local. Ici, on utilise le répertoire courant '.' comme "remote" et on fait donc un push dans notre propre dépot local pour mettre à jour une ref de branche avec le hash d'un commit.
Je viens d'essayer du coup ça marche bien avec des noms plus simples.
Au lieu de :
# Fetch from upstream
git fetch upstream
# get hash of upstream/masterhash="$(git rev-parse upstream/master)"# update 'master' without doing a checkout
git push . "$hash:refs/heads/master"
Je peux faire :
# Fetch from upstream
git fetch upstream
# update 'master' without doing a checkout
git push . upstream/master:master
# Du gitcode à partager - ou pas
Posté par Yth (Mastodon) . Évalué à 9.
Ah ben j'ai pas mal d'alias, ou de fonctions bash, de workflow git chez moi.
J'ai même un .bashrc.git inclus dans le .bashrc général pour mettre ça dans un endroit séparé.
Par exemple, tu bosses sur ton clone gitlub, et tu fais des PR sur l'origine gitlub aussi, il faut régulièrement remettre ta branche master/main à jour depuis l'origine.
Alors :
Qui s'adapte en fonction de master/main, et t'affiche en haut le nom de la branche d'où tu es parti.
Typiquement derrière tu peux faire un
git checkout ma_branche_de_travail; git rebase/merge master
J'ai aussi des alias simples comme :
Après, quand j'ai commencé à bosser sur mainster, et qu'il est temps de commiter, j'ai pas encore de branche, alors j'ai ça, avec sa version tout intégré une branche, un commit avec le même texte que le nom de la branche vaguement mis en forme, pas de choix des fichiers à commiter, ie tu commites tout ce que tu as modifié, un push, et yapluka faire la PR sur gitlub :
Et pour le « oups j'ai commité/pushé trop tôt », j'ai aussi ça :
Cette fonction est un condensé de conneries à ne pas faire : déjà on ne reprend que la première ligne du commit, ensuite on commite tous les fichiers modifiés sans réfléchir, et enfin on écrase un commit déjà envoyé sur le dépôt central, donc public, un vrai bonheur de goret !
Ça se marie bien avec la gitsimplebranch de plus haut où le message ne fait qu'une ligne et équivaut au nom de la branche, et quand on pushe sur notre clone perso, c'est public mais pas trop, assez pratique pour débugger depuis le gitlub (des fois qu'il y ait une CICD automagique derrière) avant de faire la PR évidemment.
[^] # Re: Du gitcode à partager - ou pas
Posté par gUI (Mastodon) . Évalué à 4.
Pas mal ces petits outils !
Tu pourrais expliquer le coup du
local branchname="$(sed 's/*/⚹/g' <<< "$1")"
?En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Du gitcode à partager - ou pas
Posté par Psychofox (Mastodon) . Évalué à 8.
Il veut pouvoir mettre le caractère ⚹ dans un nom de branche en le tapant plus facilement en utilisant * qui est directement accessible sur le clavier mais ne veut pas que la commande git l'interprète comme un glob pattern.
[^] # Re: Du gitcode à partager - ou pas
Posté par gUI (Mastodon) . Évalué à 4.
Tout simplement, merci !
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Du gitcode à partager - ou pas
Posté par Yth (Mastodon) . Évalué à 3.
Exactement, et comme jusqu'à présent c'est le seul caractère qui m'a posé des soucis, c'est le seul qui a droit à un cas particulier.
[^] # Re: Du gitcode à partager - ou pas
Posté par barmic 🦦 . Évalué à 6.
Oh un copain qui fait beaucoup trop de choses avec git comme moi !
Tu me permet quelques remarques ? Je suis optimiste, je vais considérer que c'est oui.
Je comprends pas le master=master, il sert à quoi ?
±a vaut le coup je trouve de faire
git rev-parse --abbrev-ref HEAD
pour avoir le nom de ta branche, c'est un peu ésothérique mais c'est plus solide que parser la sortie de git (quand on peut l'éviter).Quand je peux j'évite de faire des checkout, du coup de fais simplement :
git force
est un alias gitforce = push --force-with-lease
. Comme ça j'ai l'hébitude de fairegit force
et pas depush -f
.Ca me parait super compliqué pour faire :
que j'ai bien sûr alias en
L'alias que je trouve trop cool c'est :
Ca permet de choisir avec quel commit de ma branche les changements en cours vont être fusionnés. Ca demande un coup de
git rebase -i origin/master
pour être appliqué ensuite (j'ai l'optionrebase.autoStash = true
activé).Dernier trucs pour le fun. Si j'ai un
git wip
qui commit les changements en cours dans un commitwip
. J'ai un aliasragequit = !sh -c 'git commit -am wip && shutdown -h now'
plus expéditif encore.https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Du gitcode à partager - ou pas
Posté par Yth (Mastodon) . Évalué à 3.
Il faut voir les deux lignes :
* on crée une variable $master qui vaut "main" ;
* on tente de checkout master ;
* si ça fonctionne on remplace la valeur de $master par "master" ;
* sinon on checkout main ;
* ça permet juste après de faire le
git rebase upstream/$master
avec le bon nom de branche.À la fin la variable $master vaut le nom de ta branche de base, soit master pour les vieux dépôts, soit main pour les plus récents.
Vu que master n'est plus politiquement correct, même en dehors de la terminologie douteuse de master/slave.
Bref, c'est pragmatique, pas politique, j'ai affaire à des dépôts où la branche main s'appelle master et d'autres où la branche master s'appelle main. Enfin un truc du genre.
git rev-parse --abbrev-ref HEAD
: T'as raison, ça marche bien, c'est plus propre !Concernant le checkout plutôt que fetch, ici je fais ça :
* afficher le nom de la branche courante pour référence visuelle ;
* basculer sur mainster ;
* mettre à jour depuis origin/mainster ;
* pousser la mise à jour sur son dépôt gitlub.
Donc on bascule sur mainster, et on synchronise son dépôt perso avec l'origine. On pourrait aller sur l'interface de gitlub et faire une synchro là-bas, puis fetch/checkout localement, mais là c'est une seule commande dans mon terminal qui fait tout.
Ça évite d'aller clicouiller sur un site web…
Ok, en général je refais un checkout de ma branche et je rebase/merge depuis mainster, mais disons que jusqu'à présent j'ai jugé que l'automatisation de l'étape de synchro/mise à jour de mainster était suffisante pour mon besoin.
Ça me sert souvent pour mettre à jour des dépôts sur lesquels je bosse peu, mais dont je peux avoir besoin de la version à jour. Je suis en général déjà sur mainster, et je pourrais faire du fetch/checkout directement, mais faudrait vérifier qu'on n'est pas par hasard sur une branche, etc.
Disons que la commande gitmaster me ramène dans un état nominal permettant de démarrer un développement, et est la seule que j'adapte à la polémique master/main.
gitrepush: Ouaip, la fonction est pas clean. Je n'ai jamais cherché le --amend mais en effet ça sert pile à ça.
On pourrait donc simplifier en :
J'aime bien ton ragequit :)
J'aurais plutôt mis un loginctl suspend :)
[^] # Re: Du gitcode à partager - ou pas
Posté par barmic 🦦 . Évalué à 3.
Aaaah ! Je comprends et je comprends du coup "mainster".
Pour les problématiques "multi dépôts". J'avoue ne pas trop avoir le besoin. Tous les dépôts où je travaille sont configurés de manière identique et les autres je les manipule tellement peu que je m'en fou de devoir taper des commandes un peu plus longues.
Après comme ça s'appuie sur des usages ça s'appuie aussi beaucoup sur tout un tas d'autres configurations git, mais aussi de mon shell qui m'affiche le nom des branches dans les quels je suis dans le prompt.
Après j'essaie de garder des automatisations plus petites et de m'appuyer massivement sur mon shell (mais je suis entrain de voir pour faire une exception avec un outil qui intéragis avec git, mais aussi les apis de gitlab pour générer pour moi les noms de branches comme je veux).
C'est pour ça que je préfère garder :
mais c'est une question de goût.
J'éteins toujours mes machines, mais je fais plus "systemctl poweroff" que shutdown maintenant.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Du gitcode à partager - ou pas
Posté par alberic89 🐧 . Évalué à 1.
Il y a donc une commande pour ça ! Mais alors, à quoi sert le gros bouton à côté de l'alimentation ?
L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès
[^] # Re: Du gitcode à partager - ou pas
Posté par cosmocat . Évalué à 3.
Si je comprend bien ta fonction
gitmaster()
, c'est pour synchroniser la branchemaster/main
sur laquelle tu ne travaille pas (bonne pratique importante pour le code suivant) avec upstream.Si cela est le cas, tu peux le faire sans faire un checkout (et donc de façon plus pratique):
[^] # Re: Du gitcode à partager - ou pas
Posté par cosmocat . Évalué à 3.
Note: la màj de
master
echoue si ce n'est pas un fast-forward (et c'est ce qu'on veut)[^] # Re: Du gitcode à partager - ou pas
Posté par Yth (Mastodon) . Évalué à 2.
Ben ça peut aussi être pour démarrer un nouveau développement.
Je me met sur une master propre et bien mise à jour et de là je crée une branche de travail.
J'ai indiqué la fonction gitnewbranch plus haut, qui en interne fait en gros
git stash && gitmaster && git checkout -b ma_branche && git stash pop
.Et parfois juste pour voir où en est master, lire le code d'un dépôt sur lequel je ne travaille pas.
Bon, faut dire, dans mon boulot on a une centaine de repo actif en 2023, sur 170 au total (bigre, tout de même ? je pensais pas avant de regarder, doit y'avoir pas mal de déchets quand même), et je bosse sur quelques-uns, et j'ai de temps en temps à regarder le code de quelques autres, j'en ai 40 clonés à un moment où à un autre, et 22 forkés sur mon gitlub interne, donc pour lesquels j'ai fait au moins une PR à un moment où à un autre.
À noter que gitmaster fonctionne aussi si on a simplement cloné upstream sans fork perso, ça va râler sur le fetch upstream et le rebase, le push n'aura rien à faire, mais on aura fait notre checkout de master, et sans savoir si on a un fork perso ou pas :)
Autant dire que la commande « mets-moi ce dépôt localement à jour, sur la branche de base, dans un état synchronisé avec un éventuel fork perso, et prêt pour un nouveau dev » sans poser d'autres questions, elle est bien pratique…
[^] # Re: Du gitcode à partager - ou pas
Posté par cosmocat . Évalué à 3.
Mon commentaire était pour indiquer qu'on peut détourner la commande 'push' pour modifier/mettre à jour une branche locale sans être obligé de faire un checkout (qui peut être pénible et lent si la branche courante a pas mal divergé) et que cette solution (que peu connaissent), qui peut être adaptée pour gérer ton 2ème cas, est beaucoup plus performante car l'update de la branche est instantané (seul le fetch et push final prennent du temps) et a moins de chance d'échouer (car on a pas à gérer les cas particuliers du checkout --changes local, merge conflicts,… --)
[^] # Re: Du gitcode à partager - ou pas
Posté par barmic 🦦 . Évalué à 3.
J'avoue que je ne connaissais pas. Généralement j'évite les checkout en me référençant à la branche distante du genre :
J'ai pas trouvé la description du point dans la doc de git push, j'imagine que ça représente le "remote" local ?
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Du gitcode à partager - ou pas
Posté par cosmocat . Évalué à 4.
Comme remote, on peut donner l'url d'un depot qui peut être un chemin local. Ici, on utilise le répertoire courant '.' comme "remote" et on fait donc un push dans notre propre dépot local pour mettre à jour une ref de branche avec le hash d'un commit.
[^] # Re: Du gitcode à partager - ou pas
Posté par barmic 🦦 . Évalué à 4.
Ah oui ! Je vois. C'est super cool.
Je viens d'essayer du coup ça marche bien avec des noms plus simples.
Au lieu de :
Je peux faire :
Merci beaucoup pour l'astuce !
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Du gitcode à partager - ou pas
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2.
Les alias, pour ma part, je fais ça au niveau de Git et non du shell.
“It is seldom that liberty of any kind is lost all at once.” ― David Hume
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.