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

Posted

技术标签:

【中文标题】如何在 Git 中完全用远程分支替换本地分支?【英文标题】:How to replace local branch with remote branch entirely in Git? 【发布时间】:2012-03-01 21:34:42 【问题描述】:

我有两个分支:

    本地分支(我工作的那个) 远程分支(公共的,只有经过良好测试的提交才会到那里)

最近我严重搞砸了我的本地分支。

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

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

【问题讨论】:

我知道接受的答案有 1280 票赞成,但您真的应该考虑将接受的答案更改为 @TTT 的答案。 【参考方案1】:

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

【讨论】:

或者干脆把分支删掉再检查一遍。 是的,我想如果我找不到如何以一种不那么“丑陋”的方式去做的话,我会这样做 丑陋有时很有用。我确实希望人们不会仅仅因为它们不是传统的方式而拒绝投票:必须有一个更合理的理由拒绝投票......而且应该给出。 Git是一个能取得成果的东西。这不是某种神圣的文字。 我不明白反对意见 :-( 是的,它不优雅,等等。但它在某些情况下效果最好......对不起@Hugo @Hugo,同意。我的本地开发分支发生了一些神秘而难闻的事情,团队负责人和工程经理都建议,在更优雅的解决方案中,只需(压缩、复制并保存我的功能工作,然后)核对本地存储库并重新克隆。跨度> 【参考方案2】:

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

【讨论】:

实际上是'git rebase'命令搞砸了整个事情,然后是一些强制合并和硬重置。无论如何,我正在寻找的只是一些简单的方法来拉动整个回购来自远程服务器而不合并。【参考方案3】:
    确保您已签出要替换的分支(来自 Zoltán 的 comment)。

    假设 master 是您要替换的本地分支,而“origin/master”是您要重置到的远程分支:

    git reset --hard origin/master
    

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

【讨论】:

感谢您的建议,我已经对使用 --hard 和 --force 感到非常“害怕”,所以我选择了不使用它们的解决方案。 @KonstantinLevin:啊,是的,这些选项的命名相当烦人。 git reset 默认会重新指向你当前的分支并同步索引。 --soft 将跳过更新索引,--hard 还将同步工作区。我自己的经验是大部分时间都在使用--hard,除非我想撤消最后一次提交(这只是git reset HEAD^ 在获得更多 git 经验后,我确信这是一个更好的解决方案,谢谢。 可能你需要先获取:git fetch origin remote_branch 您应该注意,这会将您当前所在的哪个分支替换为master的内容。所以如果你在例如一个功能分支,它将用master 替换它的所有提交,所以请确保您首先检查了要替换的分支。【参考方案4】:
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>

【讨论】:

--track 部分有什么作用? @GitSync,这就是git help branch--track 的评价。 When creating a new branch, set up branch.&lt;name&gt;.remote and branch.&lt;name&gt;.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. 我在答案中修复了这个命令。感谢您提出这一点。 所以用外行的话来说:它将远程 URL 添加到新分支。所以他们永远保持同步。可以这么说。 你可以说这只是为了方便。如果您执行git status,它将报告您的本地分支是在远程分支之前还是在远程分支之后(如果您关联了它们)。此外,如果您已经将分支设置为跟踪&lt;remote/branch&gt;,则可以使用git pull(或push)而不是完整的git pull &lt;remote&gt; &lt;branch&gt;【参考方案5】:

只需三个步骤即可:

    删除您的本地分支:git branch -d local_branch

    获取最新的远程分支:git fetch origin remote_branch

    基于远程重建本地分支:

    git checkout -b local_branch origin/remote_branch

【讨论】:

其实@araqnid 说的很对,也更简洁。我已经测试过了,你也可以试试。 哇, git checkout -b local_branch origin/remote_branch 太棒了!我总是在两个单独的命令中这样做。谢谢! 如果您的分支未合并,您可能需要在第一步中执行git branch -D local_branch 谢谢,我在使用 gitflow 时遇到了困难,在发布分支然后完成它之后,我想转到已删除的分支,而您的解决方案是唯一有效的解决方案,拉不似乎工作..或者我没有很好地使用它-- 我们应该确保当前分支不是要删除的分支。【参考方案6】:

选择的答案是绝对正确的,但是它并没有给我留下最新的提交/推送...

所以对我来说:

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 

【讨论】:

【参考方案7】:

如果您想更新当前未签出的分支,您可以这样做:

git fetch -f origin rbranch:lbranch

【讨论】:

【参考方案8】:

用远程替换当前本地分支最安全最完整的方法:

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

将当前分支重命名为replaced_master_98d258f。

【讨论】:

可能希望在该工作流程中包含 git stash pop。如果您想重新应用隐藏的文件。 你如何处理隐藏的分支?恐怕它会在我忘记它的用途很久之后的某个地方再次弹出。 @ScottBiggs 如果要删除隐藏的分支,请使用“git stash clear”。【参考方案9】:

用远程分支替换所有内容; 但是,仅来自本地分支所在的同一提交:

git reset --hard origin/some-branch

OR,从远程分支获取最新的并替换所有内容:

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

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

git clean -fd

【讨论】:

git clean 命令为我做了这件事。 git reset hard origin/master 不要清除未跟踪的文件。谢谢!【参考方案10】:

正如所选解释中所提供的,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

【讨论】:

请提供解释,尤其是在回答这么古老的问题时。您的回答按原样没有帮助。 接受的答案已经提出git reset --hard。这增加了一点价值。【参考方案11】:
git reset --hard
git clean -fd

这对我有用 - clean 也显示了它删除的所有文件。如果它告诉您将丢失更改,则需要存储。

【讨论】:

【参考方案12】:

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

1) 硬重置

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

git reset --hard origin/develop

2) 删除当前分支,并从远程仓库再次签出

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

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

3) 中止合并

如果您处于错误合并之间(错误地使用错误的分支完成),并且希望避免合并返回到最新的分支,如下所示:

git merge --abort

4) 中止变基

如果您处于错误的 rebase 之间,您可以中止 rebase 请求,如下所示:

git rebase --abort

【讨论】:

【参考方案13】:

我有点惊讶没有人提到这一点;我几乎每天都使用它:

git reset --hard @u

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

请务必先git fetch 获取远程分支的最新副本。

【讨论】:

看起来真不错,我厌倦了复制粘贴分支名称来重置! 我有几个例子,我为旧问题添加了答案,并且我的答案在排行榜上排名靠前。我希望这个可以。 出色的答案!谢谢 :) 我不知道为什么这不是公认的答案! @AJ。看起来 OP 已经将近 3 年没有访问过 SO,所以我认为我没有机会得到它。 ;) 这看起来像是最现代的方法,git reset --hard origin/master 之前的方法在我的 2.29.2 git 可执行文件中被拒绝,它打印出 # fatal: Cannot do hard reset with paths.【参考方案14】:

git 结帐。

我总是使用此命令将我的本地更改替换为存储库更改。 git checkout 空格点。

【讨论】:

【参考方案15】:
    git fetch origin remote_branch git reset --hard FETCH_HEAD

【讨论】:

您的答案没有添加许多旧答案尚未建议的任何内容。

以上是关于如何在 Git 中完全用远程分支替换本地分支?的主要内容,如果未能解决你的问题,请参考以下文章

git如何强制用远程分支更新本地

git如何把远程分支的代码同步到本地

git如何修改本地分支名和远程分支名?

git如何修改本地分支名和远程分支名?

git如何修改本地分支名和远程分支名?

你如何停止在 Git 中跟踪远程分支?