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

Kar*_*lek 1555 git

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

然后,几十次提交之后,我意识到分支处于比主设备好得多的状态,所以我希望分支"成为"主设备并忽略主设备上的更改.

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

额外:在这种情况下,'old'主服务器已经被push转到另一个存储库,例如GitHub.这怎么改变了?

Cas*_*bel 2004

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

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
Run Code Online (Sandbox Code Playgroud)

如果您希望您的历史记录更清晰一点,我建议您在合并提交消息中添加一些信息,以明确您已完成的工作.将第二行更改为:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message
Run Code Online (Sandbox Code Playgroud)

  • 关于git的合并"策略"的注释:`--strategy = ours`与`--strategy = recursive -Xours`不同.即"我们的"可以是一个策略本身(结果将是当前分支,无论如何),或作为"递归"策略的选项传递(引入其他分支的更改,并在发生冲突时自动更喜欢当前分支的更改). (23认同)
  • 这个答案很有效.我只想添加(对于那些可能是新的或不确定的人),如果你希望你的代码被推送到远程,你必须在此之后做一个`git push`.您可能会看到一个警告,例如"您的分支超过'origin/master'的50次提交.这是预期的.推它吧!:d (7认同)
  • 我不得不把第二行`git merge --strategy =我们的主人-m"新主人"`让它工作. (4认同)
  • 我们可以转到 master 分支并执行“git merge --strategy=theirs better_branch”吗?有这样的事吗? (3认同)
  • 如果出现合并期间的vi编辑器,请键入:w(用于保存):q(用于退出vi) (3认同)
  • @Kelvin:感谢您的澄清......“[这不应该与‘我们的’合并策略混淆](https://git-scm.com/docs/merge-strategies)”但是当然!谁会在他的头脑中将“'我们的'合并策略”与......官方Git文档中“合并策略”部分中名为“我们的”的项目混淆!:-/ (3认同)
  • 这非常有帮助,谢谢。对我来说唯一的问题是我在吸收“如果你想让你的历史更清晰”之前执行解决方案第一部分的第二行。为什么不把第二个建议作为解决方案呢? (2认同)
  • @Johsm这正是我回答的第一句话所说的.如果这样做,新主控器将不会具有与旧主控器相同的历史记录,如果您想要推/拉,则非常糟糕.你需要拥有共享的祖先才能正常工作; 如果相反你做你所说的话,那么当你试图推动它时,除非你强迫它(因为这是坏的并且它试图阻止你),否则它将会失败,如果你强迫它,那么任何随后拉动它的人将尝试合并旧的主人和新的主人,这可能是火车残骸. (2认同)

Bra*_*ard 330

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

git checkout master
Run Code Online (Sandbox Code Playgroud)

用"better_branch"覆盖"master":

git reset --hard better_branch
Run Code Online (Sandbox Code Playgroud)

强制推送到远程存储库:

git push -f origin master
Run Code Online (Sandbox Code Playgroud)

  • 这可能是大多数人都在寻找的答案.BS策略合并的所有其他答案都不会完全取代分支.这使得一切都像我想要的那样,只需覆盖分支并推动它. (68认同)
  • 虽然这确实是许多人正在寻找的,但应该注意的是,repo的任何其他本地副本都需要在下次他们想要拉动时"git reset --hard origin/master",否则git会尝试合并这些更改进入他们(现在)发散的地方.更多在[此答案]中解释了这种危险(http://stackoverflow.com/a/8888015/1483986) (24认同)
  • 另请注意,您需要被允许强制推送到存储库 - 例如在商业环境中这是行不通的 (4认同)
  • 这里的优点也可能是缺点,具体取决于人们的需求。如果您想用另一个分支的历史记录替换 master 的历史记录,这就是您的答案。 (3认同)

Die*_*Epp 70

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

有两种方式,"脏"方式和"干净"方式.假设您的分支已命名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
Run Code Online (Sandbox Code Playgroud)

这将使配置文件更改为与重命名的分支匹配.

你也可以用脏方式来做,这不会更新配置文件.这就是上面介绍的内容......

mv -i .git/refs/new-master .git/refs/master
git checkout master
Run Code Online (Sandbox Code Playgroud)

  • @Dietrick Epp:我不确定是否建议肮脏的方式是个好主意.它会搞乱远程跟踪,reflogs ......无法想到你曾经做过的任何理由. (6认同)
  • 谢谢你。还有一个问题。我正在将其推送到 github。如果我这样做,那里会发生什么? (2认同)
  • @Karel:这会给其他用户造成混乱。他们必须将其母版重置为github母版。如果要避免给他们造成任何麻烦,请查看我的答案。 (2认同)
  • 啊,这是个好点子。不过,你可以同时拥有它:`git branch old-master master; git branch -f master new-master`。新创建备份分支,然后直接将 master 移动到 new-master。(对不起,拼错了你的名字,刚刚注意到) (2认同)
  • @FakeName 我没有断定没有理由这样做,只是没有理由这样做*肮脏的方式*。您可以使用普通命令(如我之前的评论)来完成它并获得相同的结果,除了完整的 reflogs 并且没有机会使事情变得无聊。并且它可以保证工作,因为您不会混淆实现细节。 (2认同)

Ala*_*avi 42

将分支重命名为master:

git branch -M branch_name master
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,git不跟踪分支重命名,所以如果你已经将你的repo推送到远程,而其他人在他们的本地旧主分支上进行了本地更改,那么他们就会遇到麻烦. (11认同)

fre*_*nte 22

据我所知,您可以将当前分支分支到现有分支.从本质上讲,这将覆盖master当前分支中的任何内容:

git branch -f master HEAD
Run Code Online (Sandbox Code Playgroud)

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

git push -f origin master
Run Code Online (Sandbox Code Playgroud)

没有合并,没有长命令.只要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
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 13

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

  • 如果你在制作那个分支后没有推动任何东西,你可以重命名它并毫无问题地推动它.
  • 如果你在GitHub上有push master,你需要'git push -f'新的分支:你不能再推进快进模式了.
    -f
    --force

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

如果其他人已经撤回了你的仓库,他们将无法在没有用新的GitHub主分支替换他们自己的主仓(或处理大量合并)的情况下拉出新的主历史记录.对于公共回购,
有一些git push --force的替代方案.
Jefromi的答案(将正确的变化合并回原来的主人)就是其中之一.


小智 11

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

目标:使"分支"的当前状态成为"主人"

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

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
Run Code Online (Sandbox Code Playgroud)

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


小智 9

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

git checkout master
git checkout better_branch -- .
Run Code Online (Sandbox Code Playgroud)

然后提交所有更改.


She*_*man 9

我在博客文章中找到了想要的答案,用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
Run Code Online (Sandbox Code Playgroud)

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

这种方式更容易找到。

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

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


sta*_*afl 7

要添加到Cascabel 的回答中,如果您不想在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
Run Code Online (Sandbox Code Playgroud)

这样合并提交将只存在于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>
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

693564 次

最近记录:

5 年,10 月 前