Переименовать ветку master для локальных и удаленных репозиториев Git
у меня есть филиал master
, которая отслеживает удаленный филиал origin/master
.
я хочу переименовать их в master-old
как локально, так и на удаленном. Это возможно? Для других пользователей, которые отслеживали origin/master
(и кто всегда обновлял свои локальные master
филиала по git pull
), что произойдет после того, как я переименовал удаленную ветку? Бы их git pull
все еще работает или он бросит ошибку, которую он не смог найти
15 ответов
самое близкое к переименованию-удаление, а затем повторное создание на удаленном компьютере. Например:
git branch -m master master-old
git push remote :master # delete master
git push remote master-old # create master-old on remote
git checkout -b master some-ref # create a new local master
git push remote master # create master on remote
однако это имеет много предостережений. Во - первых, никакие существующие проверки не будут знать о переименовании-git does не попытка отслеживать переименования ветвей. Если новый master
еще не существует, git pull будет ошибка. Если новый master
была создана. тяга будет пытаться объединить master
и master-old
. Так это вообще плохая идея, если у вас есть сотрудничество всех, кто ранее проверял хранилище.
Примечание: более новые версии git не позволят вам удаленно удалить главную ветвь по умолчанию. Вы можете переопределить это, установив receive.denyDeleteCurrent
значение конфигурации warn
или ignore
на пульт ДУ репозитория. В противном случае, если вы готовы сразу создать новый мастер, пропустите git push remote :master
шаг, и передают --force
до git push remote master
шаг. Обратите внимание, что если вы не можете изменить remote конфигурация, вы не сможете полностью удалить главную ветку!
это предостережение относится только к текущей ветви (обычно master
ветвь); любая другая ветвь может быть удалена и воссоздана, как указано выше.
предполагая, что вы в настоящее время на master
:
git push origin master:master-old # 1
git branch master-old origin/master-old # 2
git reset --hard $new_master_commit # 3
git push -f origin # 4
- сначала
master-old
филиала вorigin
репозиторий, основанный наmaster
commit в локальном репозитории. - создайте новую локальную ветвь для этого нового
origin/master-old
ветвь (которая будет автоматически настроена правильно как ветвь отслеживания). - теперь укажите ваш местный
master
к какой бы фиксации вы ни указали. - наконец, force-change
master
вorigin
репозиторий, чтобы отразить ваш новый локальныйmaster
.
(если вы делаете это любым другим способом, вам нужно, по крайней мере, еще один шаг, чтобы убедиться, что master-old
правильно настроен для отслеживания origin/master-old
. Ни одно из других решений, опубликованных на момент написания этой статьи, не включает это.)
с Git v1.7, я думаю, что это немного изменилось. Обновление ссылки отслеживания вашей локальной ветви на новый пульт теперь очень просто.
git branch -m old_branch new_branch # Rename branch locally
git push origin :old_branch # Delete the old branch
git push --set-upstream origin new_branch # Push the new branch, set local branch to track the new remote
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name
возможно, вам придется вручную переключиться на new-branch-name
перед удалением old-branch-name
есть много способов переименовать ветку, но я собираюсь сосредоточиться на большей проблеме: "как позволить клиентам перемотать вперед и не возиться со своими филиалами локально".
это что-то на самом деле легко сделать, но не злоупотребляйте этим. Вся идея зависит от коммитов слияния; поскольку они позволяют перемотать вперед и связать истории ветви с другой.
переименование бранч:
# rename the branch "master" to "master-old"
# this works even if you are on branch "master"
git branch -m master master-old
создание новой ветви" master":
# create master from new starting point
git branch master <new-master-start-point>
создание фиксации слияния, чтобы иметь историю "родитель-потомок":
# now we've got to fix the new branch...
git checkout master
# ... by doing a merge commit that obsoletes
# "master-old" hence the "ours" strategy.
git merge -s ours master-old
и вуаля.
git push origin master
это работает, потому что создание merge
commit позволяет быстрая перемотка вперед ветвь к новой редакции.
используя разумное сообщение фиксации слияния:
renamed branch "master" to "master-old" and use commit ba2f9cc as new "master"
-- this is done by doing a merge commit with "ours" strategy which obsoletes
the branch.
these are the steps I did:
git branch -m master master-old
git branch master ba2f9cc
git checkout master
git merge -s ours master-old
Я предполагаю, что вы все еще спрашиваете о той же ситуации, что и в вашем предыдущий вопрос. То есть master-new не будет содержать master-old в своей истории.* Если вы назовете master-new "master", у вас будет эффективно переписана история. Это не имеет значения как
другие пользователи, пытающиеся вытащить, пока master не существует просто их тяги потерпят неудачу (нет такого ref на удаленном), и как только он снова появится в новом месте, их тяги должны будут попытаться объединить своего мастера с новым удаленным мастером, так же, как если бы вы объединили мастер-старый и мастер-новый в своем репозитории. Учитывая то, что вы пытаетесь сделать здесь, слияние будет иметь конфликты. (Если бы они были разрешены, и результат был бы возвращен в хранилище, вы были бы в еще худшем состоянии - обе версии истории там.) ответить вопрос просто: вы должны принять, что иногда в вашей истории будут ошибки. Все нормально. Это случается со всеми. В git есть обратные коммиты.репозиторий git. Важно то, что как только мы публикуем историю, это то, чему каждый может доверять. *Если бы это было так, это было бы эквивалентно нажатию некоторых изменений на master, а затем созданию новой ветви, где она раньше была. Не проблема.
на выбранный ответ не удалось, когда я попробовал его. Он выдает ошибку: refusing to delete the current branch: refs/heads/master
. Думаю, я опубликую то, что работает для меня:
git checkout master # if not in master already
git branch placeholder # create placeholder branch
git checkout placeholder # checkout to placeholder
git push remote placeholder # push placeholder to remote repository
git branch -d master # remove master in local repository
git push remote :master # remove master from remote repository.
трюк состоит в том, чтобы проверить заполнитель прямо перед его перемещением в удаленный репозиторий. Остальное само собой разумеется, удаление главной ветви и ее нажатие в удаленный репозиторий должно работать сейчас. Выдержка из здесь.
хорошо. Мои 2 цента. Как насчет входа на сервер, перехода в каталог git и переименования ветки в голом репозитории. Это не имеет всех проблем, связанных с повторной загрузкой той же ветви. Фактически, "клиенты" автоматически распознают измененное имя и изменяют свою удаленную ссылку. После этого (или до) вы также можете изменить локальное имя ветви.
о:
git checkout old-branch-name
git push remote-name new-branch-name
git push remote-name :old-branch-name
git branch -m new-branch-name
Это самый простой и наиболее "читаемый" способ, который я знаю:
"переместить" локальную ветвь с помощью -m
git branch -m my_old_branch_name my_new_branch_name
нажимаем "переехал" филиал в пульте, набор 'вверх' через -у
git push origin -u my_new_branch_name
(установка "вверх по течению" по существу "соединяет" вашу локальную ветвь с удаленным, так что такие вещи, как fetch, pull и push, будут работать)
удалить старую ветку с пульта
git push origin -D <old_name>
(ваша местная ветвь уже ушла, потому что вы "переместили" ее на 1-м шаге)
OK, переименовании филиала и локально и пульт довольно легко!...
если вы на ветке, вы можете легко сделать:
git branch -m <branch>
или если нет, то вам нужно сделать:
git branch -m <your_old_branch> <your_new_branch>
затем нажимаем удаление к удаленному такой:
git push origin <your_old_branch>
теперь вы сделали, если вы получаете ошибку вверх по течению при попытке нажать, просто do:
git push --set-upstream origin <your_new_branch>
Я также создаю изображение ниже, чтобы показать шаги в реальной командной строке, просто следуйте инструкциям, и вам будет хорошо:
вы можете сделать следующее:
git -m master master-old #rename current master
git checkout -b master #create a new branch master
git push -f origin master #force push to master
но принудительное нажатие-плохая идея, если другие люди используют этот репозиторий. Принудительный толчок приведет к конфликту их истории пересмотра с новой.
для выполнения задания в сценарий оболочки можно сохранить следующее:
например:
remote="origin"
if [ "$#" -eq 0 ] # if there are no arguments, just quit
then
echo "Usage: oldName newName or newName" >&2
exit 1
elif
[ "$#" -eq 1 ] # if only one argument is given, rename current branch
then
oldBranchName="$(git branch | grep \* | cut -d ' ' -f2)" #save current branch name
newBranchName=
else
oldBranchName=
newBranchName=
fi
git branch -m $oldBranchName $newBranchName
git push $remote :$oldBranchName #delete old branch on remote
git push --set-upstream $remote $newBranchName # add new branch name on remote and track it
обратите внимание, что здесь по умолчанию удаленное имя "origin" жестко закодировано, вы можете расширить скрипт, чтобы сделать его настраиваемым!
затем этот скрипт можно использовать с псевдонимами bash, Git или, например, в пользовательских действиях sourcetree.
Я считаю, что ключом является осознание того, что вы выполняете двойной переименовать: master
to master-old
и master-new
до master
.
из всех других ответов я синтезировал это:
doublerename master-new master master-old
где мы сначала должны определить doublerename
функция Bash:
# doublerename NEW CURRENT OLD
# - arguments are branch names
# - see COMMIT_MESSAGE below
# - the result is pushed to origin, with upstream tracking info updated
doublerename() {
local NEW=
local CUR=
local OLD=
local COMMIT_MESSAGE="Double rename: $NEW -> $CUR -> $OLD.
This commit replaces the contents of '$CUR' with the contents of '$NEW'.
The old contents of '$CUR' now lives in '$OLD'.
The name '$NEW' will be deleted.
This way the public history of '$CUR' is not rewritten and clients do not have
to perform a Rebase Recovery.
"
git branch --move $CUR $OLD
git branch --move $NEW $CUR
git checkout $CUR
git merge -s ours $OLD -m $COMMIT_MESSAGE
git push --set-upstream --atomic origin $OLD $CUR :$NEW
}
это похоже на изменение истории git rebase
в том, что содержимое филиала совершенно другое, но оно отличается тем, что клиенты все еще могут безопасно перемотка вперед с git pull master
.