将当前的 Git 分支设为主分支

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

然后,在数十次提交之后,我意识到分支的状态要比主服务器好得多,因此我希望分支 “成为” 主服务器,而忽略主服务器上的更改。

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

附加 :在这种情况下,“旧” 母版已经push送到另一个存储库,例如 GitHub。这如何改变事情?

答案

其他两个答案的问题在于,新主人没有老主人的祖先,因此当您按下它时,其他所有人都会陷入困境。这是您想做的:

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

如果您想更清楚地了解历史记录,建议您向合并提交消息中添加一些信息,以使您清楚自己所做的事情。将第二行更改为:

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

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

git checkout master

用 “better_branch” 覆盖 “master”:

git reset --hard better_branch

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

git push -f origin master

编辑:您不是说您已推送到公共仓库!那是一个与众不同的世界。

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

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

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

您也可以使用肮脏的方式进行操作,这不会更新配置文件。这就是上面所说的幕后故事...

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

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

git branch -M branch_name master

据我了解,您可以将当前分支分支到现有分支。本质上,这将用您当前分支中的所有内容覆盖master

git branch -f master HEAD

完成此操作后,通常可以推送本地master分支,这里可能也需要force参数:

git push -f origin master

没有合并,没有长命令。只需branchpush - 但是,是的, 这将重写 master分支的历史记录 ,因此,如果您在团队中工作,则必须知道您在做什么。




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

# 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' 新分支: 您将无法再以快进模式进行推送
-f
    --force

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

如果其他人已经撤回了您的仓库,他们将无法撤消该新的主历史记录,而无需用该新的 GitHub 主分支替换自己的主文件(或处理大量合并)。
git push --force可以替代公共回购
Jefromi 的答案 (将正确的更改合并回原始的主菜单 )就是其中之一。

我发现这种简单的方法效果最好。它不会重写历史记录,并且分支的所有先前签入将添加到主数据库中。没有任何损失,您可以在提交日志中清楚地看到发生了什么。

目标:将 “分支” 的当前状态设为 “主”

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

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

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

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

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

基本上与Cascabel 的答案相同。他解决方案下方添加的 “选项” 已经嵌入到我的主代码块中。

这种方式更容易找到。

我加入这是一个新的答案,因为如果我以后需要这个解决方案,我想拥有所有 会在一个代码块中使用的代码。

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

一个人也可以将另一个分支中的所有文件检出到 master:

git checkout master
git checkout better_branch -- .

然后提交所有更改。

为了增加 Jefromi 的答案,如果您不想在source分支的历史记录中添加无意义的合并,则可以为ours合并创建一个临时分支,然后将其丢弃:

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的新提交:

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>