我在 Git 中有一个存储库。我做了一个分支,然后对主分支和分支进行了一些更改。
然后,数十次提交后,我意识到分支的状态比 master 好得多,所以我希望分支“成为”master 而忽略 master 上的更改。
我无法合并它,因为我不想将更改保留在 master 上。我应该怎么办?
额外:在这种情况下,“旧”主服务器已经push
-ed 到另一个存储库,例如 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 main
用“better_branch”覆盖“main”:
git reset --hard better_branch
强制推送到您的远程存储库:
git push -f origin main
git reset --hard origin/master
,否则 git 会尝试将更改合并到他们(现在)不同的本地. this answer 中详细解释了这种情况的危险
编辑:您没有说您已推送到公共回购!这让世界变得与众不同。
有两种方式,“脏”方式和“干净”方式。假设您的分支名为 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
git branch old-master master; git branch -f master new-master
。重新创建备份分支,然后直接将 master 移动到 new-master。 (很抱歉拼错了你的名字,只是注意到了)
通过以下方式将分支重命名为 master
:
git branch -M branch_name master
git checkout master&&git reset --hard better_branch
有区别吗?
据我了解,您可以将当前分支分支到现有分支。本质上,这将用当前分支中的任何内容覆盖 master
:
git branch -f master HEAD
完成此操作后,您通常可以推送本地 master
分支,此处可能还需要 force 参数:
git push -f origin master
没有合并,没有长命令。只需 branch
和 push
— 但是,是的,这将重写 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
我在博文中找到了我想要的答案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 基本相同。除了“选项”下面他们的解决方案已经嵌入到上面的代码块中。
这种方式更容易找到。
我将此添加为新答案,因为如果以后需要此解决方案,我希望将需要使用的所有代码放在一个代码块中。
否则,我可以复制并粘贴,然后阅读下面的详细信息以查看我应该更改的行 - 在我已经执行之后。
我发现这个简单的方法效果最好。它不会重写历史记录,并且所有以前的分支签入都将附加到主节点。什么都没有丢失,您可以清楚地看到提交日志中发生了什么。
目标:使“分支”的当前状态成为“主”
在分支上工作,提交并推送您的更改,以确保您的本地和远程存储库是最新的:
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 提交日志将显示分支的所有签入。
这里给出的解决方案(重命名'master'中的分支)并不坚持远程(GitHub)repo的后果:
如果您在创建该分支后没有推送任何内容,您可以重命名并推送它而不会出现任何问题。
如果你在 GitHub 上有推送大师,你将需要 'git push -f' 新分支:你不能再以快进模式推送。
-f --force
通常,该命令拒绝更新不是用于覆盖它的本地引用的祖先的远程引用。此标志禁用检查。这可能会导致远程存储库丢失提交;小心使用它。
如果其他人已经提取了您的存储库,他们将无法提取新的主历史记录,除非用新的 GitHub 主分支替换他们自己的主分支(或处理大量合并)。
有 alternatives to a git push --force for public repos。< br> Jefromi's answer(将正确的更改合并回原始主控)就是其中之一。
还可以将另一个分支中的所有文件检出到 master 中:
git checkout master
git checkout better_branch -- .
然后提交所有更改。
要添加到 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>
我的做事方式如下
#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:
右键单击项目节点。
选择团队→然后高级→然后重命名分支
然后展开远程跟踪文件夹。
选择名称错误的分支,然后单击重命名按钮,将其重命名为新名称。
选择新的主人,然后将其重命名为主人。
对我来说,我希望我的 develop
分支在它领先后返回到 master。
在开发过程中:
git checkout master
git pull
git checkout develop
git pull
git reset --hard origin/master
git push -f
以下步骤在由 Atlassian(Bitbucket 服务器)提供支持的 Git 浏览器中执行
将 {current-branch} 设为 master
从 master 中创建一个分支并将其命名为“master-duplicate”。从 {current-branch} 创建一个分支并将其命名为“{current-branch}-copy”。在存储库设置(Bitbucket)中,将“默认分支”更改为指向“master-duplicate”(没有这一步,您将无法删除 master -“在下一步中”)。删除“master”分支——我从源代码树中完成了这一步(你可以从 CLI 或 Git 浏览器中完成)将“{current-branch}”重命名为“master”并推送到存储库(这将创建一个新的“master”分支仍然存在“{current-branch}”)。在存储库设置中,将“默认分支”更改为指向“主”。
我知道这不是 OP 想要的,但是如果您知道将来会遇到与 OP 类似的问题,您可以这样做。
所以这是你的情况,
您需要一个具有新的优秀新突破特性但当前不是 prod 的分支。你有计划在未来制造它。您当前的 prod 分支(master)运行良好但很无聊。您可能会对其进行一些小的更改。如果以后需要,您希望保持当前的 master (prod) 分支安全以备将来使用。
如果这让人感到困惑,请参阅下图的糟糕情况。
*bad situation*
initial master ---> added boring changes ----merge---> you loose boring
\ /
---> (awesome branch) added awesome changes ---
要解决这个问题(即停止无聊的损失),请基本上执行以下操作,
通过执行 git branch bore 来创建当前 master 的副本 用您想要保留的任何名称替换无聊现在,您可以向 master 分支添加新的很棒的功能,并为无聊的分支添加无聊的功能。你仍然可以继续更新无聊的分支,也许用它永远不会将它合并到 master。你不会失去无聊的功能。您的主分支将具有很棒的功能。
所以,
*good situation*
initial master ---> added awesome changes ---> Final master(awesome) branch
\
---> (boring branch) added boring changes ---> Dont merge to master --X-->
code
块中而不是使用屏幕截图图像?使用屏幕截图被认为是不好的做法(它的可搜索性较差,盲人软件无法阅读,无法复制粘贴等)
--X-->
外,看起来相同。哪些词乱了?
so
添加到其中。当你有 -1 时,我是给你 +1 的人,所以我不能再次投票,但感谢你修复它。
只需去 gitlab 或 github 网站查找设置即可。
然后在设置下找到存储库。
找到默认分支,展开它,您可以获得重命名或将其更改为其他分支的选项。
我在 gitlab 中尝试过,它成功了。
我很惊讶这不是这里的答案。这就是我所做的。
在我的文件系统中的不同目录中制作了 2 个 repo 副本,一份与 master 一起,一份与分支。将分支中的所有文件(手动)复制到 master 将更改提交给 master。
这样,包含所有差异的单个提交,提交历史记录被保留,并且不需要强制推送。
--strategy=ours
与--strategy=recursive -Xours
不同。即“我们的”本身可以是一个策略(无论如何结果都将是当前分支),或者作为“递归”策略的选项传递(引入其他分支的更改,并在发生冲突时自动选择当前分支的更改)。git merge --strategy=ours master -m "new master"
才能工作。git push
。您可能会看到类似Your branch is ahead of 'origin/master' by 50 commits.
这是预期的警告。推吧! :D