Отправка существующего Git-репозитория в Github отправляет только половину коммитов? - PullRequest
9 голосов
/ 26 октября 2008

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

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

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

Ответы [ 7 ]

17 голосов
/ 09 ноября 2008

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

  • В какой-то момент rpj выполнил git checkout [commit id]. Это указало HEAD на свободный коммит, а не на признанную ветвь. Я полагаю, что это проблема "болтающейся головы", на которую ссылается CesarB.
  • Не осознавая этой проблемы, он продолжал вносить изменения и фиксировать их, что каждый раз поднимало ГОЛОВУ. Однако 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 теперь указывает на коммит F.
  • Выбросьте свою временную ветку

    git branch -d tmp

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

5 голосов
/ 10 ноября 2008

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

git checkout -B master

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


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

Итак, предполагая, что текущим коммитом является тот, кем вы хотите master, вы просто делаете

git branch -D master

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

git checkout -b master

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

2 голосов
/ 26 октября 2008

Проверьте, нажимаете ли вы правильные ветви, и действительно ли ветви имеют то, что, по вашему мнению, они имеют. В частности, проверьте, нет ли у вас отсоединенной ГОЛОВКИ, что может быть довольно запутанным, если не сделано специально.

Самый простой способ проверить это использовать gitk --all, который графически показывает все ветви, ГОЛОВУ и т. Д.

1 голос
/ 09 ноября 2008

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

gitk HEAD показывает эту проблему, но она не совсем понятна. Пистолет для курения состоит в том, что master отображается вниз по дереву коммитов, а не при самом последнем коммите.

1 голос
/ 26 октября 2008

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

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

0 голосов
/ 30 января 2009

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

0 голосов
/ 27 октября 2008

Итак, получается, что оба: хеш коммита в .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 ... НЕ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...