将本地存储库分支重置为类似于远程存储库HEAD


3849

如何将本地分支重置为与远程存储库中的分支一样?

我做了:

git reset --hard HEAD

但是,当我运行一个git status

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
      modified:   java/com/mycompany/TestContacts.java
      modified:   java/com/mycompany/TestParser.java

您能告诉我为什么我要进行这些“修改”吗?我没有碰过这些文件吗?如果我这样做了,我想删除那些。


8
根据git status您的第二条命令的输出git reset --hard HEAD失败。但是,您没有粘贴它的输出。→不完整的问题。
罗伯·西默

2
您在这里混合了两个问题:1)如何将本地分支重置到远程位置,以及2)如何清除暂存区域(可能还有工作目录),这样git statusnothing to commit, working directory clean。- 请明确说明!
罗伯特·西默

Answers:


6684

可以通过两个步骤将分支设置为与远程分支完全匹配:

git fetch origin
git reset --hard origin/master

如果要在执行此操作之前保存当前分支的状态(以防万一),可以执行以下操作:

git commit -a -m "Saving my work, just in case"
git branch my-saved-work

现在,您的工作将保存在“ my-saved-work”分支上,以防万一您决定退回(或稍后查看或将其与更新的分支进行比较)。

请注意,第一个示例假定远程仓库的名称为“ origin”,并且远程仓库中名为“ master”的分支与本地仓库中当前已签出的分支匹配。

顺便说一句,您遇到的这种情况看起来很糟糕,就像一个普通情况,即已推送到非裸存储库的当前签出分支中。您最近是否进入了本地仓库?如果没有,那就不用担心-某些其他原因一定会导致这些文件意外地被修改。否则,您应该注意,不建议将其推送到非裸仓库(尤其是不要放入当前已签出的分支)。


4
谢谢您的回答。您说:“请注意,第一个示例假设远程存储库的名称为“ origin”,并且远程存储库中名为“ master”的分支与本地存储库中的分支匹配。” 我如何在执行“ git reset --hard”之前仔细检查远程仓库的名称和分支名称以确保安全?再次感谢。
hap497

21
如果未明确命名遥控器,则其名称可能只是“来源”(默认值)。您可以使用“ git remote”来获取所有远程名称的列表。然后,您可以使用“ git remote <name>”来查看哪个分支彼此推/拉(例如,如果您的“ master”分支是从名为“ origin”的远程数据库中的“ master”克隆而来的,那么您将获得一行)表示“主服务器与远程主服务器合并”)。
Dan Moulding)2009年

6
“不建议将其放入非裸仓库(尤其是不要放入当前已签出的分支机构中)”这是为什么呢?
LeeGee 2013年

27
刚获取后,我相信您也可以做git reset FETCH_HEAD --hard同样的意思。
2013年

6
它没有删除我添加的文件。
Trismegistos

416

我需要做(已接受答案中的解决方案):

git fetch origin
git reset --hard origin/master

其次是:

git clean -f

删除本地文件

要查看将删除哪些文件(实际上并没有删除它们):

git clean -n -f

89
另外,git clean -d -f如果存在未跟踪的目录。
garg 2015年

54
git clean -fdx
Swapnil Kotwal 2015年

14
如果您想要远程分支的精确副本,则必须遵循git clean -ffdx。请注意,thare是两个f。
Trismegistos

6
git clean -f是我需要的必需品。谢谢!
dgo

17
使用clean命令时要小心。它可以从其他分支删除被忽略的文件。
mikoop

306

首先,将其重置为先前获取HEAD的相应上游分支:

git reset --hard @{u}

指定的优点 @{u}或其详细形式@{upstream}是不必显式指定远程仓库和分支的名称。

接下来,根据需要,删除未跟踪的文件,也可以选择使用-x

git clean -df

最后,根据需要获取最新更改:

git pull

53
这似乎比接受的答案更好,因为它动态地重置为当前的上游分支,而不是总是重置为静态分支,例如origin/master
Jon z

@Jonz现场,@{upstream}非常方便,可以用作别名:alias resetthisbranch="git reset --hard @{upstream}"
Siddhartha

1
@GangadharJannu git reset --hard需要提交,否则它不知道将您重置为什么。@{u}指向特定的提交-上次执行时的跟踪分支的头git fetch
克里斯托弗·巴克乔德

1
@KristofferBakkejord感谢您的解释,但即使没有提交哈希,我们也可以做到,git reset --hard尽管它不会重置为远程分支
Gangadhar JANNU

2
对于几乎在这里提出新问题的其他人,如果您从Powershell混帐,请使用引号(git reset --hard "@{u}")。花了我一段时间才能弄清楚。
MPStoering

112

git reset --hard HEAD实际上仅重置为最后的提交状态。在这种情况下,HEAD是指分支的HEAD。

如果您有多次提交,则此操作将无效。

您可能想要做的是重置为原点或任何您称为远程存储库的名称。我可能会做类似的事情

git reset --hard origin/HEAD

不过要小心。硬重置无法轻易撤消。最好按照Dan的建议进行操作,并在重设之前分支出所做更改的副本。


2
我的回答中有一个不正确的建议,那就是Dan早些时候抓到了。我已将其删除,因为我不想让任何人误入歧途。至于起源/母版或起源/ HEAD的东西,我希望这取决于您是否实际先进行获取。如果您只是克隆原点,并且没有其他分支(我发现这很普遍),则应该将其重置。但是,当然,丹是对的。
Mikael Ohlson,2009年

73

以上所有建议均是正确的,但是通常要真正重置项目,甚至还需要删除中的文件.gitignore

从道德上讲,删除项目目录并从远程重新克隆是:

git fetch
git reset --hard
git clean -x -d -f

警告git clean -x -d -f不可逆的,你可能会失去的文件和数据(您使用忽略如东西.gitignore)。


12
警告:“ git clean -x -d -f”是不可逆的,您可能会丢失.gitignore中的文件和数据
Akarsh Satija '16

短一点:git clean -xdf等于git clean -x -d -f
柯里尔

git clean -ffxd删除仓库中没有的所有内容
Trismegistos

44

使用以下命令。这些命令也会从本地git中删除所有未跟踪的文件

git fetch origin
git reset --hard origin/master
git clean -d -f

6
这是一个比较完整的响应,因为没有它,git clean -d -f我们仍然会在本地目录中拥有旧分支的某些功能。谢啦。
Flavio

3
这就是实际上使它像遥控器一样的原因。清洁很重要。
David S.

1
git clean -ffxd真正删除所有内容
Trismegistos

1
这正是我所需要的。谢谢
AllJs

38

这个问题在这里混合了两个问题:

  1. 如何将本地分支重置到远程位置
  2. 如何清除暂存区(以及可能的工作目录),这样git statusnothing to commit, working directory clean.

一站式答案是:

  1. git fetch --prune (可选)更新远程存储库的本地快照。其他命令仅在本地。
    git reset --hard @{upstream}将本地分支指针放在远程快照的位置,并将索引和工作目录设置为该提交的文件。
  2. git clean -d --force 删除妨碍git说“工作目录干净”的未跟踪文件和目录。

1
@{upstream}语法要求设置上游,如果您默认设置,则会发生上游git checkout <branchname>。–否则将其替换为origin/<branchname>
罗伯·席默

添加-xgit clean删除不在提交中的所有内容(即,甚至使用.gitignore机制忽略的文件)。
罗伯特·西默

22

这是我经常要面对的事情,并且我已经概括了上面提供的与任何分支一起使用的Wolfgang脚本

我还添加了“您确定”提示,以及一些反馈输出

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
read -p "Reset branch $branchname to origin (y/n)? "
[ "$REPLY" != "y" ] || 
echo "about to auto-commit any changes"
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  echo "Creating backup auto-save branch: auto-save-$branchname-at-$timestamp"
  git branch "auto-save-$branchname-at-$timestamp" 
fi
echo "now resetting to origin/$branchname"
git fetch origin
git reset --hard origin/$branchname

3
您可能要使用“ git remote”来获取远程名称。在某些情况下,它不是“起源”
Yurik 2014年

17

前提是远程存储库为origin,并且您对以下内容感兴趣branch_name

git fetch origin
git reset --hard origin/<branch_name>

另外,你去重置当前分支originHEAD

git fetch origin
git reset --hard origin/HEAD

怎么运行的:

git fetch origin 从远程下载最新版本,而无需尝试合并或重新设置任何内容。

然后,git reset<branch_name>分支重置为您刚获取的分支。该--hard选项将更改工作树中的所有文件以匹配中的文件origin/branch_name


14

我做了:

git branch -D master
git checkout master

完全重置分支


请注意,您应该签出到另一个分支才能删除所需的分支


5
您应该再次阅读问题,没有影响远程的内容,而是将其设置为与remote相同,因此您不应该对remote做任何事情,这对我来说是有帮助的,对我来说不是。
user2846569

如果要将其设置为与远程相同,则至少应在某个时候进行获取,您是否同意?
蒂姆(Tim)

2
您至少应该尝试一下或阅读以下文档:kernel.org/pub/software/scm/git/docs/git-checkout.html
user2846569 2014年

要走的路,我的分支中的.pck文件损坏,其余选项无效,谢谢!
LuckyBrain

14

这是一个脚本,可自动执行最流行的答案所建议的内容...有关支持分支的改进版本,请参见https://stackoverflow.com/a/13308579/1497139

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see /programming/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  git branch "auto-save-at-$timestamp" 
fi
git fetch origin
git reset --hard origin/master

10

如果您遇到我的问题,那么您已经进行了一些更改,但是现在,出于任何原因想要摆脱它,最快的方法就是这样使用git reset

git reset --hard HEAD~2

我有2个不需要的提交,因此为2。您可以将其更改为自己的提交数量以进行重置。

因此,回答您的问题-如果您比远程存储库HEAD提前5次提交,则应运行以下命令:

git reset --hard HEAD~5

请注意,您将丢失所做的更改,因此请小心!


7

先前的答案假定要重置的分支是当前分支(已签出)。在评论中,OP hap497阐明确实已检出该分支,但这不是原始问题明确要求的。由于存在至少一个“重复”问题,因此将分支完全重置为存储库状态,而不假定分支已签出,这里是一种替代方法:

如果当前检出分支“ mybranch” ,要将其重置为远程分支“ myremote / mybranch”的头,可以使用以下底层命令:

git update-ref refs/heads/mybranch myremote/mybranch

此方法使检出的分支保持原样,而工作树保持不变。它只是将mybranch的头移到另一个提交,无论第二个参数是什么。如果需要将多个分支更新到新的远程磁头,这将特别有用。

但是,在执行此操作时请小心,并使用gitk或类似工具仔细检查源和目标。如果您不小心在当前分支上执行此操作(而git不会阻止您这样做),则可能会感到困惑,因为新分支的内容与未更改的工作树不匹配(要修复,请再次更新分支,到之前的位置)。


7

这是我经常使用的:

git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;

请注意,这是很好的做法不更改您的本地主/开发分支,而是结帐另一个分支的任何变化,与变化的类型,例如前置分行的名称feat/chore/fix/等于是你只需要拉更改,而不是从主那里推送任何更改。对于其他人贡献的其他分支机构也是如此。因此,仅当您碰巧将更改提交给其他人已提交并需要重置的分支时,才应使用以上内容。否则,将来避免推到其他人推到的分支,而是签出并通过签出的分支推到所述分支。

如果您想将本地分支重置为上游分支中的最新提交,到目前为止对我有用的是:

检查您的远程服务器,确保上游和原始服务器是您期望的,如果没有按预期使用git remote add upstream <insert URL>,请使用,例如您从中派生的原始GitHub存储库,和/或git remote add origin <insert URL of the forked GitHub repo>

git remote --verbose

git checkout develop;
git commit -m "Saving work.";
git branch saved-work;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force

在GitHub上,您也可以签出与本地名称相同的分支,以将其保存在此处,尽管如果Origin开发与本地保存的工作分支具有相同的更改,则不必这样做。我以develop分支为例,但它可以是任何现有的分支名称。

git add .
git commit -m "Reset to upstream/develop"
git push --force origin develop

然后,如果需要在发生任何冲突时将这些更改与另一个分支合并,将更改保留在开发中,请使用:

git merge -s recursive -X theirs develop

使用时

git merge -s recursive -X ours develop

保留branch_name冲突的更改。否则,将mergetool与git mergetool

与所有更改一起:

git commit -m "Saving work.";
git branch saved-work;
git checkout develop;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;
git add .;
git commit -m "Reset to upstream/develop";
git push --force origin develop;
git checkout branch_name;
git merge develop;

请注意,您可以使用提交哈希,其他分支名称等代替上游/开发。使用CLI工具(例如Oh My Zsh)检查您的分支是否为绿色,指示没有要提交的内容,并且工作目录是干净的(由确认或验证git status)。请注意,这反而可能会增加相比,上游开发,如果有自动添加一个承诺,比如UML图,许可证头,等什么提交,所以在这种情况下,你可以再拉的变化origin developupstream develop,如果需要的话。


6

答案

git clean -d -f

被低估了(-d删除目录)。谢谢!


对于不带多余文件的完整,100%干净的repo文件夹,请运行git clean -xdf。这将删除git无法识别的所有文件,并使您的文件夹与git对象列表中的文件完全匹配。请注意,您可以添加-n(例如git clean -nxdf)执行“假设分析”,它会告诉您将删除的内容而无需实际执行任何操作。(git clean
qJake

5

如果您想回到HEAD工作目录和索引的状态,则应该git reset --hard HEAD而不是HEAD^。(这可能是拼写错误,就像--hard。)

至于关于这些文件为何以修改后的状态显示的特定问题,似乎您进行了软重置而不是硬重置。这将导致在HEAD提交中更改的文件看起来像是已暂存的,这很可能是您在此处看到的。


4

本地git repo中未跟踪和修改的文件似乎没有任何数量的重置和清除操作(我尝试了上述所有选项)。我唯一的解决方案是管理本地存储库,然后从远程重新克隆它。

幸运的是,我没有其他关心的分支机构。

xkcd:Git


1

在我见过的所有情况下,唯一可行的解​​决方案是删除并重新克隆。也许还有另一种方法,但是显然,这种方法不会留下旧状态留在那的机会,所以我更喜欢它。如果您经常将git弄乱,可以将Bash单行设置为宏:

REPO_PATH=$(pwd) && GIT_URL=$(git config --get remote.origin.url) && cd .. && rm -rf $REPO_PATH && git clone --recursive $GIT_URL $REPO_PATH && cd $REPO_PATH

*假设您的.git文件未损坏


4
您也可以根据需要重新安装操作系统!
塞巴斯蒂安·斯科尔

1

您是否忘记了创建功能分支并误将其直接提交给master?

您现在可以创建功能分支并重新设置master而不影响工作(本地文件系统),以避免触发构建,测试和文件锁定问题:

git checkout -b feature-branch
git branch -f master origin/master

1

只有3个命令才能使它工作

git fetch origin
git reset --hard origin/HEAD
git clean -f

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.