[英]Rename master branch for both local and remote Git repositories
我有分支master
追踪远程分支origin/master
。
我想在本地和远程将它们重命名为master-old
。 这可能吗?
对于跟踪origin/master
其他用户(并且总是通过git pull
更新他们的本地master
分支),在我重命名远程分支后会发生什么?
他们的git pull
仍然有效,还是会抛出一个错误,无法找到origin/master
?
然后,进一步,我想创建一个新的master
分支(本地和远程)。 同样,在我这样做之后,如果其他用户执行git pull
会发生什么?
我想这一切都会带来很多麻烦。 有没有一种干净的方法来获得我想要的东西? 或者我应该离开master
,因为它是创造一个新的分支master-new
上更进一步,只是在那里工作?
最接近重命名的是删除然后在遥控器上重新创建。 例如:
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
。 pull 将尝试合并master
和master-old
。 所以这通常是一个坏主意,除非您有之前签出存储库的每个人的合作。
注意:默认情况下,较新版本的 Git 将不允许您远程删除 master 分支。 您可以通过将receive.denyDeleteCurrent
配置值设置为warn
或ignore
远程存储库来覆盖它。 否则,如果您准备立即创建一个新的 master,请跳过git push remote :master
步骤,并将--force
传递给git push remote master
步骤。 请注意,如果您无法更改遥控器的配置,您将无法完全删除 master 分支!
这个警告只适用于当前分支(通常是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
提交,在origin
存储库中创建一个master-old
分支。origin/master-old
分支创建一个新的本地分支(它将自动正确设置为跟踪分支)。master
指向您希望它指向的任何提交。origin
存储库中强制更改master
以反映您的新本地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
在删除old-branch-name
new-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
# 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
我假设您仍在询问与上一个问题相同的情况。 也就是说,master-new 在其历史中不会包含 master-old。* 如果你将 master-new 称为“master”,你将有效地重写历史。 不管你如何进入一种状态,在这种状态中,主人不是以前主人的位置的后代,只是它处于那个状态。
其他用户在 master 不存在的情况下尝试 pull 只会导致他们的 pull 失败(远程上没有这样的 ref),一旦它再次出现在新的地方,他们的 pull 将不得不尝试将他们的 master 与新的远程 master 合并,就像您在存储库中合并了 master-old 和 master-new 一样。 鉴于您在这里尝试做的事情,合并会产生冲突。 (如果它们得到解决,并且结果被推回存储库,您将处于更糟糕的状态 - 两个版本的历史记录都在那里。)
简单地回答你的问题:你应该接受你的历史有时会出现错误。 这没关系。 它发生在每个人身上。 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 # Check out 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.
诀窍是在将占位符推送到远程存储库之前先签出占位符。 其余的不言自明; 删除 master 分支并将其推送到远程存储库现在应该可以工作了。 摘自这里。
登录服务器,进入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
这是我所知道的最简单、最“易读”的方式:
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>
您的本地分支已经消失了,因为您在第一步中“移动”了它。
您可以执行以下操作:
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
但是如果其他人正在共享这个存储库,强制推送是一个坏主意。 强制推送会导致他们的修订历史与新的冲突。
可以将以下内容保存到 shell 脚本中来完成这项工作:
例如:
remote="origin"
if [ "$#" -eq 0 ] # if there are no arguments, just quit
then
echo "Usage: $0 oldName newName or $0 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=$1
else
oldBranchName=$1
newBranchName=$2
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自定义操作中使用。
转到 github.com 或任何地方,单击分支,然后重命名它。 然后在本地运行这些:
git branch -m <old-branch-name> <new-branch-name>
git fetch origin
git branch -u origin/<new-branch-name> <new-branch-name>
我相信关键是意识到您正在执行双重重命名: master
到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
快进。
git update-ref newref oldref
git update-ref -d oldref newref
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.