Нажатие существующего репозитория 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
, конечно. Кто-то еще может объяснить, что происходит за кулисами, но, похоже, результатом является проблема с отсоединенной головной головкой.