我偶然在一个本不应该去的分支上工作,所以我从它分支出来,给它起了适当的名字。 现在,我想覆盖不应该从原始版本(github)转到该版本的分支。 是否有捷径可寻? 我尝试删除该分支,然后重新设置跟踪分支,但这只为我提供了我再次使用的版本。
#1楼
我在服务器上有一个专用存储库,并定期对其进行重新配置/强制推送,这使得有必要经常重置另一台计算机上的本地分支。 因此,我创建了以下别名“ 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 symbolic-ref -q --short HEAD)
是当前分支名称 -
$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))
是当前分支的上游。
由于reset是一个潜在的危险调用(尤其是使用--hard选项,因此您将丢失所有未提交的更改),因此它首先会告诉您它将要做什么。 例如,如果您在带有远程分支qcpp / dev-container的分支dev-container上 ,并输入git catchup
,则会提示您:
将dev-container重置为qcpp / dev-container? (是/否)
如果您随后键入y或仅按回车键,它将执行重置。 如果您输入其他任何内容,将不会执行重置。
如果您想超级安全并以编程方式防止丢失未分阶段/未提交的更改,则可以通过对diff-index进行相应检查来进一步拉起上述别名。
强制性的警告是:如果您正在使用其他人所基于的公共存储库,并且需要此别名, 那么您做错了™ 。
#2楼
假设这是发生了什么:
# 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
但是master
仍然指向您的承诺。 您希望它指向之前指向的位置。
解
最简单的方法是:
git branch --force master origin/master
另一种方法是:
git checkout master
git reset --soft origin/master
git checkout mybranch
请注意,使用reset --hard
将导致您未提交的更改丢失(在我的示例中为tests.py
)。
#3楼
我尝试了此操作,但它没有将当前分支重置为最新的远程github。 我用Google搜索并找到了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
而且有效
#4楼
如果尚未推送到原始位置,则可以使用以下命令将分支重置为上游分支:
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 reset --hard
一样。
正如Brad Herman所说, reset --hard
将删除任何新文件或将修改后的文件重置为HEAD 。
实际上,为确保您从“干净的状态”开始,在重置后使用git clean -f -d
可以确保工作树与您刚刚重置到的分支完全相同 。
这篇博客文章建议使用这些别名(仅适用于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
然后您可以输入:
git resetupstream
要么
git resetorigin