2016-02-28 7 views
1

Итак, единственное, что я использую, это пост-прием. Когда я редактирую этот файл на моем клиенте, я хочу, чтобы он автоматически обновлялся, когда я нажимаю на сервер.Как автоматически обновлять git-крючки?

Я пробовал 3 вещи, все из которых не работали. В посте-получить крючки я

  1. символический связан с файлом в репо
  2. трудно, связанный с файлом в репо
  3. наконец, скопировать файл из репозитория в каталог крючков.

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

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

Есть ли способ defacto для этого?

ответ

1

Одна из возможностей будет для post-receive крюка:

  • обнаружить, что post-receive сценарий является частью того, что проталкивается.
    (См "git post-receive hook to check files": git diff --name-only $1..$2|grep post-receive)
  • сделать копию в .git/hook/post-receive.new

Затем вы устанавливаете pre-receive крюк, который просто проверить на .git/hook/post-receive.new и переименовании его в качестве .git/hook/post-receive.
(Значение post-receive.new исчезают, а следующее pre-receive исполнения крюка будет делать ничего)

Таким образом, крюк не обновляется сразу, но она будет обновлена ​​в следующем git push к тому же Сделки рЕПО.


Примечание: Я думал об обнаружении и обновлении модификации post-receive файла непосредственно во время выполнения pre-receive крючка, но, как пояснил torek в «Git pre-receive hook to check config», это не тривиально:

pre-receive или update hook вызывается после того, как новые объекты (коммиты, объекты аннотированных тегов, деревья и капли) были загружены в репозиторий, но до того, как были изменены ссылки (имена ветвей, имена тегов и т. д.).

Вам необходимо, чтобы каждый ref нажал, чтобы проверить и проверить наличие и содержимое этого файла.
Это не невозможно, так как seen in this php script:

function get_changed_files($base, $commit) { 
    list($code, $stdout, $stderr) = git('diff', '--numstat', '--name-only', '--diff-filter=ACMRTUXB', '--ignore-submodules', "{$base}..{$commit}"); 
    ... 
    return explode("\n", $stdout); 
} 
function get_new_file($filename, $commit) { 
    list($code, $stdout, $stderr) = git('show', "{$commit}:{$filename}"); 
    ... 
    return $stdout; 
} 
... 
$line = file_get_contents('php://stdin'); 
list($base, $commit, $ref) = explode(" ", trim($line)); 
if ($base == "0000000000000000000000000000000000000000") { 
    verbose("Initial push received. Expecting everything to be fine"); 
    exit; 
} 
$modified = get_changed_files($base, $commit); 
$result = true; 
foreach ($modified as $fname) { 
    // if fname equals post-receive 
    $contents = get_new_file($fname, $commit); 
    // copy it to .git/hooks/post-receive 
} 

Имея двухступенчатый процесс проще.

+0

@cadegalt не требуется для внутренних устройств: у вас есть описание этих крючков на https: // git-scm.com/book/ru/v2/Customizing-Git-Git-Hooks # Сервер-боковые крючки – VonC

+0

@cadegalt уверен, что это тоже может работать, и полностью обходит git. Если вы единственный, кто нажал на сервер хостинга git repo, это не представляет никакого риска. – VonC

+0

@cadegalt нет. ssh или https. Не scp (https://git-scm.com/book/ch4-1.html#The-SSH-Protocol) – VonC

Смежные вопросы