Если есть репозиторий, к которому у меня есть git://доступ только (и обычно это просто push + pull), есть ли способ переименовать ветки в этом репозитории так же, как я делал бы локально git branch -m?
Связанный «дублирующий» вопрос просит переименовать ветку «как локально, так и удаленно». Этот вопрос, однако, только спрашивает, как переименовать ветки удаленно, что позволяет упростить. Это то , что я делаю , чтобы переименовать ветку на сервере без необходимости проверки и / или создать локальную ветвь: git push origin origin/old_name:refs/heads/new_name && git push origin :old_name.
Щуберт
1
@sschuberth: вы можете дать обе команды за один раз. И это действительно должно быть ответом на этот вопрос.
Иоахим Брейтнер
2
@JoachimBreitner Вы правы, я выполнил эту оптимизацию уже в моем сценарии .
Щуберт
1
@sschuberth, вы должны опубликовать свой комментарий в качестве ответа, так как он мне нравится больше, чем остальные ниже.
Затем, чтобы увидеть старое имя ветки, каждый клиент репозитория должен сделать:
$ git fetch origin
$ git remote prune origin
ПРИМЕЧАНИЕ. Если ваша старая ветка является вашей основной веткой, вам следует изменить настройки основной ветки. В противном случае при запуске $ git push origin :old-branch-nameвы получите сообщение об ошибке «удаление текущей ветки запрещено» .
Ну, если старое и новое имена совпадают, то это означает, что вам не нужно переименовывать ветку, поэтому нет смысла запускать команду в первую очередь ;-)
Sylvain Defresne
9
Конечно. Я просто имею в виду, что если вы вызываете это автоматически (как часть какого-то другого скрипта), вы можете не делать этого неправильно, если можете избежать этого.
Таинственный Дан
9
Путь Дэна: изменить порядок команд, чтобы они всегда работали. Путь Earth Engine: всегда не забывайте проверять, иначе вы потеряете данные. Я знаю, какой бы я выбрал.
Дорадус
2
Пользователи могут просто запустить: git fetch origin --prune(для эффективного извлечения новых веток, а также избавления от ссылок, которые больше не находятся на удаленном компьютере).
DolphinDream
2
Можно использовать -dили --deleteвместо :новых версий git.
Цитракс
285
Если вы действительно хотите переименовать ветки удаленно, без переименования каких-либо локальных веток одновременно , вы можете сделать это с помощью одной команды:
Я написал этот скрипт ( git-rename-remote-branch ), который предоставляет удобный ярлык для простого выполнения вышесказанного.
В качестве функции bash:
git-rename-remote-branch(){if[ $# -ne 3 ]; then
echo "Rationale : Rename a branch on the server without checking it out."
echo "Usage : $(basename $0) <remote> <old name> <new name>"
echo "Example : $(basename $0) origin master release"
exit 1fi
git push $1 $1/$2:refs/heads/$3 :$2
}
Чтобы интегрировать комментарий @ ksrb : в основном это делается двумя нажатиями в одной команде: сначала git push <remote> <remote>/<old_name>:refs/heads/<new_name>нажать новую удаленную ветку на основе старой удаленной ветви отслеживания, а затем git push <remote> :<old_name>удалить старую удаленную ветку.
Для тех, кому нужен псевдоним этой команды: rename = "! F () {источник происхождения git push / $ 1: refs /heads / $ 2: $ 1;}; f" это можно использовать как> git rename <old_name> < new_name>
Джонатан Шмидт
33
Для тех, кто интересуется, что на самом деле означает эта команда, это, по сути, 2 git push <remote>/<old_name>:refs/heads/<new_name>нажатия, означает нажатие нового пульта, который использует старый пульт в качестве src, а затемgit push [space]:<old_name> удаление старого пульта
ksrb
3
Зачем вам нужно использовать refs/heads/name? Разве вы не можете просто использовать nameнапрямую, делая первую команду git push <remote> <remote>/<old_name>:<new_name>?
Дрю Ноакс
6
Нет, потому что удаленная ветвь <new_name>еще не существует. Если ветка не существует, Git требует, чтобы вы использовали полное имя, так как в противном случае <new_name>также можно сослаться на имя тега.
Щуберт
3
Мы используем этот подход в нашей системе сборки. Единственное предостережение, с которым мы сталкиваемся - если оно refs/heads/<new_name> уже существует. Удаление все еще успешно, в результате чего <remote>/<old_name>только удаляется. Некоторые проверки перед рукой могут легко избежать этого.
Апейрон,
172
Первая проверка в ветке, которую вы хотите переименовать:
Когда вы перемещаете переименованную ветвь (new_branch) в удаленную (origin), вы также должны установить ее восходящий поток для отслеживания ветви с новым именем (например git push -u origin new_branch), иначе переименованная ветвь (new_branch) продолжит отслеживать origin / old_branch. И как только вы удалите удаленный old_branch, new_branch все равно будет отслеживать origin / old_branch, хотя теперь эта ветвь исчезла.
DolphinDream
@DolphinDream Я отредактировал ответ, включив в него ваши полезные изменения.
mVChr
10
Конечно. Просто переименуйте ветку локально, нажмите на новую ветку и удалите старую.
Единственная реальная проблема заключается в том, что другие пользователи хранилища не будут переименовывать локальные ветви отслеживания.
поэтому при попытке удалить master я попытался $ git clone ../src $ cd src $ git branch notmaster $ git checkout notmaster $ git branch -d master $ git push ../src: master Но он жалуется: назначение refspec не соответствует существующему ref на удаленном сервере и не начинается с refs /, и мы не можем угадать префикс, основываясь на исходном ref. ошибка: не удалось отправить некоторые ссылки на '../alpha/' У пульта действительно есть ветка с именем master
kdt
2
TL; DR
«Переименование» удаленной ветви на самом деле является двухэтапным процессом (не обязательно заказывается):
нажмите в новую удаленную ветку (разница между парой команд ответов ниже).
Удаление
Я использую TortoiseGit, и когда я впервые попытался удалить ветку через командную строку, я получил это:
$ git push origin :in
фатальный: «происхождение» не похоже на git-репозиторий
Неустранимый: Не удалось прочитать из удаленного хранилища.
Пожалуйста, убедитесь, что у вас есть правильные права доступа и хранилище существует.
Скорее всего, это связано с тем, что у страницы не загружен закрытый ключ (который TortoiseGit автоматически загружает в страницу ). Более того, я заметил, что команды TortoiseGit не имеют originссылки в них (например git.exe push --progress "my_project" interesting_local:interesting).
Я также использую Bitbucket и, как и другие сетевые онлайн-менеджеры Git (GitHub, GitLab), я смог удалить удаленную ветку напрямую через их интерфейс (страница веток):
Тем не менее, в TortoiseGit вы также можете удалить удаленные ветки через Обзор ссылок :
Если щелкнуть правой кнопкой мыши на удаленной ветви (список удаленных), появится опция Удалить удаленную ветку :
Нажимать
После удаления старого удаленного филиала я толкнул прямо в новый удаленный филиал через TortoiseGit просто введя новое имя в Remote: поле Нажимает окно и эта ветвь была создана автоматически и отображается в Bitbucket .
Однако, если вы все еще предпочитаете делать это вручную, то, что еще не было упомянуто в этой теме, это -u= --set-upstream.
git push origin -u new_branch= git push -u new_branch
из описания документов :
Если конфигурация отсутствует, по умолчанию используется origin.
В конце я не набирал вручную и не использовал ни одну из команд, предложенных другими ответами здесь, так что, возможно, это может быть полезно для других в подобной ситуации.
проблема в том, что ваш пульт не называется origin. Вы должны назвать свой пульт, как вы получаете от запуска команды git remote. Git работает с sshтем, что подразумевает использование открытых + закрытых ключей. Я предполагаю, что Autoload Putty keysTortoiseGit просто автоматически загружает необходимые ключи, чтобы вы вообще могли что-либо делать с вашей удаленной ссылкой. Последнее, что git push -uне является псевдонимом для отправки в удаленную ветвь, это псевдоним для отправки в удаленную ветвь, которая была создана локально, и ее удаленная ссылка еще не имеет этой ветви .
Juanecabellob
1
@juancab -u- это псевдоним --set-upstreamи «если конфигурация отсутствует, по умолчанию используетсяorigin ». Сильвен и Шашанк используют это для продвижения во вновь созданную удаленную ветку . Ключевой вопрос может быть связано с Pageant , не имея его загрузке , когда я пытался git push origin :inна раковине. Так что я не понимаю вашего отрицательного мнения, я просто указал на мои и неадекватные детали в других ответах, объяснил их и решил их.
CPHPython
Вы заявляете неправильные вещи, и большая часть этого ответа не связана с самим вопросом. Если вы указываете, что сработало для вас, я призываю вас ограничить ответ тем, что сработало, и если вы действительно хотите дать объяснение, пожалуйста, сообщите себе лучше. Кстати, -uэто псевдоним для, --set-upstreamно это не псевдоним для продвижения в удаленную ветку, как вы сказали. Чтобы добавить в удаленную ветку, вам нужно однозначно git push <remote>, и, если она еще не удалена, вы добавляете git push -u <remote>. Следовательно, -uиспользуется для создания ссылки на ветку в удаленном режиме.
juanecabellob
1
@juancab, возможно, то, что вы сочли неправильным, было в основном псевдонимом или выбором слов. Я реструктурировал свой ответ и перефразировал его, чтобы дать полное объяснение решения, которое я нашел для переименования удаленной ветви.
CPHPython
Я бы перефразировал это дальше. Теперь это имеет больше смысла, но это все еще слишком долго. Я бы более конкретно отнесся к проблеме, то есть скажу, что для пользователей TortoiseGit предложенные решения не будут работать. Вы рассказываете историю, и это сбивает с толку и заставляет пользователей избегать чтения. Я отредактирую ваш ответ предложением.
juanecabellob
1
Я не знаю почему, но ответ @Sylvain Defresne не работает для меня.
Я не знаю, правильно это или неправильно, но я поместил «старое имя» ветви в «новое имя» ветви, а затем полностью удалил старую ветку следующими двумя строками:
В добавление к уже приведенным ответам, вот версия, которая сначала проверяет, существует ли новая ветвь (так что вы можете безопасно использовать ее в скрипте)
if git ls-remote --heads "$remote" \
| cut -f2 \
| sed 's:refs/heads/::' \
| grep -q ^"$newname"$; then
echo "Error: $newname already exists"
exit 1
fi
git push "$oldname" "$remote/$oldname:refs/heads/$newname" ":$oldname"
git push origin origin/old_name:refs/heads/new_name && git push origin :old_name
.Ответы:
Вам просто нужно создать новую локальную ветку с нужным именем, отправить ее на удаленный компьютер, а затем удалить старую удаленную ветку:
Затем, чтобы увидеть старое имя ветки, каждый клиент репозитория должен сделать:
ПРИМЕЧАНИЕ. Если ваша старая ветка является вашей основной веткой, вам следует изменить настройки основной ветки. В противном случае при запуске
$ git push origin :old-branch-name
вы получите сообщение об ошибке «удаление текущей ветки запрещено» .источник
git fetch origin --prune
(для эффективного извлечения новых веток, а также избавления от ссылок, которые больше не находятся на удаленном компьютере).-d
или--delete
вместо:
новых версий git.Если вы действительно хотите переименовать ветки удаленно, без переименования каких-либо локальных веток одновременно , вы можете сделать это с помощью одной команды:
Я написал этот скрипт ( git-rename-remote-branch ), который предоставляет удобный ярлык для простого выполнения вышесказанного.
В качестве функции bash:
Чтобы интегрировать комментарий @ ksrb : в основном это делается двумя нажатиями в одной команде: сначала
git push <remote> <remote>/<old_name>:refs/heads/<new_name>
нажать новую удаленную ветку на основе старой удаленной ветви отслеживания, а затемgit push <remote> :<old_name>
удалить старую удаленную ветку.источник
git push <remote>/<old_name>:refs/heads/<new_name>
нажатия, означает нажатие нового пульта, который использует старый пульт в качестве src, а затемgit push [space]:<old_name>
удаление старого пультаrefs/heads/name
? Разве вы не можете просто использоватьname
напрямую, делая первую командуgit push <remote> <remote>/<old_name>:<new_name>
?<new_name>
еще не существует. Если ветка не существует, Git требует, чтобы вы использовали полное имя, так как в противном случае<new_name>
также можно сослаться на имя тега.refs/heads/<new_name>
уже существует. Удаление все еще успешно, в результате чего<remote>/<old_name>
только удаляется. Некоторые проверки перед рукой могут легко избежать этого.Первая проверка в ветке, которую вы хотите переименовать:
Чтобы удалить старую ветку из
remote
:источник
git push -u origin new_branch
), иначе переименованная ветвь (new_branch) продолжит отслеживать origin / old_branch. И как только вы удалите удаленный old_branch, new_branch все равно будет отслеживать origin / old_branch, хотя теперь эта ветвь исчезла.Конечно. Просто переименуйте ветку локально, нажмите на новую ветку и удалите старую.
Единственная реальная проблема заключается в том, что другие пользователи хранилища не будут переименовывать локальные ветви отслеживания.
источник
TL; DR
«Переименование» удаленной ветви на самом деле является двухэтапным процессом (не обязательно заказывается):
git push [space]:<old_name>
как объяснил ksrb );Удаление
Я использую TortoiseGit, и когда я впервые попытался удалить ветку через командную строку, я получил это:
Скорее всего, это связано с тем, что у страницы не загружен закрытый ключ (который TortoiseGit автоматически загружает в страницу ). Более того, я заметил, что команды TortoiseGit не имеют
origin
ссылки в них (напримерgit.exe push --progress "my_project" interesting_local:interesting
).Я также использую Bitbucket и, как и другие сетевые онлайн-менеджеры Git (GitHub, GitLab), я смог удалить удаленную ветку напрямую через их интерфейс (страница веток):
Тем не менее, в TortoiseGit вы также можете удалить удаленные ветки через Обзор ссылок :
Если щелкнуть правой кнопкой мыши на удаленной ветви (список удаленных), появится опция Удалить удаленную ветку :
Нажимать
После удаления старого удаленного филиала я толкнул прямо в новый удаленный филиал через TortoiseGit просто введя новое имя в Remote: поле Нажимает окно и эта ветвь была создана автоматически и отображается в Bitbucket .
Однако, если вы все еще предпочитаете делать это вручную, то, что еще не было упомянуто в этой теме, это
-u
=--set-upstream
.Из
git push
документации ,-u
это всего лишь псевдоним--set-upstream
, так что команды в ответах Сильвиану (-set-upstream new-branch
) и Shashank (-u origin new_branch
) эквивалентны, так как отдаленные реф по умолчанию , чтобыorigin
, если никакой другой ссылок не было определено ранее:git push origin -u new_branch
=git push -u new_branch
из описания документов :В конце я не набирал вручную и не использовал ни одну из команд, предложенных другими ответами здесь, так что, возможно, это может быть полезно для других в подобной ситуации.
источник
origin
. Вы должны назвать свой пульт, как вы получаете от запуска командыgit remote
. Git работает сssh
тем, что подразумевает использование открытых + закрытых ключей. Я предполагаю, чтоAutoload Putty keys
TortoiseGit просто автоматически загружает необходимые ключи, чтобы вы вообще могли что-либо делать с вашей удаленной ссылкой. Последнее, чтоgit push -u
не является псевдонимом для отправки в удаленную ветвь, это псевдоним для отправки в удаленную ветвь, которая была создана локально, и ее удаленная ссылка еще не имеет этой ветви .-u
- это псевдоним--set-upstream
и «если конфигурация отсутствует, по умолчанию используетсяorigin
». Сильвен и Шашанк используют это для продвижения во вновь созданную удаленную ветку . Ключевой вопрос может быть связано с Pageant , не имея его загрузке , когда я пыталсяgit push origin :in
на раковине. Так что я не понимаю вашего отрицательного мнения, я просто указал на мои и неадекватные детали в других ответах, объяснил их и решил их.-u
это псевдоним для,--set-upstream
но это не псевдоним для продвижения в удаленную ветку, как вы сказали. Чтобы добавить в удаленную ветку, вам нужно однозначноgit push <remote>
, и, если она еще не удалена, вы добавляетеgit push -u <remote>
. Следовательно,-u
используется для создания ссылки на ветку в удаленном режиме.Я не знаю почему, но ответ @Sylvain Defresne не работает для меня.
Я должен сбросить восходящий поток и затем снова установить поток. Вот как я это сделал.
источник
Я не знаю, правильно это или неправильно, но я поместил «старое имя» ветви в «новое имя» ветви, а затем полностью удалил старую ветку следующими двумя строками:
источник
Вы можете создать новую ветвь на основе ветки со старым именем. Так же, как это, затем удалите старую ветку, снова !!!
источник
В добавление к уже приведенным ответам, вот версия, которая сначала проверяет, существует ли новая ветвь (так что вы можете безопасно использовать ее в скрипте)
(чек от этого ответа )
источник
git show-ref --quiet --verify -- refs/heads/$new_name
вместоls-remote | cut | sed | grep
.