【问题标题】:Make the current Git branch a master branch将当前 Git 分支设为 master 分支
【发布时间】:2011-02-15 07:42:18
【问题描述】:

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

然后,数十次提交后,我意识到分支的状态比 master 好得多,所以我希望分支“成为”master 而忽略 master 上的更改。

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

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

【问题讨论】:

标签: git


【解决方案1】:

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

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

【讨论】:

  • 注意 git 的合并“策略”:--strategy=ours--strategy=recursive -Xours 不同。 IE。 “我们的”本身可以是一个策略(无论如何结果都将是当前分支),或者作为“递归”策略的选项传递(引入其他分支的更改,并在发生冲突时自动优先选择当前分支的更改) .
  • 我必须让第二行 git merge --strategy=ours master -m "new master" 才能工作。
  • @Johsm 这正是我的回答的第一句话所说的。如果你这样做,新主人将不会有与旧主人相同的历史,如果你想推/拉,这是非常糟糕的。您需要有共同的祖先才能正常工作;如果相反,您按照您所说的去做,那么当您尝试推动它时,除非您强迫它,否则它只会失败(因为这很糟糕,它会试图阻止您),如果您确实强迫它,那么随后拉动的任何人将尝试合并旧主和新主,这可能是火车残骸。
  • 如果在合并过程中出现vi编辑器,输入:w(保存):q(退出vi)
  • 这个答案很好用。我只是想补充一点(对于可能是新手或不确定的人),如果您希望将代码推送到远程,则必须在此之后立即执行git push。您可能会看到类似Your branch is ahead of 'origin/master' by 50 commits. 的警告,这是意料之中的。推吧! :D
【解决方案2】:

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

git checkout main

用“better_branch”覆盖“main”:

git reset --hard better_branch

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

git push -f origin main

【讨论】:

  • 这可能是大多数人正在寻找的答案。 BS 策略合并的所有其他答案都不会完全取代分支。这让一切都如我所愿,只需覆盖分支并将其向上推即可。
  • 虽然这确实是很多人想要的,但应该注意的是,repo 的任何其他本地副本都需要git reset --hard origin/master 下次他们想要拉,否则 git 会尝试合并变成他们(现在)发散的地方。 this answer 详细解释了这种情况的危险
  • 还请注意,您需要被允许强制推送到存储库 - 例如,在商业环境中这将不起作用
  • 这里的好处也可能是坏处,这取决于人们想要什么。如果您想用另一个分支的历史记录替换 master 的历史记录,这就是您的答案。
  • 这是我一直在寻找的答案,因为我的新分支来自主提交。这使得以前 master 的任何分支都可以轻松地没有太多合并问题。
【解决方案3】:

编辑:您没有说您已推送到公共回购!这让世界变得与众不同。

有两种方式,“脏”方式和“干净”方式。假设您的分支名为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

【讨论】:

  • 谢谢。还有一个问题。我正在将其推送到 github。如果我这样做,那里会发生什么?
  • @Karel:它会给其他用户造成一些混乱;他们将不得不将他们的主人重置为 github 主人。如果您想避免给他们带来任何麻烦,请查看我的答案。
  • @Dietrick Epp:我不确定提出肮脏的方式是否是个好主意。它会搞乱远程跟踪、reflogs...想不出任何你会这样做的理由。
  • 啊,说得好。不过,你可以同时拥有它:git branch old-master master; git branch -f master new-master。重新创建备份分支,然后直接将 master 移动到 new-master。 (很抱歉拼错了你的名字,刚刚注意到)
  • @FakeName 我没有断定没有理由这样做,只是没有理由这样做肮脏的方式。您可以使用普通命令(如我之前的评论中所述)并获得相同的结果,除了引用日志完好无损且没有机会进行操作。而且它可以保证工作,因为您不会对实现细节感到困惑。
【解决方案4】:

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

git branch -M branch_name master

【讨论】:

  • 不幸的是 git 不跟踪分支重命名,所以如果你已经将你的 repo 推送到远程并且其他人在他们本地的旧 master 分支上进行了本地更改,他们将会遇到麻烦。
  • 这个和git checkout master&&git reset --hard better_branch有区别吗?
  • @thSoft 如果只有我在使用存储库怎么办?
【解决方案5】:

据我了解,您可以将当前分支分支到现有分支。本质上,这将用您在当前分支中的任何内容覆盖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

【讨论】:

  • 非常简单并且完美运行!两个简单易懂的 git 命令。我的 git repo 已保存,现在看起来超级干净。谢谢!
  • @thehelix 为什么在一些投票率较高的解决方案(在您撰写评论时也存在)如此简单的情况下选择此解决方案?
【解决方案6】:

我在博文中找到了我想要的答案Replace the master branch with another branch in git

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's answer 相同。除了“选项”下面他们的解决方案已经嵌入到上面的代码块中。

这样更容易找到。

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

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

【讨论】:

    【解决方案7】:

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

    目标:使“分支”的当前状态成为“主”

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

    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 将是您上次提交分支的确切状态,并且您的 master 提交日志将显示分支的所有签入。

    【讨论】:

      【解决方案8】:

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

      • 如果您在创建该分支后没有推送任何内容,您可以重命名并推送它而不会出现任何问题。
      • 如果您在 GitHub 上拥有 push master,则需要 'git push -f' 新分支:you can no longer push in a fast forward mode
      -F - 力量

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

      如果其他人已经提取了您的存储库,他们将无法提取新的主历史记录,除非用新的 GitHub 主分支替换他们自己的主分支(或处理大量合并)。
      alternatives to a git push --force for public repos
      Jefromi's answer(将正确的更改合并回原来的master)就是其中之一。

      【讨论】:

        【解决方案9】:

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

        git checkout master
        git checkout better_branch -- .
        

        然后提交所有更改。

        【讨论】:

          【解决方案10】:

          要添加到Cascabel's answer,如果不想在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>
          

          【讨论】:

            【解决方案11】:

            我的做事方式如下

            #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
            

            【讨论】:

              【解决方案12】:

              如果您在 Eclipse 中使用 eGit

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

              【讨论】:

              • 我这样做了,但不确定它是否有效。在 github 上,没有任何变化,但在 git 扩展上,我可以看到分支已重命名。
              【解决方案13】:

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

              在开发中:

              git checkout master
              git pull
              
              git checkout develop
              git pull
              
              git reset --hard origin/master
              git push -f
              

              【讨论】:

              • 与所提问题无关
              【解决方案14】:

              以下步骤在由 Atlassian(Bitbucket 服务器)提供支持的 Git 浏览器中执行

              将 {current-branch} 设为 master

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

              【讨论】:

                【解决方案15】:

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

                这就是你的情况,

                1. 您需要一个具有新的优秀新突破特性但当前不是 prod 的分支。你有计划在未来让它成为产品。
                2. 您当前的 prod 分支(master)运行良好,但很无聊。您可以对其进行一些小改动。
                3. 您希望保持当前主(生产)分支的安全,以备日后需要时使用。

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

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

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

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

                所以,

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

                【讨论】:

                • 您能否将您的代码复制并粘贴到code 块中,而不是使用屏幕截图?使用屏幕截图被认为是不好的做法(可搜索性较差,盲人软件无法阅读,无法复制粘贴等)
                • @user1271772 我实际上尝试这样做而不是拍摄图像(这就是图像的内容在 ascii 中的原因),但是 stackoverflow 弄乱了单词,如果在移动/较小的设备中查看,它会没有任何意义。这就是为什么我决定以图像形式保存它。不过谢谢你的暗示。
                • 它看起来一样,除了和屏幕截图相比,这个版本中多了一个--X--&gt;。哪些词搞砸了?
                • 它看起来有效。在有序列表之后插入代码块存在一些问题。一些涉及空格的试验和错误解决了这个问题。再次感谢。
                • 是的,我想您必须将so 添加到其中。当你有 -1 时,我是给你 +1 的人,所以我不能再次投票,但感谢你修复它。
                【解决方案16】:

                只要去 gitlab 或 github 网站找设置即可。

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

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

                我在 gitlab 中尝试过,它成功了。

                【讨论】:

                  猜你喜欢
                  • 2011-11-01
                  • 2016-07-24
                  • 2015-01-21
                  • 2016-04-30
                  • 2012-07-26
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多