Git предварительно получить крючок - PullRequest
8 голосов
/ 03 апреля 2010

Когда вы включаете pre-receive hook для git-репозитория:

Он не принимает аргументов, но для каждого обновляемого ссылки на стандартный ввод получает строку в формате:

<старое значение> SP <новое значение> SP LF

где - это старое имя объекта, сохраненное в ссылке, - это новое имя объекта, которое будет сохранено в ссылке, и полное имя ссылки. При создании новой ссылки равно 40 0.

Кто-нибудь может мне объяснить, как мне проверить все файлы, которые будут изменены в хранилище, если я разрешу этот коммит?

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

Спасибо.

Ответы [ 3 ]

19 голосов
/ 03 апреля 2010

Как ни странно, у меня был какой-то код из утилиты git -> Wordpress, который мог бы помочь. Ниже приведен список всех файлов, измененных в получении, а также их содержимое. Никаких гарантий, могут быть ошибки, возможно, не самый эффективный способ сделать это, бла-бла-бла. Часть этого кода основана на вещах из gitshelve , что является действительно отличной вещью, которую нужно рассмотреть для универсальной манипуляции с git.

import sys
import os
import subprocess

def git(args, **kwargs):
    environ = os.environ.copy()
    if 'repo' in kwargs:
        environ['GIT_DIR'] = kwargs['repo']
    if 'work' in kwargs:
        environ['GIT_WORK_TREE'] = kwargs['work']
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=environ)
    return proc.communicate()

def get_changed_files(base, commit, **kw):
    (results, code) = git(('git', 'diff', '--numstat', "%s..%s" % (base, commit)), **kw)
    lines = results.split('\n')[:-1]
    return map(lambda x: x.split('\t')[2], lines)

def get_new_file(filename, commit):
    (results, code) = git(('git', 'show', '%s:%s' % (commit, filename)))
    return results

repo = os.getcwd()
basedir = os.path.join(repo, "..")

line = sys.stdin.read()
(base, commit, ref) = line.strip().split()
modified = get_changed_files(base, commit)

for fname in modified:
    print "=====", fname
    print get_new_file(fname, commit)
10 голосов
/ 01 марта 2013

Я только что сделал это. Вот основной поток, который я использовал.

В вашем хуке предварительного получения прочитайте каждую строку из stdin, которая (как вы упомянули) выглядит следующим образом:

oldref newref refname
  1. Для каждой пары (oldref, newref) необходимо перечислить все коммиты:

    git show --format=format:%H --quiet oldref..newref
    
  2. для каждого коммита вам нужно перечислить все файлы:

    git diff --name-only commit^..commit
    
  3. , чтобы проверить файл, используйте git show:

    git show commit:filepath
    

    сделать любую проверку содержимого файла здесь. Если вы хотите уведомить пользователя о проблеме, напишите в stderr

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

Обратите внимание, что при таком подходе все коммиты идут по порядку, поэтому, если файл изменяется в нескольких коммитах, будет проверяться каждая версия. Если вы хотите просмотреть каждый файл только одним нажатием, просмотрите коммиты в обратном порядке и просто не проверяйте данный файл дважды. Однако я рекомендую первый подход, чтобы все версии отправляемых файлов были проверены.

1 голос
/ 02 февраля 2012

Если вы хотите узнать, изменяются ли права доступа к файлам в локальном репозитории до отправки в удаленный репозиторий, запустите git ls-tree -r commit, где commit - это значение SHA commit локального репозитория.

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

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