У меня есть репозиторий, размещенный на github, который я использовал для разработки некоторого кода, назовем его https://github.com/foo/bar.git.
В другом, совершенно отдельном локальном репозитории я разработал другой код. Теперь я хочу запушить содержимое этого локального репозитория в https://github.com/foo/bar.git, полностью заменив старый контент (ветки, теги и т.д.). Как мне этого добиться?
Я знаю, что могу просто удалить репозиторий на github и создать новый, но я бы хотел этого избежать.
Я установил удаленный URL-адрес в локальном репо. Я также сделал git push
, но это привело к тому, что новый контент сосуществовал с исходным (например, из-за несоответствия веток main
и master
). Есть ли способ это исправить?
Сидя на main
, делая git push --force -u origin master
получаю error: src refspec master does not match any
.
Комментарий-ответ Xiidref в основном верен, но упускает несколько замечаний:
Поскольку у вас есть main
сейчас и нет master
в репозитории замены, вы можете захотеть, чтобы GitHub установил имя main
, а не имя master
. Затем вы можете захотеть полностью заменить удалять имя старыйmaster
, но прежде чем вы сможете это сделать, вам, вероятно, потребуется сообщить GitHub, чтобы он изменил свое представление о ветвь по умолчанию для вашего репозитория на стороне GitHub, поскольку вы не можете удалить рекомендованное имя ветки. по умолчанию для клонов.
В качестве альтернативы, возможно, вы захотите продолжить использовать имя master
на пульте дистанционного управления. Если это так, вам нужно будет решить, переименовывать ли ветку в вашем собственном локальном репозитории. Проще всего git branch -m main master
, а затем принудительно нажать по мере необходимости.
Чтобы сделать первое (переключить имя ветки GitHub на main
), вы можете начать с:
git remote add origin https://github.com/foo/bar.git
git push -u origin main
Это отправляет (большинство, если не все) ваши новые коммиты с отсутствием связи с существующими коммитами в GitHub, а затем просит программное обеспечение на стороне GitHub создать там новое имя ветки main
. В случае успеха он устанавливает восходящий поток вашего локального main
на ваш вновь созданный origin/main
.
Теперь, когда там существует main
, вы можете использовать веб-страницы GitHub или gh
кли команда, чтобы установить имя ветки по умолчанию на main
:
gh repo edit --default-branch main
(или используйте браузер и обычные кликающие кнопки).
Возможно, вы также захотите удалить все существующие имена тегов и других веток на стороне GitHub, а затем создать новые для любых новых имен веток и тегов.
Вы можете, но не обязаны; см. ниже — используйте git push --delete
, чтобы удалить все имена веток и тегов, которые есть на GitHub, кроме новых main
, которые вы только что создали, или master
, которые вы только что обновили. Чтобы получить список таких имен, рассмотрите возможность использования:
git ls-remote origin
который выдаст их все (вы, вероятно, захотите перенаправить это в файл, который вы можете редактировать). Обязательно отфильтруйте имена HEAD
и main
. Вы можете предоставить оставшиеся имена одному git push origin --delete
с префиксами refs/heads/
и refs/tags/
или без них, например:
git push origin --delete br1 br2 master tag1 tag2 tag3
Теперь, если вам нужно установить больше имен веток и/или тегов, вы можете сделать их все сразу с помощью еще одного git push
, например:
git push -u origin newbr1 newbr2 newtag1 newtag2
(примечание: я на самом деле не уверен, правильно ли работает -u
при отправке тегов; если это вызывает проблемы, подумайте о том, чтобы разделить это на две отдельные команды git push
, одну для имен веток с -u
и одну для имен тегов без -u
).
В качестве короткого пути рассмотрите:
git push --mirror origin
Опция --mirror
будет отправлять имена удалятьнет и будет пытаться отправить (с помощью --force
) все имена ветвей и тегов. Таким образом, это должно охватывать как «удаление старых имен», так и «обновление новых». Однако я не думаю, что это можно сочетать с -u
. Вместо этого вы можете запустить git fetch
позже, чтобы создать origin/*
имена, если / по мере необходимости, а затем выполнить серию git branch --set-upstream-to
команд (что легко написать в сценарии).
Если у вас есть какие-либо защищенные имена веток, вам может потребоваться снять с них защиту, прежде чем делать все это.
Удаление названия ветвей из репозитория на стороне GitHub делает старые совершает недоступными для поиска. Однако на самом деле это не удалять для этих коммитов. У GitHub есть внутренняя политика хранения (по внутренним причинам, связанным с ветвями GitHub), согласно которой такие коммиты хранятся навсегда, а не типичный локальный срок действия Git 30 или 90 дней. (Вы можете попросить сотрудников службы поддержки очистить мертвые коммиты, как вы могли бы сделать с коммитами, содержащими конфиденциальные данные. Однако я не уверен, какие политики действуют в этом случае.)
Все это означает, что (а) много Полегче всего лишь удалять всего вашего репозитория на стороне GitHub; (b) это может сэкономить место на диске GitHub, особенно если нет разветвлений вашего частного репозитория. Поэтому я бы не стал делать это более сложным способом, сохраняющим репозиторий. Конечно, удаление и повторное создание репозитория также уничтожает базу данных проблем, PR и т. д. только для GitHub, что может быть рассмотрено.
Прежде всего, спасибо, что нашли время написать этот очень подробный и исчерпывающий ответ! Да, я не хочу удалять репо из-за базы данных проблем. Буду пробовать другие варианты.
Из вашей основной ветки используйте
git push --force -u origin master
. --force заменит содержимое на удаленном компьютере вашей веткой, а -u origin master заставит вашу ветку ссылаться на мастер на gihub (даже если он называется main на локальном компьютере)