为本地和远程Git存储库重命名master分支

时间:2009-10-06 16:51:57

标签: git git-branch

我有跟踪远程分支master的分支origin/master

我想在本地和远程将它们重命名为master-old。那可能吗?对于跟踪origin/master(以及始终通过master更新其本地git pull分支的用户)的其他用户,重命名远程分支后会发生什么?他们的git pull是否仍然可以使用,或者它会抛出一个找不到origin/master的错误?

然后,继续,我想创建一个新的master分支(本地和远程)。再说一遍,在我这样做之后,如果其他用户做git pull会发生什么?

我猜这一切都会带来很多麻烦。是否有一种干净的方式来获得我想要的东西?或者我应该保持原样master并创建一个新分支master-new并在那里继续工作?

16 个答案:

答案 0 :(得分:594)

最接近重命名的是删除然后在遥控器上重新创建。例如:

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。拉动将尝试合并mastermaster-old。所以这通常是一个坏主意,除非你得到了之前已经检查过存储库的每个人的合作。

注意:较新版本的git默认情况下不允许远程删除master分支。您可以通过将远程存储库上的receive.denyDeleteCurrent配置值设置为warnignore来覆盖此设置。否则,如果您已准备好立即创建新主服务器,请跳过git push remote :master步骤,然后将--force传递到git push remote master步骤。请注意,如果您无法更改遥控器的配置,您将无法完全删除主分支!

此警告仅适用于当前分支(通常是master分支);任何其他分支都可以删除并重新创建,如上所述。

答案 1 :(得分:253)

假设您目前在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
  1. 首先在master-old存储库中根据本地存储库中的origin提交创建一个master分支。
  2. 为这个新的origin/master-old分支创建一个新的本地分支(它将自动正确设置为跟踪分支)。
  3. 现在将您的本地master指向您希望它指向的任何提交。
  4. 最后,强制更改master存储库中的origin以反映您的新本地master
  5. (如果您以任何其他方式执行此操作,则至少需要再执行一个步骤,以确保master-old已正确设置为跟踪origin/master-old。其他所有解决方案均未在这篇文章包括。)

答案 2 :(得分:151)

使用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

答案 3 :(得分:35)

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

在删除new-branch-name

之前,您可能需要手动切换到old-branch-name

答案 4 :(得分:26)

有很多方法可以重命名分支,但我将专注于更大的问题:“如何让客户快进而不必在本地弄乱他们的分支”

首先快速了解一下: renaming master branch and allowing clients to fast-forward

这实际上很容易做到;但不要滥用它。 整个想法取决于合并提交;因为它们允许快进,并将分支的历史链接与另一个分支。

重命名分支:

# 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

答案 5 :(得分:11)

我假设你仍在询问与previous question相同的情况。也就是说,master-new在其历史中不会包含master-old。*如果你称为master-new“master”,你将有效地重写历史记录。无论如何进入一个状态,其中master不是master的前一个位置的后代,只是它处于该状态。

其他试图在主人不存在时拉动的用户只会让他们的拉动失败(在远程没有这样的参考),一旦它再次存在于新的地方,他们的拉动将不得不尝试将他们的主人与新的合并远程主服务器,就像您在存储库中合并master-old和master-new一样。考虑到你在这里尝试做什么,合并会产生冲突。 (如果它们被解决了,并且结果被推回到存储库中,那么你将处于更糟糕的状态 - 那里的两个历史版本。)

简单地回答你的问题:你应该接受有时你的历史会有错误。这没关系。它发生在每个人身上。 git.git存储库中有还原的提交。重要的是,一旦我们发布历史,这是每个人都可以信任的东西。

*如果确实如此,这相当于将一些更改推送到master,然后创建一个新的分支。没问题。

答案 6 :(得分:8)

我尝试时selected answer失败了。它抛出一个错误: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.

诀窍是在将其推送到远程存储库之前将其签出到占位符。其余的是自我解释,删除主分支并将其推送到远程存储库应该现在工作。摘自here

答案 7 :(得分:3)

好。我的2美分。如何在服务器上登录,转到git目录并重命名裸存储库中的分支。这没有与重新上载同一分支相关的所有问题。实际上,'clients'会自动识别修改后的名称并更改其远程引用。之后(或之前),您还可以修改分支的本地名称。

答案 8 :(得分:1)

怎么样:

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

答案 9 :(得分:1)

确定,重命名本地远程的分支非常简单!...

如果你在分支机构,你可以很容易地做到:

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>

我还创建了下面的图片,以显示真实命令行中的步骤,只需按照步骤操作即可:

enter image description here

答案 10 :(得分:1)

这是我所知道的最简单,最“可读”的方式:

使用-m

'移动'本地分支
git branch -m my_old_branch_name my_new_branch_name

将“移动”分支推送到远程,使用-u

设置“上游”
git push origin -u my_new_branch_name

(设置'upstream'基本上'连接'你的本地分支到遥控器,这样就可以使用fetch,pull和push这样的东西了)

从远程

删除旧分支
git push origin -D <old_name>

(你的本地分支已经不见了,因为你'在第一步中'移动了'

答案 11 :(得分:0)

您可以执行以下操作:

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 :(得分:0)

以下内容可以保存到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自定义操作中使用。

答案 13 :(得分:0)

到 github.com 或任何地方,单击分支,然后重命名。然后在本地运行这些:

interface SkillType {
    end: string,
    ends_level: [
        {
            course: string,
            level: string
        }
    ]
}

interface DataType {
    profile: {
        name: string
    },
    skills: SkillType[]
}

let postData: DataType = {
    profile: {
        name: "",
    },
    skills: [
        {
            end: "",
            ends_level: [
                {
                    course: "",
                    level: ""
                }
            ]
        },
    ],
};

// Create a new holder with all the old skills
let newSkills : SkillType[] = [... postData.skills ];

// Will have multiple skills per post-data
// Each post-data will have multiple "ends_levels" in it
// Do you want to merge it so all of these blocks now have the new value e.target.value ??
// If so, manipulate newSkills

let newPostData: DataType = {
    ...postData,
    skills: newSkills
}

答案 14 :(得分:-1)

我认为关键是要意识到您正在执行双重重命名:mastermaster-old以及master-newmaster

从所有其他答案中我综合了这个:

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安全地快进。

答案 15 :(得分:-3)

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