我不小心在一个我不应该有一段时间的分支上工作,所以我给它起了一个合适的名字。现在我想覆盖的分支,我不应该从原来的版本(github)。有什么简单的方法吗?我尝试删除分支,然后重新设置跟踪分支,但它只是给了我我正在工作的版本。


当前回答

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

抓紧了。

[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中的换行符)它看起来像这样:

"
!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 symbol -ref -q——short HEAD)是当前分支的名称 $(git for-each-ref——format='%(upstream:short)' $(git symbol -ref -q HEAD))是当前分支的上游。

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

将dev-container重置为qcpp/dev-container?(Y / n)

如果你输入y或者直接点击返回,它就会执行重置。如果您输入任何其他内容,重置将不会进行。

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

必须警告一句:如果您正在其他人基于其工作的公共存储库上工作,而您需要这个别名,那么您就做错了™。

其他回答

有一种稍微简单的方法:

git reset --hard @{u}

@{u}是跟踪分支的快捷方式,所以如果你在master上跟踪原点/master, @{u}指向原点/master。

使用它的好处是您不必记住(或键入)跟踪分支的全名。你也可以创建一个别名:

git-reset-origin="git reset --hard @{u}"

不管你现在在哪个分支上,它都可以工作。

假设事情是这样的:

# 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

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

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

但主人仍然指向你的承诺。你想让它指向它之前指向的地方。

解决方案

最简单的方法是:

git branch --force master origin/master

另一种方法是:

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

注意,使用reset——hard会导致未提交的更改丢失(在我的例子中是tests.py)。

我尝试了这个,它没有重置我当前的分支到我的远程github最新。 我谷歌了一下,找到了 https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

这建议

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

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

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

这个方法奏效了

如果你还没有推到原点,你可以用以下方法将你的分支重置到上游分支:

git checkout mybranch
git reset --hard origin/mybranch

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

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

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


对于Git 2.23(2019年8月),这将是一个命令:Git switch。 即:git switch -C mybranch origin/mybranch

例子

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'.

这将恢复索引和工作树,就像git重置一样——很难。


正如布拉德·赫尔曼(Brad Herman)所评论的那样,reset -hard会删除任何新文件或将修改过的文件重置到HEAD。

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


这篇博文建议了这些别名(只适用于主分支,但你可以调整/扩展它们):

(别名) 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

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

抓紧了。

[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中的换行符)它看起来像这样:

"
!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 symbol -ref -q——short HEAD)是当前分支的名称 $(git for-each-ref——format='%(upstream:short)' $(git symbol -ref -q HEAD))是当前分支的上游。

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

将dev-container重置为qcpp/dev-container?(Y / n)

如果你输入y或者直接点击返回,它就会执行重置。如果您输入任何其他内容,重置将不会进行。

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

必须警告一句:如果您正在其他人基于其工作的公共存储库上工作,而您需要这个别名,那么您就做错了™。