需要将 git branch 重置为原始版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9301782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:59:52  来源:igfitidea点击:

Need to reset git branch to origin version

git

提问by Brad Herman

I was accidentally working on a branch I shouldn't have been for a while, so I branched off of it giving it the appropriate name. Now I want to overwrite the branch I shouldn't have been on to the version from origin (github). Is there an easy way to do this? I tried deleting the branch and then resetting up the tracking branch, but it just gives me the version I was working on again.

我不小心在一个我不应该有一段时间的分支上工作,所以我把它分支出来给它一个合适的名字。现在我想覆盖我不应该进入的分支到原始版本(github)。是否有捷径可寻?我尝试删除分支,然后重新设置跟踪分支,但它只是给了我再次处理的版本。

回答by VonC

If you haven't pushed to origin yet, you can reset your branch to the upstreambranch with:

如果您还没有推送到原点,您可以使用以下命令将您的分支重置为上游分支:

git checkout mybranch
git reset --hard origin/mybranch

(Make sure that you reference your latest commit in a separate branch, like you mention in your question)

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

Note that just after the reset, mybranch@{1}refers to the old commit, before reset.

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

But if you had already pushed, see "Create git branch, and revert original to upstream state" for other options.

但是,如果您已经推送,请参阅“创建 git 分支,并将原始状态恢复到上游状态”以了解其他选项。



With Git 2.23 (August 2019), that would be one command: git switch.
Namely: git switch -C mybranch origin/mybranch

使用Git 2.23 (August 2019),这将是一个命令:git switch.
即:git switch -C mybranch origin/mybranch

Example

例子

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

That restores the index and working tree, like a git reset --hardwould.

这会恢复索引和工作树,就像git reset --hard这样。



As commented by Brad Herman, a reset --hardwould remove any new file or reset modified file to HEAD.

正如Brad Herman所评论的, areset --hard删除任何新文件或将修改后的文件重置为 HEAD

Actually, to be sure you start from a "clean slate", a git clean -f -dafter the reset would ensure a working tree exactlyidentical to the branch you just reset to.

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



This blog postsuggests those aliases (for masterbranch only, but you can adapt/extend those):

这篇博文建议使用这些别名(master仅适用于分支,但您可以调整/扩展这些别名):

[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:

git resetupstream

or

git resetorigin
[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

然后你可以输入:

git resetupstream

或者

git resetorigin

回答by user28667

Assuming this is what happened:

假设这是发生的事情:

# 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

Then you realise you make changes on the wrong branch.

然后您意识到您在错误的分支上进行了更改。

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

But masterstill points to your commit. You want it to point where it pointed before.

master仍然指向你的提交。你想让它指向它之前指向的地方。

Solution

解决方案

The easiest way is:

最简单的方法是:

git branch --force master origin/master

Another way is:

另一种方式是:

git checkout master
git reset --soft origin/master
git checkout mybranch

Note that using reset --hardwill cause your uncommitted changes to be lost (tests.pyin my example).

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

回答by DerManu

I have a private repo on a server and regularly rebase/force-push to it, which makes it necessary to reset the local branch on my other computer often. I therefore created the following alias "catchup", which allows doing this for the current branch. Unlike the other answer there is no hardcoded branch name in this alias.

我在服务器上有一个私人仓库,并定期对其进行变基/强制推送,这使得有必要经常在我的另一台计算机上重置本地分支。因此,我创建了以下别名“catchup”,它允许对当前分支执行此操作。与其他答案不同,此别名中没有硬编码的分支名称。

Hold on tight.

紧紧抓住。

[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"

Properly formatted (won't work with the newlines in .gitconfig) it looks like this:

正确格式化(不适用于 .gitconfig 中的换行符)它看起来像这样:

"
!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
"
  • The \\033[0;33mand \\033[0mis for emphasizing the current branch and upstream with color.
  • $(git symbolic-ref -q --short HEAD)is the current branch name
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))is the upstream of the current branch.
  • \\033[0;33m\\033[0m是用于强调当前分支和上游的颜色。
  • $(git symbolic-ref -q --short HEAD)是当前的分支名称
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))是当前分支的上游。

Since reset is a potentially dangerous call (especially with the --hard option, you will lose any uncommitted changes), it first tells you what it's about to do. For example if you're on branch dev-containerwith remote called qcpp/dev-containerand you enter git catchup, you'll be prompted:

由于 reset 是一个潜在的危险调用(尤其是使用 --hard 选项,您将丢失任何未提交的更改),因此它首先告诉您它将要做什么。例如,如果您在名为qcpp/dev-container 的远程分支dev-container上输入,则会提示您:git catchup

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

将开发容器重置为 qcpp/开发容器?(是/否)

If you then type y or just hit return, it will perform the reset. If you enter anything else the reset will not be carried out.

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

If you want to be super safe and programmatically prevent losing unstaged/uncommitted changes, you can pimp the above alias further with according checks for diff-index.

如果您想要超级安全并以编程方式防止丢失未暂存/未提交的更改,您可以通过对 diff-index 的相应检查进一步拉皮条上述别名。

The obligatory word of warning: If you are working on a public repository other people have based work on, and you need this alias, you are doing it wrong?.

强制性警告:如果您正在处理其他人基于工作的公共存储库,并且您需要这个别名,那么您做错了吗?.

回答by SimpleSi

I tried this and it didn't reset my current branch to my remote github latest. I googled and found https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

我试过了,它没有将我当前的分支重置为我的远程 github 最新版本。我用谷歌搜索并发现 https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

which suggested

这建议

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

I wanted to reset my v8 branch so I did

我想重置我的 v8 分支所以我做了

git fetch origin v8
git reset --hard origin/v8

and it worked

它起作用了