При отправке существующего репозитория Git на Github отправляется только половина коммитов?
-
04-07-2019 - |
Вопрос
У меня есть локальный репозиторий Git, над которым я работал несколько дней:на данный момент у него восемнадцать коммитов.Сегодня вечером я создал частный репозиторий Github, куда надеялся его разместить;однако когда я это сделал, в Github было отправлено только восемь из восемнадцати коммитов.Я удалил репозиторий Github и повторил попытку с тем же результатом.
Есть мысли, почему это может происходить?Я уже несколько раз проделывал эту процедуру безуспешно, поэтому я немного озадачен.
Обновлять:В этом репозитории есть и всегда была только главная ветка.Просто чтобы ответить на несколько опубликованных ответов...
Решение
Я взглянул на рассматриваемый репозиторий и вот что происходит:
- В какой-то момент rpj выступил
git checkout [commit id]
.Это указало HEAD на свободную фиксацию, а не на распознанную ветку.Я считаю, что это проблема «висячей головы», о которой говорит CesarB. - Не осознавая этой проблемы, он продолжал вносить изменения и фиксировать их, из-за чего каждый раз поднимался HEAD.Однако HEAD просто указывал на оборванную цепочку коммитов, а не на распознанную ветку.
- Когда он приступил к отправке своих изменений, git отправил все на вершину master, которая находилась примерно на середине текущего дерева, в котором он находился.
- Возникла путаница
Эта диаграмма должна прояснить ситуацию:
-- 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
теперь указывает на фиксациюF
.
Выбросьте свою временную ветку
git branch -d tmp
Вы можете с радостью отправить запрос в удаленный репозиторий, и он должен отправить все ваши изменения.
Другие советы
Начиная с Git 1.7.3, вы можете сделать это с помощью одной простой команды:
git checkout -B master
Переключатель -b
означает & # 8220; создать ветку здесь перед проверкой ее & # 8221; и -B
является безусловной версией этого, & # 8220; даже если ветвь уже существует & # 8211; в этом случае переместите его сюда, прежде чем проверять & # 8221;.
Очень простой подход к решению проблемы такого рода - просто удалить ветку master
и воссоздать ее. В конце концов, ветки в git - это просто имена для коммитов, а ветка master
ничего особенного.
Итак, предполагая, что текущий коммит - это тот, кем вы хотите, чтобы master
был, вы просто делаете
git branch -D master
чтобы удалить существующую ветку master
, затем выполните
git checkout -b master
a) создать новую ветку с именем master
, которая указывает на текущий коммит, и b) обновить HEAD
, чтобы она указала на ветку master
, После этого HEAD
будет присоединен к master
, и поэтому master
будет двигаться вперед всякий раз, когда вы фиксируете.
Проверьте, нажимаете ли вы правильные ветви, и действительно ли ветви имеют то, что, по вашему мнению, они имеют. В частности, проверьте, нет ли у вас отсоединенного HEAD, что может привести к путанице, если не сделано специально.
Самый простой способ проверить это использовать gitk --all
, который графически показывает все ветви, HEAD и многое другое.
Полагаю, первым делом я бы запустил git fsck
в своем локальном репозитории, чтобы убедиться, что все в порядке.
Я никогда не видел эту проблему раньше, и я не могу думать о том, что может быть не так.
У меня нет репутации, чтобы комментировать прямой ответ CesarB, но gitk --all
в этом случае не работает, потому что он перечисляет только известные ветки. Р>
gitk HEAD
показывает эту проблему, но она не совсем понятна. Пистолет для курения заключается в том, что master
отображается вниз по дереву коммитов, а не при самом последнем коммите.
Итак, получается, что оба: хеш коммита в .git / refs /head / master был верным, а информация в .git / logs / refs /head / master была неполной; Я имею в виду, что он только поднялся и включил хеш коммита, указанный в .git / refs /head / master. Р>
Как только я исправил эти файлы (вручную) и отправил обратно на Github, все снова стало подливкой. Я до сих пор не знаю, не знаю , что случилось, чтобы получить вещи в этом состоянии, но я рад, что, по крайней мере, нашел решение.
В случае, если кому-то интересно: исправить .git / refs /head / master, я просто заменил содержимое этого файла на последний хеш коммита (HEAD) и исправил .git / logs / refs /head / master Я просто скопировал содержимое .git / logs / HEAD в .git / logs / refs /heads / master. Легко peasy ... НЕ.
У меня была такая же проблема дважды, и, наконец, я выяснил, что я делал, что вызвало ее. В процессе редактирования старого коммита с помощью git rebase -i
вместо вызова git commit --amend
я вызывал git commit -a
по привычке, сразу же после git rebase --continue
, конечно. Кто-то еще может объяснить, что происходит за кулисами, но, похоже, в результате возникает проблема с отделенной головкой.