Автоматическое копирование файлов из одного репозитория GitHub в другой

У меня есть два репозитория GitHub.

Я хотел бы автоматически (возможно, используя hooks И/или GitHub API) фиксировать и передавать файлы во второй репозиторий, когда они будут переданы в первый.

второй репозиторий не является клоном первого, их макет папки не обязательно одинаковый, есть только куча общих файлов.

каков самый простой способ сделать это?

бонусные баллы, если мне не нужно устанавливать http сервер или узнать perl:)

6 ответов


если вы ищете что-то надежное и простое в обслуживании, я призываю Вас разработать решения Веб-Перехватчиков На GitHub. Да, вам потребуется развернуть HTTP-сервер, скажем узел.сервер JS, и это потребует небольшого количества разработки (ваши требования довольно специфичны), но я думаю, что это окупится, если вам нужно что-то надежное и низкое обслуживание. То есть, если вы решите, что этот подход к зеркальному отображению файлов по-прежнему является правильным, рассмотрев подходы и подготовительные усилия.

пусть исходные репозитории (на GitHub) будут S1, S2 ... с (неперекрывающимися) наборами файлов для зеркального отображения F1, F2 ..., для отправки в целевое РЕПО T (также на GitHub), где соответствующие файлы считаются только для чтения. Ваши требования необычны в этом Sn и T звучит так, как будто они не клонированы друг от друга, они могут даже не иметь общей фиксации, и в этом случае это не сценарий push/fetch. Вы также не гарантировали, что исходные обновления файлов происходят по одному на фиксацию или даже сгруппированы, но изолированы от нереплицирующихся изменений, поэтому речь идет не о фиксации выбора вишни.

триггер для репликации находится на push определенных файлов в S1, S2 ..., не фиксация на любом клоне разработчика этих репозиториев, поэтому крючки на стороне клиента не помогут (и их может быть неудобно поддерживать). GitHub, конечно, не позволяет общие крючки, поэтому веб-крючки твое лучшее решение. Вы можете рассмотреть другой, опросный клон, который регулярно тянет из S1 ..., выполняя логику, а затем совершая T, но это звучит неудобно по сравнению с Webhooks, которые дадут вам надежную доставку, возможность воспроизведения, достойный аудиторский след и т. д.

плюс в том, что существует много уже построенной инфраструктуры для поддержки этого типа настройки, поэтому фактический код, который вам нужно будет написать, может быть довольно маленьким. Скажем, вы идете с Node.js тип настройка:

  • развернуть GitHub-webhook-handler. Эта классная маленькая библиотека является встроенным обработчиком для GitHub Webhooks и обрабатывает HMAC X-Hub-Signature проверка и обеспечивает простые крючки прослушивателя событий для всех событий Webhooks. У вас может быть одна конечная точка в секунду, или, вероятно, легче их веером.
  • имейте некоторый локальный файл (держите его в репозитории Git), который отображает Sn to Fn.
  • зарегистрируйте обработчик для X-GitHub-Event: push, и проверить repository/name и commits[]/modified[] для путей, соответствующих вашей локальной карте.
  • развернуть узел-github реализация GitHub APIv3 для узла.js.
  • для каждого соответствующего файла:
    • вызов getblob был читать utf-8 или base64 копия файла из Sn.
    • вызов createBlob для повторного создания этого файла в T.
    • сделайте серию звонков в T to getReference (текущий коммит), getTree, createTree (создайте новый из базы и нового blob),createCommit и наконец updateReference . Это один рабочий процесс-более низкое столкновение - это ветвление / слияние.

этот подход позволяет вам делать все, не нуждаясь в локальном клоне T. Возможно, вам лучше использовать локальный клон, я бы посмотрел, как легкие вещи идут с методом API в первую очередь.

enter image description here


У нас была аналогичная проблема - мы хотели автоматически копировать файлы документации между репозиториями проекта и общей документации. Мы создали инструмент, который слушает веб-крючки GitHub, анализирует коммиты и создает запрос на вытягивание в выбранное место назначения. Copycat schema Мы с открытым исходным кодом -https://github.com/livechat/copycat - его можно использовать на любом сервере платформы узла.


редактировать: теперь я понимаю, что вопрос был о GitHub. Мой ответ касается стандартного репозитория git, к которому у вас есть доступ к файлам.

Я предполагаю, что второе РЕПО является клоном первого, созданным что-то вроде этого

git clone --bare first.git second.git

изменить текущий каталог на внутри first.git репозиторий, и добавить second.git как пульт дистанционного управления.

cd first.git
git remote add second ../second.git

затем создайте файл в папке first.git/hooks/ имени post-receive (вы можете переименовать post-receive.sample файл уже там)

содержание должно быть таким

#!/bin/sh
git push second

теперь, когда вы нажимаете новые коммиты в первый репозиторий, толчок от первого до второго будет выполняться немедленно, так что также второй получает коммиты.


два репозитория GitHub (без стороннего сервера, прослушивающего события webhook) не могут отражать друг друга.

вам нужно будет зарегистрировать веб-перехватчик на одном репозитории GitHub для обнаружения события push и нажмите на второе репозиторий GitHub.

это означает наличие сервера, который прослушивает webhook полезная нагрузка json.

инструмент dustin/gitmirror может помочь (в Go).


поскольку у вас есть другое РЕПО, вы можете попытаться применить коммиты один за другим с помощью git-apply/git-am, а затем нажать.

если у вас есть Repo1.git и Repo2 на сервере, Repo1.git-это голый репозиторий, Repo2-это локальный клон вашего второго репозитория.

Repo1/.git/hooks/post-receive

#!/bin/sh
t=$(mktemp)
repo2_directory=/some/place/you/cloned/repo2
error=
while read line; do
  ref1=$(echo "$line"|cut -d' ' -f1)
  ref2=$(echo "$line"|cut -d' ' -f2)
  for ref in $(git log --oneline $ref1..$ref2); do
    git show -p --no-color --binary $ref > $t
    if !(cd $repo2_directory && git am -q < $t || (git am --abort; false)); then
      echo "Cannot apply $ref" >&2
      error=1
      break
    fi
  done
  [ -n "$error" ] && break
done
rm -f $t
[ -z "$error" ] && (cd $repo2_directory && git push)

простой способ сделать это-добавить два (или более) pushurls до origin (или какой-то другой пульт).

например:

git remote set-url --add --push origin url1
git remote set-url --add --push origin url2

он не сильно меняется на чей-либо рабочий процесс, но все толчки по-прежнему эффективно дублируются для обоих репозиториев. Это объясняется гораздо более подробно здесь.

если у вас много людей, работающих над одним и тем же РЕПО, и вы хотите, чтобы их изменения отражались, попробуйте запустить скрипт для назначения нового pushurls для каждый разработчик. В противном случае, боюсь, вам придется использовать hooks + server.