Почему "git нажмите helloworld + master: master" вместо "git нажмите helloworld"?

Я попытался вытолкнуть мой (первый в истории!) репозиторий git как это первоначально:

$ git push helloworld

Но я получил это обратно:

To [email protected]:helloworld.git
 ! [rejected]        HEAD -> master (non-fast forward) error:
 failed to push some refs to '[email protected]:helloworld
git'

Итак, я нашел qaru.site/info/1009/... о "исправленных коммитах" и попробовал оттуда предложение, не зная, поможет ли мне это:

[email protected] /c/test/helloworld (master)
$ git push helloworld +master:master

Это сработало!

Но я не знаю, почему он исправил мою проблему: (

Может кто-нибудь объяснить, почему это работает, но "git push helloworld" не работает?

Ответ 1

Кажется, вы переписали свою историю (SHA-1, связанную с вашей фиксацией) в своей главной ветке.

Это означает, что вы больше не можете переходить в режим быстрой перемотки вперед.

+ мастер заставляет толчок проходить:
Имея дополнительный указатель +, вы можете сообщить git обновить ref <dst>, даже если обновление не является быстрым.

Примечание: это может быть плохо, если кто-то еще клонировал ваш репозиторий, так как они больше не смогут просто вытащить вашу основную ветку без конфликта.
См. Также этот SO ответ для более.


Примечание: как упоминалось от Junio ​​C. Hamano:

Существует два независимых механизма безопасности:

  • безопасность отправки отправления может быть переопределена "git push --force" и/или с помощью refspec с префиксом "+" );

  • безопасность конечного конца может быть переопределена переменной конфигурации receive.denynonfastworwards репозитория, в который вы вставляете.

Последний по умолчанию имеет значение "небезопасно", но если безопасность активирована в репозитории, форсирование со стороны отправки не отключит его. IOW, оба конца должны согласиться, чтобы разрешить небезопасное поведение.


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

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

 $ git fetch origin
 $ git log master..origin/master

отобразит все изменения, которые удаленная сторона имеет на вашей стороне.
Если вы хотите графическое представление, используйте gitk --left-right master...origin/master.
Стрелки влево - это изменения, которые вы хотите нажимать, стрелки вправо - изменения на удаленной стороне.

Другое решение (это то, что вы сделали):

$ git push origin +branchname

Это приведет к обновлению. Если у вас нет разрешения, иногда это будет работать:

$ git push origin :branchname
$ git push origin +branchname

т.е. сначала удалите ветвь (это часто разрешено), затем повторно нажмите "новую" (или, возможно, перемотанную) ветвь.

Будьте предупреждены, что если вы перемотаете ветки, другие могут попасть в проблему при потянув.
Есть вероятность, что они сольются в отрасли, которую они принесли с новой, которую вы опубликовали, эффективно сохраняя изменения, от которых вы пытаетесь избавиться.
Тем не менее, это будут только их копии, которые имеют плохие ревизии. По этой причине перематывающие ветки считаются мягко антисоциальными. Тем не менее, это часто уместно.