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


1657

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

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

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

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


2
检查非常相似的问题的答案stackoverflow.com/q/2862590/151641
mloskot 2012年

4
遇到了同样的问题,但是我只是删除了master,然后将另一个分支重命名为master:stackoverflow.com/a/14518201/189673
jayarjo 2013年

10
@jayarjo,如果可能的话,应该避免这种情况,因为它会重写历史记录,并在其他人下次尝试拉主机时给其他人造成问题。
joelittlejohn 2013年

3
这就是为什么我喜欢@Jefromi的答案。档案的历史没有被解构。
froggythefrog 2015年

Answers:


2134

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

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

25
有关git的合并“策略”的注意事项:--strategy=ours与有所不同--strategy=recursive -Xours。即“我们的”本身可以是一种策略(无论如何结果都将是当前分支),也可以作为选项传递给“递归”策略(引入其他分支的更改,并在出现冲突时自动选择当前分支的更改) )。
开尔文2014年

5
我必须进行第二行git merge --strategy=ours master -m "new master"处理才能正常工作。
白炽灯2015年

5
@Johsm这就是我的答案的第一句话。如果这样做,新的母版将不会与旧的母版具有相同的历史记录,如果要推/拉,这将是非常不好的。您需要具有共同的血统,才能使其正常工作。相反,如果您按照您的意思去做,那么当您尝试推动它时,除非您强迫它,否则它只会失败(因为这很糟糕,并且它正试图阻止您),如果您强迫了它,那么随后任何人都会拉它将尝试合并新旧母版,这很可能会造成火车事故。
卡斯卡贝尔

4
如果出现合并期间的vi编辑器,请输入:w(用于保存):q(用于从vi退出)
Tomas Kubes

9
这个答案很棒。我只是想补充一下(对于新手或不确定者),git push如果您想将代码推送到远程,则必须在此之后立即进行操作。您可能会看到类似“ Your branch is ahead of 'origin/master' by 50 commits.这是预期的” 的警告。只是推!:D
chapeljuice

387

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

git checkout master

用“ better_branch”覆盖“ master”:

git reset --hard better_branch

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

git push -f origin master

81
这可能是大多数人想要的答案。BS策略合并的所有其他答案不会完全替换分支。这使一切如我所愿,只需覆盖分支并将其向上推即可。
古巴特龙(Gubatron)

31
尽管这确实是许多人所希望的,但是应该注意,git reset --hard origin/master下一次要提取存储库的其他任何本地副本都需要,否则git会尝试将更改合并到其(现在)不同的本地中。在此答案
中将

3
另请注意,需要允许您强制推送到存储库-例如,在无法正常工作的商业环境中
-inetphantom

根据人们的需求,这里的上涨也可能是不利的一面。如果您想用另一个分支的历史替换master的历史,这就是您的答案。
B15

75

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

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

2
谢谢。还有一个问题。我将其推到github。如果我这样做,那将会发生什么?
卡雷尔·比列克(KarelBílek),2010年

3
@Karel:这会给其他用户造成混乱。他们必须将其母版重置为github母版。如果要避免给他们造成任何麻烦,请查看我的答案。
卡斯卡贝尔

6
@Dietrick Epp:我不确定建议采用肮脏的方式是否是个好主意。它会搞乱远程跟踪,更新记录……无法想到您会这样做的任何原因。
卡斯卡贝尔

2
嗯,这是一个好点。不过,您可以同时使用两种方法git branch old-master master; git branch -f master new-master。重新创建备份分支,然后直接将master转移到new-master。(非常抱歉,您拼错了您的名字,只是注意到了这一点)
卡斯卡贝尔

2
@FakeName我没有得出结论,没有理由这样做,只是没有理由以肮脏的方式这样做。您可以使用普通命令执行此操作(如我之前的评论中所示),并获得相同的结果,但reflog完好无损,不会造成麻烦。而且它可以保证工作,因为您无需考虑实施细节。
卡斯卡贝尔2013年

46

将分支重命名为master

git branch -M branch_name master

11
不幸的是,git无法跟踪分支的重命名,因此,如果您已经将存储库推送到远程站点,并且其他人在其本地旧的master分支上进行了本地更改,则它们会遇到麻烦。
thSoft 2015年

和之间有区别git checkout master&&git reset --hard better_branch吗?
wotanii

26

据我了解,您可以将当前分支分支到现有分支。本质上,这将覆盖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

15

我在博客文章中找到了想要的答案,用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的答案相同。他解决方案下方添加的“选项” 已经嵌入到我的主代码块中。

这种方式更容易找到。

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

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


14

此处给出的解决方案(在“ master”中重命名分支)并不坚持远程(GitHub)仓库的后果:

  • 如果自创建该分支以来没有进行任何操作,则可以对其进行重命名并进行毫无问题的推送。
  • 如果您在GitHub上具有push master,则需要'git push -f'新分支:您将无法再以快进模式进行推送
    -F
    - 力

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

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


14

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

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

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

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

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


10

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

git checkout master
git checkout better_branch -- .

然后提交所有更改。


5

为了增加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>

3

对我来说,我希望我的开发者在领先之后能回到大师那里。

在开发过程中:

git checkout master
git pull

git checkout develop
git pull

git reset --hard origin/master
git push -f

2

我的做事方式如下

#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

2

如果您在Eclipse中使用eGit

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

我这样做了,但不确定是否可行。在github上,除了git扩展,什么都没有改变,我可以看到分支被重命名了。
普拉莫德

0

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

使{current-branch}为 master

  1. 创建一个分支master并将其命名为“ master-duplicate”。
  2. 从{current-branch}中创建一个分支,并将其命名为“ {current-branch} -copy”。
  3. 在存储库设置(Bitbucket)中,将“默认分支”更改为指向“母版重复”(没有此步骤,您将无法删除母版-“在下一步”)。
  4. 删除“ master”分支-我从源代码树中执行了此步骤(您可以在CLI或Git浏览器中完成此操作)
  5. 将“ {current-branch}”重命名为“ master”并推送到存储库(这将创建一个新的“ master”分支,仍然存在“ {current-branch}”)。
  6. 在存储库设置中,将“默认分支”更改为指向“主”。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.