Переименовать главную ветвь для локальных и удаленных репозиториев Git

У меня есть ветвь master, которая отслеживает удаленную ветвь origin/master.

Я хочу переименовать их в master-old как локально, так и на удаленный. Это возможно? Для других пользователей, которые отслеживали origin/master (и кто всегда обновлял свой локальный ветвь master через git pull), что произойдет после того, как я переименовал удаленную ветку? Будут ли их git pull еще работать или выкинуть ошибку, чтобы она больше не могла найти origin/master?

Затем, далее, я хочу создать новую ветвь master (как локально, так и удаленно). Опять же, после того, как я это сделал, что произойдет, если другие пользователи сделают git pull?

Думаю, все это приведет к большим проблемам. Есть ли чистый способ получить то, что я хочу? Или я должен просто оставить master как есть и создать новую ветку master-new и просто работать там дальше?

Ответ 1

Самое близкое к переименованию - удаление, а затем повторное создание на пульте дистанционного управления. Например:

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 не пытается отслеживать переименования веток. Если новый master еще не существует, git pull выйдет из строя. Если новый master был создан. притяжение будет пытаться объединить master и master-old. Так что это вообще плохая идея, если у вас нет сотрудничества со всеми, кто ранее проверил репозиторий.

Примечание. Более новые версии git не позволяют удаленно удалять мастер-ветвь по умолчанию. Вы можете переопределить это, установив значение конфигурации receive.denyDeleteCurrent в warn или ignore в удаленном репозитории. В противном случае, если вы готовы сразу же создать новый мастер, пропустите шаг git push remote :master и перейдите --force на шаг git push remote master. Обратите внимание, что если вы не можете изменить удаленную конфигурацию, вы не сможете полностью удалить ведущую ветвь!

Это оговорка относится только к текущей ветке (обычно ветки master); любая другая ветвь может быть удалена и воссоздана, как указано выше.

Ответ 2

Предполагая, что вы в данный момент находитесь на 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 в локальном репозитории.
  • Создайте новую локальную ветвь для этой новой ветки origin/master-old (которая будет автоматически настроена как ветка отслеживания).
  • Теперь укажите локальный master на то, что вы хотите, чтобы он указал.
  • Наконец, force-change master в репозитории origin, чтобы отразить ваш новый локальный master.

(Если вы это сделаете каким-либо другим способом, вам понадобится хотя бы еще один шаг, чтобы обеспечить правильную настройку master-old для отслеживания origin/master-old. Ни одно из других решений, опубликованное на момент написания этой статьи,.)

Ответ 3

С 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

Ответ 4

git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name

Вам может потребоваться вручную переключиться на new-branch-name перед удалением old-branch-name

Ответ 5

Существует много способов переименования ветки, но я собираюсь сосредоточиться на более серьезной проблеме: "как разрешить клиентам ускоренную перемотку вперед и не связываться с их ветвями локально" .

Сначала быстрая картина: переименовать главную ветку и разрешить клиентам ускоренную перемотку вперед

Это действительно легко сделать; но не злоупотребляйте им. Вся идея зависит от слияния; так как они позволяют ускоренную перемотку и историю связей ветки с другой.

переименование ветки:

# 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 позволяет быстро пересылать ветку в новую ревизию.

с помощью сообщения с разумным сообщением о слиянии:

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

Ответ 6

Я предполагаю, что вы все еще спрашиваете о той же ситуации, что и в предыдущем вопросе . То есть, мастер-новый не будет содержать мастер-старый в своей истории. * Если вы назовете мастер-новый "мастер", вы эффективно перепишете историю. Неважно, как вы попадаете в состояние, в котором мастер не является потомком предыдущей позиции мастера, просто потому, что он находится в этом состоянии.

Другие пользователи, пытающиеся вытащить, в то время как мастер не существует, просто будут терпеть неудачу (нет такой ссылки на пульт), и как только он снова появится на новом месте, их тяги будут пытаться объединить свой мастер с новым удаленный мастер, так же, как если бы вы объединили мастер-старый и мастер-новый в своем репозитории. Учитывая то, что вы пытаетесь сделать здесь, слияние будет иметь конфликты. (Если они были разрешены, и результат был возвращен в репозиторий, вы оказались бы в еще худшем состоянии - обе версии истории там.)

Чтобы ответить на ваш вопрос просто: вы должны признать, что иногда в вашей истории будут ошибки. Это нормально. С кем не бывает. В репозитории git.git возвращены фиксации. Важно то, что как только мы публикуем историю, это все, кому можно доверять.

* Если бы это было так, это было бы эквивалентно нажатию некоторых изменений на master, а затем создание новой ветки, где она была раньше. Нет проблем.

Ответ 7

выбранный ответ не удалось, когда я его попробовал. Это вызывает ошибку: 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.

Фокус в том, чтобы проверить правильность закладок перед тем, как направить его в удаленный репозиторий. Остальное самоочевидно, удаление мастер-ветки и последующее нажатие на удаленный репозиторий должно работать. Выдержка из здесь.

Ответ 8

Хорошо. Мои 2 цента. Как насчет входа в систему на сервере, перехода в каталог git и переименование ветки в голом репозитории. У этого нет всех проблем, связанных с повторной загрузкой одной ветки. Фактически, "клиенты" автоматически распознают измененное имя и изменят свою удаленную ссылку. Впоследствии (или раньше) вы также можете изменить локальное имя ветки.

Ответ 9

Как насчет:

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

Ответ 10

ОК, переименование ветки как локально, так и удаленной довольно просто!...

Если вы на ветке, вы можете сделать:

git branch -m <branch>

или если нет, вам нужно сделать:

git branch -m <your_old_branch> <your_new_branch>

Затем нажмите на удаленное удаление следующим образом:

git push origin <your_old_branch>

Теперь вы сделали, если у вас возникла ошибка восходящего потока во время попытки нажатия, просто выполните:

git push --set-upstream origin <your_new_branch>

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

введите описание изображения здесь

Ответ 11

Вы можете сделать следующее:

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

Но принудительное нажатие - это плохая идея, если другие люди используют этот репозиторий. Силовое нажатие приведет к тому, что история их пересмотра будет конфликтовать с новой.

Ответ 12

Я считаю, что ключ - это осознание того, что вы выполняете двойное переименование: 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=$1
  local CUR=$2
  local OLD=$3
  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.

Ответ 13

git update-ref newref oldref
git update-ref -d oldref newref