2

There was a simple config with a bare central repository that had an 'update' hook script.

Now it's not central any more. It should poll central repository for changes.

How to make the hook script work in this situation?

One solution is to make an intermediate repository that will pull from central and will push to old-central. Other thoughts?

Velkan
  • 7,067
  • 6
  • 43
  • 87

2 Answers2

0

I know you didn't mention using Jenkins as a CI server in your question, but one common solution for this type of thing is to hook up a Jenkins job to your centralized Git repo using it's Git plugin.

You can have your script trigger when new commits are pushed to the repo.

See this post for more information on how jobs can be triggered upon pushes: How can I make Jenkins CI with git trigger on pushes to master?

Community
  • 1
  • 1
Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115
  • It's not hard (even easier) to trigger with cron. But if I trigger the fetch inside that repo, the hooks are not executed. If I trigger push to that repo, there needs to be a temporary repository to pull from central and then push. – Velkan Dec 08 '15 at 19:57
0

Got some useful clues from local git hook for “git remote update” question.

The idea is to update this repository with git remote update wrapped into a script that launches the post-receive hook. remote-update.sh:

#!/bin/bash

git_dir=$(git rev-parse --git-dir) || exit
cd "$git_dir"

declare -A before after all

# create the 'before' list
while read commit_hash refspec; do
    before[$refspec]="$commit_hash"
    all[$refspec]=''
done < <(git show-ref --heads)

# do the remote update
git remote update --prune

# create the 'after' list
while read commit_hash refspec; do
    after[$refspec]="$commit_hash"
    all[$refspec]=''
done < <(git show-ref --heads)

# see if there were any changes, and if so, run the post-receive hook
changes=0
for refspec in "${!all[@]}"; do
    [ "${before[$refspec]}" != "${after[$refspec]}" ] && { changes=1; break; }
done

if [ "$changes" == "1" ]; then
    none="$(printf "%0.s0" {1..40})" # forty zeroes, or git's "don't care" ref
    for refspec in "${!all[@]}"; do
        # if the refspec changed, pass it to the post-receive hook
        [ "${before[$refspec]}" != "${after[$refspec]}" ] && \
            echo "${before[$refspec]:-$none} ${after[$refspec]:-$none} $refspec"
    done | GIT_DIR="$git_dir" hooks/post-receive
fi

And since I've got only post-receive and update hooks, a partial (because it ignores errors) simulation of the update hook inside post-receive can go like that:

#!/bin/bash

while read oldrev newrev refname; do
    GIT_DIR="$GIT_DIR" hooks/update "$refname" "$oldrev" "$newrev"
done

Of course it can be done properly and prevent fetching on failures.

Any cleaner solutions?

Community
  • 1
  • 1
Velkan
  • 7,067
  • 6
  • 43
  • 87