it-swarm.com.de

Schreiben eines Git-Post-Receive-Hooks für einen bestimmten Zweig

Hier ist mein aktueller Hook in einem nackten Repo, der auf dem Server des Unternehmens lebt: git Push Origin master Dieser Haken drückt auf Assembla . Was ich brauche, ist, nur einen Zweig (Master, idealerweise) zu drücken, wenn jemand Änderungen drückt dieser Zweig auf unserem Server und ignoriert Pushs an andere Zweige. Ist es möglich, den Zweig aus einem reinen Repo auszuwählen und nur diesen Zweig nach Assembla zu verschieben?

97
Jorge Guberte

Ein Post-Receive-Hook erhält seine Argumente von stdin in der Form <oldrev> <newrev> <refname>. Da diese Argumente von stdin stammen und nicht von einem Befehlszeilenargument, müssen Sie read anstelle von $1 $2 $3 verwenden.

Der Post-Receive-Hook kann mehrere Verzweigungen gleichzeitig empfangen (beispielsweise, wenn jemand einen git Push --all ausführt), sodass wir die read auch in eine while-Schleife einschließen müssen.

Ein funktionierendes Snippet sieht ungefähr so ​​aus:

#!/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

Der letzte Parameter, den ein Post-Receive-Hook für stdin erhält, ist der, was ref geändert hat. Daher können wir mit diesem Parameter prüfen, ob der Wert "refs/heads/master" war. Ein bisschen Ruby ähnlich dem, was ich in einem Post-Receive-Hook verwende:

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

Beachten Sie, dass für jeden gesetzten Ref eine Zeile abgerufen wird. Wenn Sie also mehr als nur Master gedrückt haben, funktioniert es trotzdem.

8
ebneter

Stefans Antwort funktionierte nicht für mich, aber das tat:

#!/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

Keine der oben genannten Lösungen funktionierte für mich. Nach vielem, vielem Debuggen stellt sich heraus, dass die Verwendung des Befehls 'read' nicht funktioniert - stattdessen funktioniert das Analysieren von Befehlszeilenargumenten wie üblich.

Hier ist der genaue Hook nach dem Update, den ich gerade erfolgreich auf CentOS 6.3 getestet habe.

#!/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: der seltsamere Hinweis: Der Pre-Receive-Hook nimmt seine Eingabe über stdin auf und kann daher mit 'read' gelesen werden (wow, hätte nie gedacht, dass ich das sagen würde). Der Hook nach dem Update funktioniert immer noch mit $ 1 für mich.

3
razvan

Die Antwort von @pauljz funktioniert gut für bestimmte Git-Hooks wie pre-Push, aber pre-commit hat keinen Zugriff auf diese Variablen oldrev newrev refname

Also habe ich diese alternative Version erstellt, die für Pre-Commit oder wirklich und Hook funktioniert. Dies ist ein pre-commit-Hook, der ein husky-Skript ausführt, wenn wir NICHT im Zweig master sind.

#!/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

Ich hoffe das hilft jemandem. Sie können leicht zwischen Ihren Anweisungen if und fi für Ihre Anforderungen modifizieren.

1
TetraDev

Ich hatte ein PHP -Skript geschrieben, um diese Funktion auszuführen.

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

Hosten Sie diese Datei auf Ihrem Server, vorzugsweise repo root, und definieren Sie die URL in github webhooks. Ändern Sie 'allcommits' in Zeile 8 mit Ihrem Zweignamen und fügen Sie Ihren Code/Funktion in Zeile 18 hinzu.

z.B.

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

Einfacher Ansatz in git hook write

read refname
echo $refname

Einfach - mehr Infos zu diesem tollen Link Hooking System

0
Haris Krajina