Помилка Git Push: відмова від оновлення перевіреної гілки


196

Я вирішив кілька конфліктів злиття, здійснив, потім спробував підштовхнути свої зміни та отримав таку помилку:

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'

Хтось знає, що може спричинити цю помилку?



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) можливий перехід до перевіреної гілки не оголеного сховища . Тим не менш, ви все одно не можете натиснути на брудне робоче дерево, що все одно не є безпечною експлуатацією.


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

Це дозволить підштовхнути історію змін, але ці зміни не відображатимуться в неоголеному репо.
jhill515

ти будеш git config core.bare falseі git reset --hard ?
літак

1
Як було сказано вище, пульт дистанційного управління не буде змінено при натисканні на нього.
користувач1097111

46

Підсумок

Ви не можете натиснути на одну перевірену гілку сховища, тому що вона зіпсується з користувачем цього сховища таким чином, який, швидше за все, закінчиться втратою даних та історії . Але ви можете перейти до будь-якої іншої гілки того ж сховища.

Оскільки в голих сховищах ніколи не перевіряється жодна гілка, ви завжди можете перейти до будь-якої гілки голого сховища.

Розтин проблеми

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

Так

A ← B
    ↑
[HEAD,branch1]

стає

A ← B ← C
        ↑
    [HEAD,branch1]

Але якби хтось міг просунутися до цієї гілки між ними, користувач отримав би себе в тому, що git викликає відключений головний режим:

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

Тепер користувач більше не перебуває у відділенні1, не вимагаючи прямо перевірити іншу гілку. Гірше, що користувач зараз знаходиться поза будь-яким відділенням , і будь-яке нове зобов'язання буде просто звисати :

      [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 repo:git config receive.denyCurrentBranch updateInstead
klor

21

CD в ​​каталог репо / каталог, який ви натискаєте на віддалену машину, і введіть

$ git config core.bare true

Це не працює. Після натискання на нього сховище залишається порожнім.
Сьорен

як сказано в jhil515 вище, неочищені файли не оновлюються, лише бази даних.
Денис

14

Оскільки працює вже наявне сховище

git config --bool core.bare true

на віддаленому сховищі повинно вистачити

З документації на core.bare

Якщо 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і хочете замінити репо зі своїми змінами, ви, мабуть, хочете змусити натиснути, додавши -f/ --forceпараметр (не рекомендується, якщо цього не зробили rebase). Якщо по- , як і раніше не буде працювати, вам потрібно встановити , receive.denyCurrentBranchщоб ignoreна пульті дистанційного управління , як запропоновано повідомлення мерзотника через:

git config receive.denyCurrentBranch ignore

3

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


1

У мене є ця помилка, тому що git repo (випадково) було ініціалізовано двічі в одному місці: спочатку як не голе репо, а незабаром - як голе репо. Оскільки папка .git залишається, git припускає, що сховище не є голим. Видалення папки .git та даних робочого каталогу вирішило проблему.


1
У моїй ситуації це було так. Видалення .gitпапки на пульті дистанційного керування дозволило мені підштовхнути початкове завдання.
tim.rohrer

0

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.