Каковы последствия использования метода receive.denyCurrentBranch в Git?

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

Как только я создаю ветку, я проверяю ветку, завершаю свою работу, а затем проверяю основную ветку. Затем я объединяю свои локальные изменения в главную ветку. Когда я пытаюсь нажать на сервер, я получаю следующее исключение:

Welcome to Git (version 1.7.11-preview20120620)

Run 'git help git' to display the help index.
Run 'git help <command>' to display help for specific commands.

$ git push origin master:master
 Counting objects: 9, done.
 Delta compression using up to 4 threads.
 Compressing objects: 100% (7/7), done.
 Writing objects: 100% (8/8), 13.68 KiB, done.
 Total 8 (delta 2), reused 1 (delta 0)
 Unpacking objects: 100% (8/8), done.
 remote: error: refusing to update checked out branch: refs/heads/master
 remote: error: By default, updating the current branch in a non-bare repository
 remote: error: is denied, because it will make the index and work tree inconsistent
 remote: error: with what you pushed, and will require 'git reset --hard' to match
 remote: error: the work tree to HEAD.
 remote: error:
 remote: error: You can set 'receive.denyCurrentBranch' configuration variable to

 remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into

 remote: error: its current branch; however, this is not recommended unless you
 remote: error: arranged to update its work tree to match what you pushed in some

 remote: error: other way.
 remote: error:
 remote: error: To squelch this message and still keep the default behaviour, set

 remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
 To c:/jGit
 ! [remote rejected] master -> master (branch is currently checked out)
 error: failed to push some refs to 'c:/gitRepository'

Одним из решений является запуск следующей команды:

git config receive.denyCurrentBranch ignore

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

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

Ответ 2

Почему Git не позволит вам нажать на не-голые репозитории

Оригинальный плакат гласит:

Одним из решений является запуск следующей команды:

git config receive.denyCurrentBranch ignore

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

Как я отмечаю в мой ответ на аналогичный вопрос, поскольку Git версия 1.6.2, Git не позволит вам по умолчанию нажать на не-голый репозиторий. Это связано с тем, что команда git push обновляет ссылки на ветку и HEAD в удаленном репозитории. То, что он не делает, также обновляет рабочую копию и промежуточную область на этом небедренном пульте.

Как следствие, когда вы используете git status в удаленном репо, вы увидите, что предыдущее состояние repo все еще присутствует в рабочей копии (и поставлено в индексе):

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   previous-state.txt

Если вы посмотрите на сообщение об ошибке, которое вы получили, когда вы впервые попытались нажать на свое не-обнаженное дистанционное репо с параметром receive.denyCurrentBranch, установленным на значение по умолчанию refuse, вы увидите, что сообщение сообщает вам в основном одно и то же:

error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error:
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.

Вам следует просто нажать на голые репозитории Git

Как указано в некоторых других ответах, вы не должны нажимать на не-голый репозиторий, по причинам, указанным выше, и которые Git говорит вам.

Так что, как говорится в этом ответе, простой способ конвертировать существующий не-голый репо на голый - просто отложить его как голый репо:

git clone --bare old-repo

Или вы могли бы попытаться объединиться с настройкой core.bare config, как описано в этом ответе.

Ответ 3

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

См. этот ответ для получения информации о том, как конвертировать ваш не-голый репозиторий на сервере на один.

Ответ 4

У меня была такая же ошибка, и мне нужно, чтобы репозиторий запускался как тестовая страница dev онлайн (то есть, я полагаю, для сохранения не-голого репо). Надеюсь, я решил это, инициировав репозиторий с помощью этой серии команд (начиная с git 2.3):

git init
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
git commit
git config receive.denyCurrentBranch updateInstead

Как показано здесь: не может попасть в репозиторий git

Ответ 5

Вскрытие проблемы

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

Итак,

A ← B
    ↑
[HEAD,branch1]

становится

A ← B ← C
        ↑
    [HEAD,branch1]

Но если кто-то может нажать на эту ветку между ними, пользователь получит то, что git вызывает режим отдельной главы:

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

Теперь пользователь больше не находится в ветке1, не запросив явно другую ветку. Хуже того, пользователь теперь находится вне любой ветки, и любая новая фиксация будет просто болтаться:

     [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

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

Ответ 6

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