Git Push error: отказывается обновлять извлеченную ветку

197

Я решил некоторые конфликты слияния, зафиксировал их, затем попытался отправить свои изменения и получил следующую ошибку:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
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:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

Кто-нибудь знает, что может быть причиной этой ошибки?

трусливый
источник
3
продублировано: stackoverflow.com/questions/2816369/…
cregox
6
Теперь у вас есть безопасный способ перейти к репозиторию без использования Git 2.3.0 (февраль 2015 г.) и git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

Ответы:

229

Причина: вы отправляете в не голое хранилище

Есть два типа репозиториев: голые и не голые

Голые репозитории не имеют рабочей копии, и вы можете нажать на них. Это те типы репозиториев, которые вы получаете в Github! Если вы хотите создать пустой репозиторий, вы можете использовать

git init --bare

Итак, короче говоря, вы не можете нажать на не обнаженное хранилище(Редактировать: Ну, вы не можете нажать на текущую извлеченную ветвь репозитория. С пустым репозиторием вы можете нажать на любую ветку, поскольку ни одна из них не извлечена. Хотя это возможно, отправка в не пустые репозитории не распространена) , Что вы можете сделать, это получить и объединить из другого хранилища. Вот как работает то, pull requestчто вы можете видеть в Github. Вы просите их оторваться от вас, и вы не толкаете их силой.


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

Shahbaz
источник
1
Да! Это правильно, спасибо! Поскольку у меня есть около миллиона дел, я случайно клонировал рабочий каталог .... дох!
Фанки
25
На самом деле, вы можете просто перейти в не-пустой репозиторий, вы просто не можете перейти в одну ветвь, которая в данный момент извлечена .
Нигде человек
1
На самом деле существуют десятки других сценариев. Например, некоторые из моих репозиториев находятся только на моей рабочей станции и на моем ноутбуке (не код, а заметки, которые я делаю). На каждом у меня есть две ветки, «рабочая станция» и «ноутбук». На рабочей станции я проверяю только «рабочую станцию» и нажимаю только на ветку «рабочая станция» на ноутбуке (и наоборот).
Нигде человек
8
На самом деле у вас теперь есть безопасный способ перейти к непроигрышному репо с Git 2.3.0 (февраль 2015 г.) и git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC
1
@skelly Ваш клон не голый, а копия на github. Таким образом, хотя у обоих клонов есть вся история, у копии на github нет проверенных коммитов, но у вашей копии есть, чтобы позволить вам работать!
Шахбаз
115

Я решил эту проблему, сначала проверив, что на пульте не было ничего проверено (на самом деле это не предполагалось), а затем обнажил его:

$ git config --bool core.bare true

После этого git push работал нормально.

Саша пачев
источник
3
Это исправление из одной строки, которое я искал ... но, может быть, объясните голые не голые репозитории, такие как ответ
@shahbaz
Это позволит сдвинуть историю изменений, но эти изменения не будут отражены в репозитории non-bare.
jhill515
будет вам git config core.bare falseи git reset --hard ?
самолет
1
Как уже упоминалось выше, пульт не будет изменен, когда вы нажмете на него.
user1097111
46

Резюме

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

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

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

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

Так

A ← B
    ↑
[HEAD,branch1]

становится

A ← B ← C
        ↑
    [HEAD,branch1]

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

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

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

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

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

Нигде человек
источник
Я немного расширил в stackoverflow.com/questions/2816369/…
Нигде человек
22

Для меня следующее сделали свое дело:

git config --global receive.denyCurrentBranch updateInstead

Я настроил диск F: почти полностью для синхронизации между моим рабочим столом Windows 10 и ноутбуком с Windows 10 с помощью Git. Я закончил тем, что выполнил вышеупомянутую команду на обеих машинах.

Сначала я поделился диском F рабочего стола в сети. Затем я смог клонировать его на своем ноутбуке, запустив:

F: git clone 'file://///DESKTOP-PC/f'

К сожалению, все файлы оказались под "F: \ f \" на моем ноутбуке, а не под F: \ напрямую. Но мне удалось вырезать и вставить их вручную. Git все еще работал с нового места позже.

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

Обратите внимание, что я выполнил все эти команды из Windows PowerShell на обеих машинах.

ОБНОВЛЕНИЕ: у меня все еще были проблемы, подталкивающие изменения, в некоторых случаях. Наконец, я просто начал извлекать изменения, запустив на компьютере следующее, на которое я хочу получить последние коммиты:

git pull --all --prune

Стивен Дж Тагги
источник
1
Я предпочитаю это местное к мерзавца репо:git config receive.denyCurrentBranch updateInstead
Klor
21

Перейдите в каталог repo /, в который вы вставляете на удаленном компьютере, и введите

$ git config core.bare true
Рики
источник
Это не работает. Хранилище остается пустым после вставки в него.
Сёрен
как сказано выше в jhil515, файлы без поддержки не обновляются, только базы данных.
Дени Кузино
14

Как уже существует хранилище, работает

git config --bool core.bare true

на удаленном репозитории должно хватить

Из базовой документации.

Если true (bare = true), предполагается, что хранилище пустое, без рабочего каталога. В этом случае ряд команд, которым требуется рабочий каталог, будет отключен, например, git-add или git-merge (но вы сможете нажать на него).

Этот параметр автоматически определяется git-clone или git-init при создании репозитория. По умолчанию предполагается, что репозиторий, оканчивающийся на «/.git», не является пустым (bare = false), а все остальные репозитории предполагаются пустыми (bare = true).

Джонни
источник
12

TLDR

  1. Потяните и нажмите еще раз: git pull &&& git push .
  2. Все еще проблема? Нажмите в другую ветку:git push origin master:foo и объедините его на удаленном репо.
  3. В качестве альтернативы, принудительно добавьте толчок -f( denyCurrentBranchнеобходимо игнорировать).

По сути, ошибка означает, что ваш репозиторий не соответствует удаленному коду (его индекс и рабочее дерево не соответствуют тому, что вы нажали).

Обычно вы должны pullсначала получить последние изменения иpush это снова.

Если не поможет, попробуйте перейти в другую ветку, например:

git push origin master:foo

затем объедините эту ветку в удаленном хранилище с master.

Если вы изменили некоторые прошлые коммиты преднамеренно через git rebaseи хотите переопределить репо с вашими изменениями, вы, вероятно, захотите форсировать push, добавив параметр -f/ --force(не рекомендуется, если вы этого не сделали rebase). Если по- прежнему не будет работать, вам нужно установить , receive.denyCurrentBranchчтобы ignoreна пульте дистанционного управления , как предложено сообщение мерзавца через:

git config receive.denyCurrentBranch ignore
kenorb
источник
3

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

JZAU
источник
1

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

xastor
источник
1
В моей ситуации это было так. Удаление .gitпапки на пульте позволило мне нажать начальную фиксацию.
tim.rohrer
0

Я получил эту ошибку, когда играл во время чтения проги. Я сделал локальный репозиторий, затем извлек его в другом репо в той же файловой системе, сделал правку и попытался нажать. После прочтения ответа NowhereMan, было бы быстрое решение - перейти в «удаленный» каталог и временно извлечь еще один коммит, выдвинуть из каталога, в котором я внес изменения, затем вернуться и вернуть голову на master.

Натан Чаппелл
источник
0

Это работает для меня

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master

Прасенджит Махато
источник