将本地存储库分支重置为就像远程存储库 HEAD

git undo

如何将我的本地分支重置为就像远程存储库上的分支一样?

我做了:

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

根据 git status 的输出,您的第二个命令 git reset --hard HEAD 失败。不过,您没有粘贴它的输出。 → 不完整的问题。

您在这里混合了两个问题:1)如何将本地分支重置到远程所在的位置,以及 2)如何清除暂存区域(可能还有工作目录),以便 git status 表示 nothing to commit, working directory clean。 - 请明确说明!

这回答了你的问题了吗? How do I force "git pull" to overwrite local files?

如果 repo 很大,显然不是答案,但是对于小的 repo,你可以用锤子敲它并完全避免 git:rm -fr ./repo; git clone repo。我找到的最好方法

你救了我的命....爱你...我去另一个空荡荡的分行结账...没有结账发生...此时我的 1 周工作已经结束...而且我无法达到截止日期.感谢上帝!

H
Herohtar

将您的分支设置为与远程分支完全匹配可以分两步完成:

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”的分支与本地仓库中当前签出的分支匹配。

顺便说一句,你所处的这种情况看起来很像一个常见的情况,即推送到非裸存储库的当前签出分支中。您最近是否推入了本地仓库?如果没有,那么不用担心——一定是其他原因导致这些文件意外地最终被修改。否则,您应该知道不建议推送到非裸存储库(特别是不要推送到当前签出的分支)。

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

如果您没有明确命名遥控器,那么它的名称可能只是“原点”(默认值)。您可以使用“git remote”来获取所有远程名称的列表。然后,您可以使用“git remote ”查看哪些分支相互推/拉(例如,如果您的“master”分支是从名为“origin”的远程“master”克隆的,那么您将得到一行上面写着“主与远程主合并”)。

“不建议推入非裸存储库(特别是不要推入当前签出的分支)”为什么?

就在获取之后,我相信你也可以做git reset FETCH_HEAD --hard,同样的意思。

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

A
Akavall

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

git fetch origin
git reset --hard origin/master

其次是:

git clean -f

to remove local files

要查看将删除哪些文件(而不实际删除它们):

git clean -n -f

此外,如果存在未跟踪的目录,则为 git clean -d -f

还有git clean -fdx

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

git clean -f 是我需要的重要部件。谢谢!

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

A
Asclepius

首先,使用 git reset 重置为相应上游分支的先前获取的 HEAD

git reset --hard @{u}

指定 @{u} 或其详细形式 @{upstream} 的优点是不必显式指定远程 repo 和分支的名称。在 Windows 或 PowerShell 中,指定 "@{u}"(带双引号)。

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

git clean -df

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

git pull

这似乎比接受的答案更好,因为它会动态重置到当前的上游分支,而不是总是像 origin/master 这样的静态分支

@GangadharJannu git reset --hard 需要提交,否则它不知道将您重置为什么。 @{u} 指向一个特定的提交 - 跟踪分支的头部,从您上次执行 git fetch 开始。

@KristofferBakkejord 感谢您的解释,但即使没有提交哈希,我们也可以执行 git reset --hard 虽然它不会重置为远程分支

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

使用引号的@MPStoering 在 Windows 上的 git bash 中也适用于我。干杯

M
Mikael Ohlson

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

如果您有多个提交,这将不起作用..

您可能想要做的是重置为源头或远程存储库被调用的任何内容。我可能会做类似的事情

git reset --hard origin/HEAD

不过要小心。硬重置不能轻易撤消。最好按照 Dan 的建议去做,并在重置之前将更改的副本分支出来。

我的回答中有一个不正确的建议,丹早些时候发现了。我把它删掉了,因为我不想让任何人误入歧途。至于 origin/master 或 origin/HEAD 的东西,我希望这取决于你是否真的先进行 fetch。如果您只是克隆了 origin,并且它没有其他分支,我发现这很常见,那么它应该重置它。但当然,丹是对的。

C
Charlie Collins

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

要获得擦除项目目录并从远程重新克隆的道德等价物是:

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

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

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

稍短一点:git clean -xdf 等于 git clean -x -d -f

git clean -ffxd 删除所有不在 repo 中的东西

C
Charlie Wallace

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

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

这是一个更完整的响应,因为如果没有 git clean -d -f,我们仍然会在本地目录中保留旧分支的一些内容。谢啦。

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

R
Robert Siemer

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

如何将本地分支重置到远程是如何清除暂存区域(可能还有工作目录)的位置,以便 git status 表示没有任何提交,工作目录干净。

一站式答案是:

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

@{upstream} 语法需要设置上游,如果您使用 git checkout <branchname>,则默认情况下会发生这种情况。 – 否则将其替换为 origin/<branchname>

-x 添加到 git clean 以删除不在提交中的所有内容(即,即使是使用 .gitignore 机制忽略的文件)。

e
eigenharsha

假设远程存储库是 origin,并且您对 branch_name 感兴趣:

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

此外,您还可以将 origin 的当前分支重置为 HEAD

git fetch origin
git reset --hard origin/HEAD

这个怎么运作:

git fetch origin 从远程下载最新版本,而不尝试合并或变基任何内容。

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

我不确定我是否在此处关注 origin/HEAD,我认为这不正确

W
Wolfgang Fahl

这是我经常遇到的问题,我已经概括了 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

您可能想使用“git remote”来获取遥控器的名称。在某些情况下,它不会是“起源”

您脚本中的逻辑不正确。 [ "$REPLY" != "y" ] || 将仅跳过下一行 echo "about to auto-commit any changes" 并继续运行脚本的其余部分。该行的内容应类似于 [[ "$REPLY" != "y" ]] && { echo "Exiting branch reset"; exit; }

u
user2846569

我做了:

git branch -D master
git checkout master

完全重置分支

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

您应该再次阅读问题,没有任何影响远程,但设置为与远程相同,因此您不应该对远程执行任何操作,这对我的情况有所帮助,而不是以上。

如果您想将其设置为与远程相同,您至少应该在某个时候进行提取,您不同意吗?

你至少应该试试这个或阅读文档:kernel.org/pub/software/scm/git/docs/git-checkout.html

走的路,我在分支中有一个损坏的 .pck 文件,其余选项不起作用,谢谢!!

C
Community

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

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see https://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"`
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
A
Anael

答案

git clean -d -f

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

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

C
Community

以前的答案假定要重置的分支是当前分支(已签出)。在评论中,OP hap497 澄清了该分支确实已签出,但这不是原始问题明确要求的。由于至少有一个“重复”问题 Reset branch completely to repository state,它不假定分支已签出,因此这里有一个替代方案:

如果分支“mybranch”当前检出,要将其重置为远程分支“myremote/mybranch”的头部,您可以使用此 low-level 命令:

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

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

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

A
Asclepius

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

git reset --hard HEAD~2

我有 2 次不需要的提交,因此编号为 2。您可以将其更改为您自己的提交次数以重置。

所以回答你的问题 - 如果你在远程存储库 HEAD 之前提交了 5 次提交,你应该运行这个命令:

git reset --hard HEAD~5

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

J
James Ray

这是我经常使用的:

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

请注意,最好不要对本地 master/develop 分支进行更改,而是将任何更改签出到另一个分支,分支名称前有更改类型,例如 feat/chore/、{3 } 等。因此您只需要拉取更改,而不需要从 master 推送任何更改。其他人贡献的其他分支也是如此。因此,仅当您碰巧将更改提交到其他人已提交的分支并需要重置时,才应使用上述内容。否则,将来避免推送到其他人推送到的分支,而是通过签出的分支签出并推送到所述分支。

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

检查您的遥控器,确保您的上游和来源符合您的预期,如果不符合预期,请使用 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 上,您还可以签出与本地分支同名的分支,以便将工作保存在那里,尽管如果原始开发与本地保存的工作分支具有相同的更改,则不需要这样做。我以开发分支为例,但它可以是任何现有的分支名称。

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 的冲突更改。否则,使用带有 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;

请注意,您可以使用提交哈希、其他分支名称等代替上游/开发。使用诸如 Oh My Zsh 之类的 CLI 工具检查您的分支是否为绿色,表示没有要提交的内容并且工作目录是干净的( git status 确认或验证)。请注意,与上游开发相比,如果提交自动添加了任何内容,例如 UML 图、许可证头等,这实际上可能会添加提交,因此在这种情况下,您可以将 origin develop 上的更改拉到 upstream develop , 如果需要的话。

D
Deep Nirmal

只有 3 个命令可以使它工作

git fetch origin
git reset --hard origin/HEAD
git clean -f
E
Emil Sit

如果您希望工作目录和索引都返回到 HEAD 状态,那么您应该返回 git reset --hard HEAD,而不是 HEAD^。 (这可能是一个错字,就像 --hard 的单破折号和双破折号一样。)

至于您关于为什么这些文件显示为已修改状态的具体问题,看起来您可能进行了软重置而不是硬重置。这将导致在 HEAD 提交中更改的文件看起来好像它们是暂存的,这很可能是您在此处看到的。

M
Martin

多少重置和清理似乎对我本地 git repo 中未跟踪和修改的文件有任何影响(我尝试了上面的所有选项)。我对此的唯一解决方案是 rm 本地 repo 并从远程重新克隆它。

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

xkcd: Git

s
sudo

在我见过的所有情况下,唯一可行的解决方案是删除和重新克隆。也许还有另一种方式,但显然这种方式不会留下旧状态的机会,所以我更喜欢它。如果您经常在 git 中搞砸事情,您可以将 Bash one-liner 设置为宏:

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 文件没有损坏

如果您想确定,您也可以重新安装操作系统!

G
Grastveit

您是否忘记创建功能分支并错误地直接在 master 上提交?

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

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

您可以获取原点并重置以解决问题

 git fetch origin
 git reset --hard origin/master

您可以在重置之前保存更改,如下所示,

git stash

重置后,如果你想恢复,你可以简单地运行,

git stash apply
v
vinzee

抛出错误,因为它有未提交的更改。

所以,你可以使用 git stash

这将保存未提交的更改以供以后使用,然后从您的工作副本中恢复它们。

如果您希望再次进行这些更改,可以使用 git stash apply

然后你可以使用 git pull

这会从远程仓库获取最近的代码。

如果您有冲突的未推送提交,则不起作用(错误:“致命:拒绝合并不相关的历史”)

S
Snowcrash

此处评分最高的答案没有按预期重置我的本地代码。

如今,master 通常是主要的,它不会对您可能躺在周围的未跟踪文件做任何事情

反而:

检查您的默认远程分支的名称(这不是 git 的东西,所以请在 GitHub 中检查)然后在下面的步骤 4 中替换 main 或 master 保存当前的东西 git stash -u update from remote git fetch origin reset to remote default branch (但请参阅上面的步骤 1) git reset --hard origin/main

M
Micah Walter

如果您不介意保存本地更改,但仍想更新存储库以匹配 origin/HEAD,您可以简单地存储本地更改,然后拉取:

git stash
git pull