Нажатие существующего репозитория Git в Github отправляет только половину коммитов?

У меня есть локальный репозиторий Git, который я разрабатывал в течение нескольких дней: он имеет восемнадцать коммитов. Сегодня вечером я создал частный репозиторий Github, на который я надеялся подтолкнуть его; однако, когда я это сделал, он только закончил тем, что отбил восемнадцать из восемнадцати коммитов в Гитуб. Я удалил репозиторий Github и повторил его с тем же результатом.

Любые мысли о том, почему это может произойти? Я проделал эту процедуру раньше, чем несколько раз, поэтому я немного озадачен.

Обновление. В этом репо есть и всегда была только ведущая ветвь. Просто чтобы ответить на несколько опубликованных ответов...

Ответы

Ответ 1

Я посмотрел на репозиторий, и вот что происходило:

  • В какой-то момент rpj выполнил git checkout [commit id]. Это указывало HEAD на свободную фиксацию, а не на признанную ветку. Я считаю, что это проблема "оборванных голов", к которой относится CesarB.
  • Не осознавая эту проблему, он продолжал делать изменения и совершать их, каждый раз сталкиваясь с HEAD. Тем не менее, HEAD просто указывал на свисающую цепочку коммитов, а не на признанную ветку.
  • Когда он пошел, чтобы подтолкнуть свои изменения, git подтолкнул все до вершины мастера, что было примерно на полпути к текущему дереву, в котором он был.
  • Последовала путаница.

Эта диаграмма должна сделать ее более понятной:

                 -- D -- E -- F
                /             ^
   A -- B -- C -              |
   ^         ^               HEAD
   |         |
 remote    master

Когда он попытался нажать свои изменения, нажали только A через C, а remote переместился на C. Он не мог получить фиксацию D через F для нажатия, потому что на них не ссылается известная ветвь.

Здесь вы видите, когда находитесь в этом состоянии:

$ git branch
* (no branch)
master

Решение состоит в том, чтобы переместить master до F в цепочку битвитов. Вот как я это сделал.

  • Создайте законную ветвь для текущего состояния:

    git checkout -b tmp

    • Теперь ветвь tmp указывает на фиксацию F на диаграмме выше
  • Перемотка вперед master в tmp

    git checkout master

    git merge tmp

    • master теперь указывает на commit F.
  • Отбросьте свою временную ветку

    git branch -d tmp

  • Вы можете с радостью нажать на удаленный репозиторий, и он должен отправить все ваши изменения.

Ответ 2

От Git 1.7.3 и выше вы можете сделать это с помощью одной простой команды:

git checkout -B master

Переключатель -b означает "создать ветку перед проверкой", а -b - это безусловная версия, "даже если ветвь уже существует - в этом случае переместите ее сюда, прежде чем ее проверить".


Очень простой подход для устранения этой проблемы - просто удалить ветвь master и воссоздать ее. В конце концов, ветки в Git - это просто имена для коммитов, а ветвь master ничего особенного.

Итак, предполагая, что текущая фиксация - это та, которая вам нужна master, вы просто выполняете

git branch -D master

чтобы удалить существующую ветвь master, затем выполните

git checkout -B master

a) создать новую ветвь с именем master, которая указывает на текущую фиксацию и b) обновить HEAD, чтобы указать на ветвь master. После этого HEAD будет прикреплен к master, и поэтому master будет перемещаться вперед, когда вы совершаете фиксацию.

Ответ 3

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

Самый простой способ проверить - использовать gitk --all, который графически отображает все ветки, HEAD и т.д.

Ответ 4

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

Я никогда раньше не видел эту проблему, и я не могу придумать, что может быть неправильным.

Ответ 5

Итак, получается, что оба: хеш фиксации в .git/refs/heads/master был правильно, а информация в .git/logs/refs/heads/master была неполной; в том, что я имею в виду, что он только поднялся и включил хеш фиксации, указанный в .git/refs/heads/master.

Как только я исправил эти файлы (вручную) и вернулся в Github, все снова подливалось. У меня все еще есть не знаю, что случилось с вещами в этом состоянии, но я рад, что хотя бы понял, что исправить.

В случае, если кому-то интересно: исправить .git/refs/heads/master, я просто заменил содержимое этого файла последним хешем фиксации (HEAD) и исправил .git/logs/refs/heads/master, Я просто скопировал содержимое .git/logs/HEAD в .git/logs/refs/heads/master. Легкий peasy... НЕ.

Ответ 6

У меня нет репутации, чтобы комментировать прямо на предыдущем ответе CesarB, но gitk --all не работает в этом случае, потому что в нем перечислены только известные ветки.

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

Ответ 7

У меня была одна и та же проблема дважды, и, наконец, я понял, что я делаю, это вызывало ее. В процессе редактирования старого коммита с git rebase -i вместо вызова git commit --amend я вызывал git commit -a по привычке, сразу после чего следовал git rebase --continue, конечно. Кто-то еще может объяснить, что происходит за кулисами, но, похоже, результатом является проблема с отсоединенной головной головкой.