使当前Git分支成为主分支


Make the current Git branch a master branch

我在Git中有一个存储库。我做了一个分支,然后对主分支和分支都做了一些更改。

然后,几十年后,我意识到分支的状态比主分支要好得多,所以我希望分支"成为"主分支,而忽略主分支的变化。

我不能合并它,因为我不想保留主控形状上的更改。我该怎么办?

额外:在这种情况下,"旧"主文件已经被push编辑到另一个存储库,如github。这是如何改变事情的?


另外两个答案的问题是,新主人没有老主人作为祖先,所以当你推动它时,其他人都会搞砸。这就是你想要做的:

1
2
3
4
git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

如果您希望自己的历史记录更清晰一点,我建议您在合并提交消息中添加一些信息,以便清楚地了解您所做的工作。将第二行更改为:

1
2
git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message


确保所有内容都被推送到远程存储库(Github)中:

1
git checkout master

用"更好的分支"覆盖"master":

1
git reset --hard better_branch

强制推送到远程存储库:

1
git push -f origin master


编辑:你没有说你推动了一个公共回购!这就是一个与众不同的世界。

有两种方式,"肮脏"和"干净"方式。假设您的分支机构名为new-master。这是干净的方法:

1
2
3
4
5
git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part.  Just don't.  But if you want to...
# git branch -d --force old-master

这将更改配置文件以匹配重命名的分支。

你也可以用不干净的方式来做,这不会更新配置文件。这是在上面的罩下发生的事情…

1
2
mv -i .git/refs/new-master .git/refs/master
git checkout master


将分支重命名为master

1
git branch -M branch_name master


根据我的理解,您可以将当前分支分支分支到现有分支。从本质上讲,这将用您在当前分支中拥有的内容覆盖master

1
git branch -f master HEAD

完成此操作后,通常可以推动本地master分支,也可能需要此处的力参数:

1
git push -f origin master

没有合并,没有长命令。简单地说,branchpush——但是,是的,这将改写master分支的历史,所以如果你在一个团队中工作,你必须知道你在做什么。

或者,我发现您可以将任何分支推送到任何远程分支,因此:

1
2
3
4
5
6
7
8
# This will force push the current branch to the remote master
git push -f origin HEAD:master

# Switch current branch to master
git checkout master

# Reset the local master branch to what's on the remote
git reset --hard origin/master


这里给出的解决方案(重命名"master"中的分支)并不强调远程(github)回购的后果:

  • 如果在创建分支之后您没有推送任何东西,那么您可以重命名它并毫无问题地推送它。
  • 如果您在Github上有push master,那么您将需要"git push-f"新分支:您不能再以快速前进模式推进。
1
2
    -f
    --force

Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. This flag disables the check. This can cause the remote repository to lose commits; use it with care.

如果其他人已经撤回了你的回购协议,他们将无法在没有用新的Github主分支替换他们自己的主分支(或处理大量合并)的情况下完成新的主历史记录。除了Git推送之外还有其他选择——公共回购的强制力。Jefromi的答案(将正确的更改合并回原始主文件)就是其中之一。


我发现这个简单的方法最有效。它不会重写历史记录,分支的所有以前的签入都将附加到主控形状中。没有丢失任何内容,您可以清楚地看到提交日志中发生了什么。

目标:使"支部"的现状成为"主人"

处理分支、提交和推送更改以确保本地和远程存储库是最新的:

1
2
3
git checkout master      # Set local repository to master
git reset --hard branch  # Force working tree and index to branch
git push origin master    # Update remote repository

在此之后,您的主服务器将是分支最后一次提交的确切状态,主提交日志将显示分支的所有签入。


您还可以将另一个分支的所有文件签入master:

1
2
git checkout master
git checkout better_branch -- .

然后提交所有更改。


我在博客文章中找到了我想要的答案,用Git中的另一个分支替换主分支:

1
2
3
4
5
git checkout feature_branch
git merge -s ours --no-commit master
git commit      # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch

这基本上与卡斯卡贝尔的答案相同。除了他在解决方案下面添加的"选项"已经嵌入到我的主代码块中。

这样更容易找到。

我将这个作为一个新的答案添加,因为如果我以后需要这个解决方案,我希望在一个代码块中使用所有的代码。

否则,我可以复制粘贴,然后阅读下面的详细信息,查看我应该更改的行-在我执行它之后。


再加上Jefromi的回答,如果您不想在source分支的历史中进行无意义的合并,可以为ours合并创建一个临时分支,然后将其丢弃:

1
2
3
4
5
6
git checkout <source>
git checkout -b temp            # temporary branch for merge
git merge -s ours <target>      # create merge commit with contents of <source>
git checkout <target>           # fast forward <target> to merge commit
git merge temp                  # ...
git branch -d temp              # throw temporary branch away

这样,合并提交将只存在于target分支的历史中。

或者,如果您根本不想创建合并,您可以简单地获取source的内容,并将其用于target上的新提交:

1
2
3
git checkout <source>                          # fill index with contents of <source>
git symbolic-ref HEAD <target>                 # tell git we're committing on <target>
git commit -m"Setting contents to <source>"   # make an ordinary commit with the contents of <source>

我的做事方式如下

1
2
3
4
5
6
7
8
#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop


如果在Eclipse中使用eGit:

  • 右键单击项目节点。
  • 选择团队→然后选择高级→然后重命名分支
  • 然后展开远程跟踪文件夹。
  • 选择名称错误的分支,然后单击"重命名"按钮,将其重命名为任何新名称。
  • 选择新的主控形状,然后将其重命名为主控形状。


以下步骤在Atlassian(BitBucket服务器)支持的Git浏览器中执行。

将当前分支设为master

  • master做一个分支,命名为"主副本"。
  • 从当前分支中创建分支,并将其命名为"当前分支-副本"。
  • 在存储库设置(bitback)中,将"默认分支"更改为指向"主副本"(没有此步骤,您将无法删除主副本-"在下一步")。
  • 删除"master"分支-我从源代码树执行了此步骤(您可以从CLI或Git浏览器执行此步骤)
  • 将"当前分支"重命名为"master",并推送到存储库(这将创建一个新的"master"分支"当前分支"仍然存在)。
  • 在存储库设置中,将"默认分支"更改为指向"master"。