web-dev-qa-db-fra.com

Écrire un crochet post-réception git pour traiter une branche spécifique

Voici mon point d’accès actuel dans un dépôt dépouillé qui réside sur le serveur de la société: git Push Origin master Ce pointage pousse vers Assembla . Ce dont j’ai besoin est de ne pousser qu’une branche (maître, idéalement) lorsque l’on insère des modifications dans cette branche sur notre serveur, et ignorer les poussées vers d'autres branches. Est-il possible de sélectionner la branche depuis un dépôt nu et de pousser uniquement cette branche vers Assembla?

97
Jorge Guberte

Un hook post-réception tire ses arguments de stdin, sous la forme <oldrev> <newrev> <refname>. Étant donné que ces arguments proviennent de stdin, et non d'un argument de ligne de commande, vous devez utiliser read au lieu de $1 $2 $3.

Le hook post-réception peut recevoir plusieurs branches à la fois (par exemple, si quelqu'un effectue un git Push --all), nous devons donc aussi envelopper la read dans une boucle while.

Un extrait de travail ressemble à ceci:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" == "$branch" ]; then
        # Do something
    fi
done
363
pauljz

Le dernier paramètre qu'un hook post-réception obtient sur stdin est ce que ref a été modifié. Nous pouvons donc l'utiliser pour vérifier si cette valeur était "refs/heads/master". Un peu de Ruby semblable à ce que j'utilise dans un hook post-réception:

STDIN.each do |line|
    (old_rev, new_rev, ref_name) = line.split
    if ref_name =~ /master/
         # do your Push
    end
end

Notez qu'il reçoit une ligne pour chaque ref qui a été poussé, donc si vous avez poussé plus que simplement maître, cela fonctionnera toujours.

8
ebneter

La réponse de Stefan n'a pas fonctionné pour moi, mais this a:

#!/bin/bash

echo "determining branch"

if ! [ -t 0 ]; then
  read -a ref
fi

IFS='/' read -ra REF <<< "${ref[2]}"
branch="${REF[2]}"

if [ "master" == "$branch" ]; then
  echo 'master was pushed'
fi

if [ "staging" == "$branch" ]; then
  echo 'staging was pushed'
fi

echo "done"
6
Dean Rather

Aucune des solutions ci-dessus n'a fonctionné pour moi. Après beaucoup, beaucoup de débogage, il s’avère que l’utilisation de la commande 'read' ne fonctionne pas - à la place, l’analyse des arguments en ligne de commande fonctionne normalement.

Voici le hook exact post-mise à jour que je viens de tester avec succès maintenant sur CentOS 6.3.

#!/bin/bash

echo "determining branch"

branch=`echo $1 | cut -d/ -f3`

if [ "master" == "$branch" ]; then
    echo "master branch selected"
fi

if [ "staging" == "$branch" ]; then
    echo "staging branch selected"
fi

exec git update-server-info

UPDATE: sur une note encore plus étrange, le hook de pré-réception prend son entrée via stdin, donc lu avec 'read' (wow, je n'aurais jamais pensé dire ça). Le crochet post-mise à jour fonctionne toujours avec 1 $ pour moi.

3
razvan

La réponse de @pauljz fonctionne bien pour certains hooks git tels que pre-Push, mais pre-commit n'a pas accès à ces variables oldrev newrev refname

J'ai donc créé cette version alternative qui fonctionne en pré-commit, ou vraiment et en hook. Ceci est un hook pre-commit qui exécutera un script husky si nous ne sommes PAS sur la branche master.

#!/bin/bash
# git 'commit' does not have access to these variables: oldrev newrev refname
# So get the branch name off the head

branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName
branch=${branchPath##*/}      # Get text behind the last / of the branch path

echo "Head: $branchPath";
echo "Current Branch: $branch";

if [ "master" != "$branch" ]; then

   # If we're NOT on the Master branch, then Do something
   # Original Pre-Push script from husky 0.14.3

   command_exists () {
     command -v "$1" >/dev/null 2>&1
   }

   has_hook_script () {
     [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
   }

   cd "frontend" # change to your project directory, if .git is a level higher

   # Check if precommit script is defined, skip if not
   has_hook_script precommit || exit 0

   # Node standard installation
   export PATH="$PATH:/c/Program Files/nodejs"

   # Check that npm exists
   command_exists npm || {
     echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json"
     exit 0
   }

   # Export Git hook params
   export GIT_PARAMS="$*"

   # Run npm script
   echo "husky > npm run -s precommit (node `node -v`)"
   echo

   npm run -s precommit || {
     echo
     echo "husky > pre-commit hook failed (add --no-verify to bypass)"
     exit 1
   }
fi

J'espère que cela aide quelqu'un. Vous pouvez facilement modifier selon vos besoins tout ce qui se situe entre les instructions if et fi.

1
TetraDev

J'avais écrit un script PHP pour cette fonctionnalité.

https://github.com/fotuzlab/githubdump-php

Hébergez ce fichier sur votre serveur, de préférence repo root et définissez l'URL dans github webhooks. Modifiez «allcommits» à la ligne 8 avec le nom de votre succursale et ajoutez votre code/fonction à la ligne 18.

par exemple.

function githubdump($payload_object) {
    // Write your code here.
    exec('git Push Origin master');
}
0
fotuzlab

Approche simple, en git hook écriture

read refname
echo $refname

Simple - plus d'infos sur ce super lien système d'accrochage

0
Haris Krajina