Git сервер на сервере локальной компании + файлы - PullRequest
1 голос
/ 10 ноября 2019

Я пытаюсь установить удаленный репо на файловом сервере моей компании с помощью GIT.

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

Я единственный пользователь, работающий над проектом.

  1. Я не могу использовать голый репо, так как хочу, чтобы файлы были перенесены на «удаленный».
  2. Клонирование локального на удаленное генерирует ошибку при попытке PUSH

Ошибка: git -c diff.mnemonicprefix = false -c core.quotepath = false --no-option-locks push -v --tags origin master: master Нажатие на M: / ARC / MikeS remote: ошибка: отказ от обновления извлеченной ветки: refs / руководителей / master
remote: ошибка: по умолчанию обновление текущей ветви в не-пустом хранилище
remote: запрещено, потому что это сделает несовместимым индекс и рабочее дерево.
remote: с тем, что вы нажали, и потребует, чтобы 'git reset --hard' совпадал с
remote: рабочее дерево для HEAD.
remote: remote: Вы можете установить 'receive.denyCuКонфигурационная переменная rrentBranch
remote: игнорировать или предупреждать в удаленном репозитории, чтобы разрешить проталкивание в
remote: его текущая ветвь;однако, это не рекомендуется, если вы не
remote: договорились обновить свое рабочее дерево, чтобы оно соответствовало тому, что вы нажали на каком-то
remote: другим способом.
remote: remote: чтобы подавить это сообщение и при этом сохранить значение по умолчаниюПоведение, установите
remote: переменная конфигурации 'receive.denyCurrentBranch' в 'отказ'.

Для М: / ARC / MikeS! [удалено отклонено] master -> master (ветка в настоящее время извлечена) ошибка: не удалось отправить некоторые ссылки в 'M: / ARC / MikeS'

Завершено с ошибками, см. выше.

Я попытался использовать «git config receive.denyCurrentBranch ignore» на удаленном репо. ошибка очищена, но файл на удаленном репо. не обновляются.

Есть ли решение? Я знаю, это звучит очень просто, но я просто не могу заставить его работать.

Спасибо, Майк

1 Ответ

0 голосов
/ 10 ноября 2019

Использование чистого репо (через SSH) - хорошее решение, при условии, что у вас есть правильный хук pre / post-receive, который будет извлекать ваши файлы в не-пустом хранилище.

  • pre-receive hook, чтобы проверить, что в вашем удаленном репозитории не было никаких изменений / новых коммитов (в этом случае вы сначала извлечете его, выполните локальное слияние, а затем добавите в пустой репозиторий)
  • hook после получения:чтобы извлекать содержимое, которое вы отправляете в репозиторий non-bare, делая файлы видимыми.

Значение: на удаленном сервере вы создаете два репозитория:

  • onenon-bare (для работы непосредственно на сервере)
  • one bare (для отправки с локального компьютера)

То есть:

ssh remoteUser@remoteServer
git init newRepo
cd newRepo
git init --bare bare

Затем нана вашем локальном компьютере вы клонируете пустой новый (не пустой) репозиторий, , но вы изменяете push-URL для ссылки на пустой репозиторий (newRepo/bare)

git clone remoteUser@remoteServer:~/newRepo
cd newRepo
git config --add remote.origin.pushurl remoteUser@remoteServer:~/newRepo/bare

на удаленномсервер, в ~ / newRepo / bare / hooks добавьте ловушку предварительного получения:

#!/bin/bash

DIR="$( cd "$( dirname "$(readlink "${BASH_SOURCE[0]}")" )" && pwd )"

git fetch

# Read stdin for ref information
while read -r oldref newref refname; do

  case "${refname}" in
  */master) branch="master"
  ;;
  refs/tags/*)
    ok "Pushing tag: proceed"
    exit 0
  ;;
  *) echo "invalid branch '${refname}'"
  exit 1
  ;;
  esac

  if [[ "${newref}" == "0000000000000000000000000000000000000000" ]]; then
    ok "Deletion of oldref '${oldref}': pre-receive proceed"
    exit 0
  fi

  localsha1=${newref}

  if [[ "master" == "${branch}" ]]; then
    originsha1=$(git rev-parse origin/master)

    force="false"
    # shellcheck disable=SC2086
    if [[ "$(git rev-list ${oldref} ^${newref})" != "" ]]; then force="true"; fi

    cmd="git merge-base --is-ancestor ${originsha1} ${localsha1}"
    if ! eval "${cmd}"; then
      if [[ "${force}" == true ]]; then
        info "force push master"
      else
        fatal "Git push of '${refname}' refused because repo locally ($(hostname)) modified\nDo a git pull first" 1
        exit 1
      fi
    fi
    if git rev-parse --quiet --verify from_prod >/dev/null && ! git merge-base --is-ancestor from_prod "${localsha1}"; then
      error "Git push of '${refname}' refused because from_prod is not an ancestor"
      error "Meaning: prod has evolved, fetch and rebase on top of from_prod first, then push again"
      exit 1
    fi
    ok "Push to master will proceed"
  fi
done

И хук после получения:

#!/bin/bash
DIR="$( cd "$( dirname "$(readlink "${BASH_SOURCE[0]}")" )" && pwd )"

while read -r oldrev newrev refname
do
  case "${refname}" in
  */master) branch="master"
  ;;
  refs/tags/*)
    ok "Pushing tag: proceed post-receive"
    exit 0
  ;;
  *) fatal "invalid branch '${refname}' in post-receive (oldrev:'${oldrev}')" 1
  ;;
  esac

  if [[ "${newrev}" == "0000000000000000000000000000000000000000" ]]; then
    ok "Deletion of oldrev '${oldrev}': post-receive proceed"
    unset GIT_DIR
    cd ..
    git --work-tree=. --git-dir=.git fetch --prune
    if [ "${branch}" != "" ]; then git --work-tree=. --git-dir=.git branch -d "${branch}"; fi
    cd ./bare || fatal "Unable to go into bare of '$(pwd)'" 8
    git --git-dir=. fetch --prune
    exit 0
  fi

  info "post-receive for branch '${branch}'"
  if [ "master" == "$branch" ]; then
    info "pull from non-bare repo"
    unset GIT_DIR
    cd ..
    git --work-tree=. --git-dir=.git fetch
    git --work-tree=. --git-dir=.git fetch --tags
    if ! git --work-tree=. --git-dir=.git merge-base --is-ancestor master origin/master; then
      info "Reset non-bare master to bare master (forced update)"
      git  --work-tree=. --git-dir=.git reset --hard origin/master
    else
      info "Update non-bare master with merge from origin/master"
      git --work-tree=. --git-dir=.git pull --no-rebase origin master
    fi
  fi
done

Таким образом, вы можете работать как непосредственно на сервере, в своем обычном репозитории ~ / newRepo, так и без него, совершая коммиты.
Но вы также можете работать на своем компьютере и выполнять push-уведомления, не опасаясь переопределения удаленной фиксации, выполняемой одновременно на сервере: ловушка предварительного получения блокирует push-запрос.

Примечания:

  • заменить "ok", "info" и "fatal" на простые "echo" в скриптах).
  • Добавить bare/ в .gitignore,для вашего обычного репозитория, чтобы игнорировать его вложенное голое хранилище.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...