使当前的Git分支成为主分支

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

然后,几十次提交后,我意识到分支的状态比主分支好得多,所以我希望分支“成为”主分支,而不管主分支的变化。

我无法合并它,因为我不想将更改保留在master上。我该怎么办?

额外:在这种情况下,“旧”主服务器已经被push编辑到另一个存储库,例如GitHub。这会如何改变事情?

905589 次浏览

编辑:你没有说你已经推送到公共存储库!那就大不相同了。

有两种方式,“脏”方式和“干净”方式。假设你的分支名为new-master。这是干净的方式:

git checkout new-mastergit branch -m master old-mastergit 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

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

你也可以用肮脏的方式来做,这不会更新配置文件。这就是上面提到的情况…

mv -i .git/refs/new-master .git/refs/mastergit checkout master

通过以下方式将分支重命名为master

git branch -M branch_name master

这里给出的解决方案(在'master'中重命名分支)并不坚持远程(GitHub)存储库的后果:

  • 如果你在创建分支后没有推送任何东西,你可以重命名它并推送它,没有任何问题。
  • 如果您在GitHub上有推送主,则需要将新分支“git push-f”:你不能再按快进模式了
-f--force

通常,该命令拒绝更新不是用于覆盖它的本地ref的祖先的远程ref。此标志禁用检查。这可能导致远程存储库丢失提交;小心使用它。

如果其他人已经拉取了你的仓库,他们将无法拉取新的主历史,而不用新的GitHub主分支替换他们自己的主分支(或处理大量合并)。
git推送的替代方案--force for public repos.
Jefromi的回答(将正确的更改合并回原始主服务器)就是其中之一。

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

git checkout better_branchgit merge --strategy=ours master    # keep the content of this branch, but record a mergegit checkout mastergit merge better_branch             # fast-forward master up to the merge

如果你想让你的历史更清晰一点,我建议在合并提交消息中添加一些信息,以清楚你做了什么。将第二行更改为:

git merge --strategy=ours --no-commit mastergit commit          # add information to the template merge message

还可以将其他分支中的所有文件签出到master:

git checkout mastergit checkout better_branch -- .

然后提交所有更改。

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

git branch -f master HEAD

完成后,您通常可以推送本地master分支,可能还需要参数:

git push -f origin master

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




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

# This will force push the current branch to the remote mastergit push -f origin HEAD:master
# Switch current branch to mastergit checkout master
# Reset the local master branch to what's on the remotegit reset --hard origin/master

确保所有内容都被推送到您的远程存储库(GitHub):

git checkout main

用“better_branch”覆盖“main”:

git reset --hard better_branch

强制推送到您的远程存储库:

git push -f origin main

我发现这个简单的方法效果最好。它不重写历史记录,所有以前的分支签入都将附加到主服务器。没有任何丢失,你可以清楚地看到提交日志中发生的事情。

目的:使“分支”的现状成为“主人”

在分支上工作,提交并推送您的更改,以确保您的本地和远程存储库是最新的:

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

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

要添加到卡斯卡贝尔的回答,如果您不想在source分支的历史记录中放置无意义的合并,您可以为ours合并创建一个临时分支,然后将其丢弃:

git checkout <source>git checkout -b temp            # temporary branch for mergegit merge -s ours <target>      # create merge commit with contents of <source>git checkout <target>           # fast forward <target> to merge commitgit merge temp                  # ...git branch -d temp              # throw temporary branch away

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

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

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>

如果您在Eclipse中使用eGit

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

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

git checkout feature_branchgit merge -s ours --no-commit mastergit commit      # Add a message regarding the replacement that you just didgit checkout mastergit merge feature_branch

它本质上与卡斯卡贝尔的回答相同。除了“选项”下面他们的解决方案已经嵌入在上面的代码块中。

更容易找到这种方式。

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

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

我做事的方式如下

#Backup branchgit checkout -b master_backupgit push origin master_backupgit checkout master#Hard Reset master branch to the last common commitgit reset --hard e8c8597#Mergegit merge develop

以下步骤在由艾特莱森提供支持的Git浏览器中执行

将{当前分支}设置为master

  1. master创建一个分支,并将其命名为“主重复”。
  2. 从{当前分支}中创建一个分支,并将其命名为“{当前分支}-复制”。
  3. 在存储库设置(比特桶)中,将“默认分支”更改为指向“主-重复”(如果没有此步骤,您将无法删除主-“在下一步”)。
  4. 删除“master”分支-我从源代码树中执行了这一步(您可以从CLI或Git浏览器执行)
  5. 将“{当前分支}”重命名为“主”并推送到存储库(这将创建一个新的“主”分支,但“{当前分支}”仍然存在)。
  6. 在存储库设置中,将“默认分支”更改为指向“主”。

对我来说,我希望我的develop分支在它领先后回到主分支。

在开发中:

git checkout mastergit pull
git checkout developgit pull
git reset --hard origin/mastergit push -f

我知道这不是OP想要的,但如果你知道你将来会遇到类似的问题,你可以这样做。

这是你的情况,

  1. 你需要一个分支,有新的优秀的新突破功能,但不是prod目前。你有计划在未来使其prod。
  2. 您当前的prod分支(master)运行良好,但很无聊。您可以对其进行一些小的更改。
  3. 如果以后需要,您希望保持当前的master(prod)分支的安全。

如果这让人感到困惑,请参阅下面的糟糕情况图表。

*bad situation*initial master   --->           added boring changes       ----merge---> you loose boring\                                                /---> (awesome branch) added awesome changes ---

要解决这个问题(即停止无聊的损失),请执行以下操作基本上,

  1. 通过执行git branch boring将无聊替换为您想要保留的任何名称来创建当前主服务器的副本
  2. 现在,您可以向主分支添加新的令人敬畏的功能,并向无聊分支添加无聊的功能。
  3. 您仍然可以继续更新无聊的分支,也许使用它永远不会合并它来掌握。您不会失去无聊的功能。
  4. 您的主分支将具有令人敬畏的功能。

所以,

*good situation*initial master   --->     added awesome changes     --->    Final master(awesome) branch\--->   (boring branch) added boring changes  ---> Dont merge to master  --X-->

只需转到gitlab或github网站并查找设置。

然后在设置下找到存储库。

找到默认分支,展开它,您可以获得重命名它或将其更改为其他分支的选项。

我在gitlab中尝试了这个,它奏效了。

我很惊讶这不是一个答案。这就是我所做的。

  1. 在我的文件系统中的不同目录中制作了2个repo副本,一个带有master,一个带有分支。
  2. 将所有文件从分支复制(手动)到master
  3. 将更改提交给master。

通过这种方式,有一个包含所有差异的单一提交,保留了提交历史,并且不需要硬推送。