关于git:将本地存储库分支重置为与远程存储库头相同

Reset local repository branch to be just like remote repository HEAD

如何将本地分支重置为与远程存储库上的分支相同?

我做到了:

1
git reset --hard HEAD

但是当我运行一个git status时,

1
2
3
4
5
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

你能告诉我为什么要修改这些吗?我没碰过这些文件?如果我做了,我想去掉那些。


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

1
2
git fetch origin
git reset --hard origin/master

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

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

现在,您的工作将保存在分支"我保存的工作"上,以防您决定要它返回(或希望稍后查看它或将其与更新的分支进行比较)。

请注意,第一个示例假定远程回购的名称是"origin",并且远程回购中名为"master"的分支与本地回购中当前签出的分支匹配。

顺便说一句,您所处的这种情况看起来非常类似于一个常见的情况,在这种情况下,已经对非裸机存储库的当前签出分支进行了推送。你最近是否参与了本地回购?如果没有,那么就不用担心——一定是其他原因导致这些文件意外地被修改了。否则,您应该知道,不建议将其推入非裸机存储库(尤其是当前已签出的分支)。


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

1
2
git fetch origin
git reset --hard origin/master

然后:

1
git clean -f

删除本地文件

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

1
git clean -n -f


首先,重置到相应上游分支的先前获取的HEAD

1
git reset --hard @{u}

指定@{u}或其冗长形式@{upstream}的好处是不必明确指定远程回购和分支的名称。

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

1
git clean -df

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

1
git pull


git reset --hard HEAD实际上只重置到最后一个提交状态。在这种情况下,head指的是分支机构的头。

如果你有几个承诺,这就行不通了。

您可能想要做的,是重置到原始库的头上,或者是远程存储库的调用。我可能会做一些像

1
git reset --hard origin/HEAD

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


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

要获得从远程删除项目目录和重新克隆的道德等价物,请执行以下操作:

1
2
3
git fetch
git reset --hard
git clean -x -d -f

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


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

  • 如何将本地分支重置为远程
  • 如何清理你的集结地(可能还有工作目录),使git statusnothing to commit, working directory clean.
  • 一站式回答是:

  • git fetch --prune(可选)更新远程回购的本地快照。其他命令仅限于本地命令。git reset --hard @{upstream}将本地分支指针放在远程快照所在的位置,并将索引和工作目录设置为该提交的文件。
  • git clean -d --force删除未跟踪的文件和目录,这些文件和目录阻碍git说"Working directory clean"。

  • 这是我经常面对的事情,我已经将上面提供的脚本概括为与任何分支一起工作。

    我还添加了"确定"提示和一些反馈输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #!/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


    下面是一个自动执行最流行答案的脚本…有关支持分支的改进版本,请参阅https://stackoverflow.com/a/13308579/1497139

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/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

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

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

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

    1
    2
    git fetch origin
    git reset --hard origin/HEAD

    它是如何工作的:

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

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


    我做到了:

    1
    2
    git branch -D master
    git checkout master

    完全重置分支

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


    如果你像我一样有问题,你已经做出了一些改变,但是现在,无论出于什么原因,你想摆脱它,最快的方法是使用这样的git reset

    1
    git reset --hard HEAD~2

    我有2个不需要的承诺,因此是第2个。您可以将其更改为您自己要重置的提交数。

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

    1
    git reset --hard HEAD~5

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


    以前的答案假设要重置的分支是当前分支(已签出)。在评论中,OP HAP497澄清了分支确实是签出的,但原始问题并没有明确要求这样做。由于至少有一个"重复"问题,请将分支完全重置为存储库状态,这不假定分支已签出,下面是一个替代方法:

    如果分支"mybranch"当前未签出,要将其重置为远程分支"myremote/mybranch"的头,可以使用此低级命令:

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

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

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


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

    至于为什么这些文件显示为修改状态的具体问题,可能是您进行了软重置,而不是硬重置。这将导致在HEAD承诺中更改的文件看起来像是分阶段的,这很可能就是您在这里看到的。


    这是我经常使用的:

    1
    2
    3
    git fetch upstream master;
    git reset --hard upstream/master;
    git clean -d --force;

    请注意,最好不要更改您的本地主机,而是签出到另一个分支机构进行任何更改,分支机构名称由更改类型预先决定,例如feat/chore/fix/等。因此,您只需进行更改,而不需要从主机进行任何更改。其他分支机构也同样如此。因此,只有当您碰巧提交了其他人已提交并需要重置的分支的更改时,才应该使用上面的内容。否则,以后不要推到其他人推到的分支机构,而是通过签出的分支机构签出并推到所述分支机构。

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

    检查你的遥控器,确保你的上游和源头是你所期望的,如果不是像预期的那样,那么使用git remote add upstream ,例如,你从原来的github repo,和/或git remote add origin

    1
    2
    3
    4
    5
    6
    7
    8
    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 Development与本地保存的工作分支具有相同的更改,则不需要这样做。我正在使用开发分支作为示例,但它可以是任何现有的分支名称。

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

    然后,如果您需要将这些更改与另一个分支合并,而在存在任何冲突的情况下,保留开发中的更改,请使用:

    1
    git merge -s recursive -X theirs develop

    使用时

    1
    git merge -s recursive -X ours develop

    保留分支名称的冲突更改。否则,将MergeTool与git mergetool一起使用。

    所有的变化都在一起:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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;

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


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

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

    XKCD:Git


    请尝试以下命令,它也将从本地git中删除所有未跟踪的文件

    1
    2
    3
    git fetch origin
    git reset --hard origin/master
    git clean -d -f


    唯一能在我所见过的所有情况下工作的解决方案是删除和重新排序。也许还有另一种方法,但很明显,这种方法不会留下旧的状态,所以我更喜欢它。如果你经常在Git中把事情搞砸,你可以设置一个宏的bash一行程序:

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


    如果您不介意保存本地更改,但仍希望更新存储库以匹配源/头,您可以简单地存储本地更改,然后拉:

    1
    2
    git stash
    git pull

    如果您希望在以后使用当前更改,那么以其他方式存储更改,您可以使用这两个命令,

    1
    2
    git fetch origin
    git reset --hard origin/master