需要将git分支重置为原始版本


Need to reset git branch to origin version

我不小心在一个我不该去的分支上工作了一段时间,所以我把它分开,给它取了一个合适的名字。现在我想覆盖这个分支,我不应该访问源站(Github)的版本。有简单的方法吗?我尝试删除分支,然后重新设置跟踪分支,但它只提供了我正在重新处理的版本。


如果尚未推到原点,可以使用以下命令将分支重置为上游分支:

1
2
git checkout mybranch
git reset --hard origin/mybranch

(请确保在单独的分支中引用最新的提交,就像您在问题中提到的那样)

注意,重置后,mybranch@{1}指的是重置前的旧提交。

但是,如果已经推了,请参见"创建git分支,并将原始状态恢复为上游状态",了解其他选项。

正如布拉德·赫尔曼(BradHerman)所评论的那样,一个reset --hard将删除任何新文件或将修改后的文件重置为头文件。

实际上,为了确保从"干净的石板"开始,重置后的git clean -f -d将确保工作树与刚刚重置的分支完全相同。

此博客文章建议使用这些别名(仅适用于master分支,但您可以修改/扩展这些别名):

1
2
3
[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

Then you can type:

1
git resetupstream

or

1
git resetorigin


假设发生了这种情况:

1
2
3
4
5
# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m"Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

然后你意识到你在错误的分支上做了改变。

1
git checkout -b mybranch    # you create the correct branch and switch to it

但是以东十一〔三〕仍然指向你的承诺。你要它指向它之前指向的地方。

解决方案

最简单的方法是:

1
git branch --force master origin/master

另一种方法是:

1
2
3
git checkout master
git reset --soft origin/master
git checkout mybranch

请注意,使用reset --hard将导致您未提交的更改丢失(在我的示例中为tests.py)。


我在一台服务器上有一个私有的回购协议,并定期对其进行重新平衡/强制推送,这使得经常需要在我的另一台计算机上重置本地分支。因此,我创建了以下别名"catchup",它允许为当前分支执行此操作。与另一个答案不同,此别名中没有硬编码的分支名称。

抓紧。

1
2
[alias]
  catchup ="!f(){ echo -n "reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) "; read -r ans; if [ "$ans" = "y" -o "$ans" = "Y" -o -z "$ans" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo "catchup aborted"; fi }; f"

格式正确(不适用于.gitconfig中的换行符)如下:

1
2
3
4
5
6
7
8
9
10
11
"
!f(){
  echo -n "reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) ";
  read -r ans;
  if [ "$ans" = "y" -o "$ans" = "Y" -o -z "$ans" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo "catchup aborted";
  fi
}; f
"
  • \\033[0;33m\\033[0m用于强调当前分支和上游的颜色。
  • $(git symbolic-ref -q --short HEAD)是当前分行名称
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))是当前分支的上游。

由于reset是一个潜在的危险调用(特别是对于--hard选项,您将丢失任何未提交的更改),它首先告诉您它将要做什么。例如,如果您在带有远程名为qcpp/dev container的branch dev container上,并且输入git catchup,则系统将提示您:

reset dev-container to qcpp/dev-container? (Y/n)

如果您然后键入y或只按回车键,它将执行重置。如果您输入任何其他内容,将不会执行重置。

如果您希望超级安全,并且以编程方式防止丢失未过期/未提交的更改,那么您可以通过对diff索引的相应检查进一步拉取上述别名。

必须警告的一句话:如果您正在处理其他人基于的公共存储库,并且您需要这个别名,那么您是在做错事吗?.