如何在Git中完全用远程分支替换本地分支?


776

我有两个分支:

  1. 本地分支机构(与我合作的分支机构)
  2. 远程分支(公共,只有经过良好测试的提交才可以进入)

最近,我严重搞砸了当地分支机构。

如何将本地分支完全替换为远程分支,以便可以从现在的远程分支继续工作?

我已经搜索过SO,并且在本地签出到远程分支没有任何效果。


1
我知道接受的答案有1280票,但您应该真正考虑通过@TTT将接受的答案更改为该答案。
杰米

Answers:


1285
  1. 确保您已签出要替换的分支(根据Zoltán的评论)。
  2. 假设master是您要替换的本地分支,而“ origin / master”是您要重置为的远程分支:

    git reset --hard origin/master
    

--hard会将您的本地HEAD分支更新为与origin / master相同的修订版,并将此更改也同步到索引和工作空间中。


4
感谢您的建议,我已经非常害怕使用--hard和--force,因此我只选择了不使用这些解决方案的解决方案。
YemSalat

13
@KonstantinLevin:啊,是的,这些选项的命名很令人讨厌。git reset默认情况下将重新指向您当前的分支并同步索引。--soft将跳过更新索引,--hard也将同步工作空间。我自己的经验是--hard大部分时间都在使用,除非我想撤消上一次提交(只是git reset HEAD^
araqnid12年

9
在拥有git的更多经验之后,我坚信这是一个更好的解决方案,谢谢。
YemSalat 2013年

24
可能您需要先获取:git fetch origin remote_branch
b1r3k 2014年

53
您应该注意,这将用master内容替换您当前所在的任何分支。因此,如果您使用的是功能分支,它将用替换所有提交,因此请确保已签出要替换的分支。master
佐尔坦

218

这很简单,只需三个步骤:

  1. 删除本地分支: git branch -d local_branch
  2. 获取最新的远程分支: git fetch origin remote_branch
  3. 根据远程分支重建本地分支: git checkout -b local_branch origin/remote_branch

7
实际上,@ araqnid所说的是正确的,也更加简洁。我已经测试过了,您也可以尝试。
adamsmith

哇,git checkout -b local_branch origin / remote_branch非常好!我总是在两个单独的命令中执行此操作。谢谢!
kendepelchin

11
git branch -D local_branch如果您的分支未合并,则可能需要执行第一步。
szeryf

谢谢,我在使用gitflow时遇到了困难,在发布了一个分支然后完成它之后,我想转到已删除的分支,而您的解决方案是唯一可行的解​​决方案,pull似乎不起作用。 -有没有利用好
德切巴尔

2
我们应确保当前分支不是要删除的分支。
a_secenthusiast

43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>

--track部分有什么作用?
eonist

3
@GitSync,这是git help branch关于的内容--trackWhen creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. 我在答案中修复了此命令。感谢您提出这一点。
Sailesh

因此,以通俗易懂的方式来说:它将远程URL添加到新分支中。因此,它们永远保持同步。可以这么说。
eonist

2
您可以说这只是为了方便。如果这样做git status,它将在关联本地分支时报告本地分支位于远程分支之前还是之后。此外,如果您已经将分支设置为track ,则可以git pull(或push)代替全部。git pull <remote> <branch><remote/branch>
Sailesh

22

用远程分支替换所有内容; 但是,只有在同一提交中,本地分支才会打开:

git reset --hard origin/some-branch

或者,获取最新从远程分支机构信息并替换所有内容:

git fetch origin some-branch
git reset --hard FETCH_HEAD

顺便说一句,如果需要,您可以清除尚未提交的未跟踪文件和目录:

git clean -fd

git clean命令为我做。git reset hard origin/master不要清除未跟踪的文件。谢谢!
莫诺(Mornor)

9

用遥控器替换当前本地分支的最安全,最完整的方法:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

stash行将保存您尚未提交的更改。该branch行将您的分支移动到其他名称,以释放原始名称。的fetch行检索遥控器的最新副本。该checkout行将原始分支重新创建为跟踪分支。

或作为bash函数:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

这会将当前分支重命名为replace_master_98d258f之类的名称。


可能要包括git stash pop在该工作流程中。如果要重新应用保存的文件。
eonist

您对藏匿的分支做什么?恐怕在我忘记它的用途之后很久以后,它还会在某个地方弹出。
Scott Biggs

1
@ScottBiggs如果要删除隐藏的分支,请使用“ git stash clear”。
Mark A. Durham

4

我很惊讶没有人提到这件事;我几乎每天都在使用它:

git reset --hard @{u}

基本上,@{u}这只是您当前分支正在跟踪的上游分支的简写。例如,这通常等于origin/[my-current-branch-name]。很好,因为它与分支无关。

确保git fetch首先获取远程分支的最新副本。


1
看起来真的很好,我已经厌倦了复制和粘贴分支的名称来重设!
pedroct92

1
我曾在一些实例中为旧问题添加答案,而我的答案在排行榜中一直沿用。我希望这能做到。
杰米

3

它可以通过多种方式完成,并继续编辑此答案以传播更好的知识视角。

1)硬重置

如果您是在远程开发分支上工作,则可以将HEAD重置为远程分支上的最后一次提交,如下所示:

git reset --hard origin/develop

2)删除当前分支,然后再次从远程存储库中签出

考虑到您正在本地仓库中的develop分支上,该分支与远程/ develop分支同步,您可以执行以下操作:

git branch -D develop
git checkout -b develop origin/develop

3)中止合并

如果您处于错误的合并之间(错误地用了错误的分支),并且想要避免合并,请如下所示最新返回分支:

git merge --abort

4)中止基础

如果您处于错误的重定基准之间,则可以按如下所示中止重定基准请求:

git rebase --abort

2

您可以按照@Laurent的@Hugo所说的那样做,或者git rebase,如果您知道要删除的提交,可以使用它来删除要摆脱的提交。我倾向于使用git rebase -i head~N(其中N是一个数字,允许您操纵最后的N次提交)进行此类操作。


实际上,是'git rebase'命令使整个事情搞砸了,然后进行了一些强制合并和硬重置。.无论如何,我一直在寻找的是从远程服务器提取整个仓库而不合并的一种简单方法。
YemSalat

2

选择的答案是绝对正确的,但它并没有离开我了最新提交/推...

所以对我来说:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

由于我知道我想将上游分支临时设置为特定分支几个星期(与我之前切换到/签出并对其进行硬重置的分支相同)

所以重置后

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 

1

如果要更新当前未签出的分支,可以执行以下操作:

git fetch -f origin rbranch:lbranch

0

如所选说明中提供的那样,git reset是好的。但是如今,我们经常使用子模块:存储库内部的存储库。例如,如果您在项目中使用ZF3和jQuery,则很可能希望从其原始存储库中克隆它们。在这种情况下,git reset是不够的。我们需要将子模块更新为存储库中定义的确切版本:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

它与您递归地进入每个子模块的工作目录(cd)并将运行:

git submodule update

这与

git checkout master
git pull

因为子模块不是指向分支而是指向提交。

在这种情况下,当您手动签出1个或多个子模块的某个分支时,可以运行

git submodule foreach git pull

请提供解释,尤其是在回答这么古老的问题时。您的回答没有任何帮助。
Erik A

公认的答案已经提出git reset --hard。这几乎没有价值。
florisla


-6

丑陋但简单的方法:删除本地文件夹,然后再次克隆远程存储库。


10
或者只是删除分支,然后再次签出。
劳伦特

是的,我猜这就是我要怎么做才能找到一种不太“丑陋”的方式
YemSalat 2012年

2
丑陋有时很有用。我确实希望人们不要仅仅因为他们不是常规方式就投票反对:必须有一个更合理的理由才可以投票……并且应该给出理由。Git是可以实现结果的东西。这不是某种神圣的文本。
麦克啮齿动物

3
我不明白downvotes :-(是的,这是不好的,等等,但它可以工作最好在某些情况下...对不起@Hugo
silverdr

@雨果,同意。我的本地开发分支发生了一些奇怪而又臭的事情,团队负责人和工程经理都建议,在更优雅的解决方案中,只是(压缩,复制和保存我的要素作品)对本地存储库和副本进行核对。
AmitaiB
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.