我创建了一个新文件(包含相当多的代码和努力工作)并将其提交给我的git repo的主分支。片刻之后,我意识到我可能应该为文件创建一个分支。我以为我可以撤销master的提交并再次在分支上提交,但我认为我是以愚蠢的顺序做事。出于某种原因,我首先创建了分支,然后使用is it possible to revoke commits?作为指南来撤销提交。
这基本上就是我所做的:
echo "Lots of code and hard work" > newfile.txt
git commit -m "thoughtless commit" newfile.txt
# Oh wait, I should've branched!
git branch thoughtful
git checkout thoughtful
# Hmm, I didn't mean for that last commit to be in master
git checkout master
# get the previous commit's hash
oldhead=$(git log | awk 'BEGIN{commitcount=0; } /^commit/{ if (commitcount++ == 1) { print $2 }; }')
git reset --hard "$oldhead"
git checkout thoughtful
所以现在我显然已经在 master 上删除了一个提交(确实, master 上不再存在'newfile.txt'),但它仍然存在于 >周到(我猜reflog)。
有人会非常友好地解释我在这里做了什么,为什么不需要提交考虑周全?
答案 0 :(得分:3)
当您创建分支thoughtful
时,它从当前状态master
开始,该状态已包含提交。从那时起,这两个分支是无关的。无论您对master
做什么,都不会影响thoughtful
。无论如何,引入该文件的提交仍将是thoughtful
的一部分。
您应该尝试git log thoughtful
和git log master
来审核提交的历史记录。在thoughtful
上,您仍会看到您尝试从母版中删除的提交。
假设我们目前正在master
...
echo "Lots of code and hard work" > newfile.txt
git commit -m "thoughtless commit" newfile.txt
您已在master
上创建了一个包含newfile.txt
的提交。
# Oh wait, I should've branched!
git branch thoughtful
您已创建了一个分支thoughtful
,该分支处于当前状态master
,但与主完全无关。分支的起点是master
,因为您没有明确指定起点,并且当前已检出master
。
git checkout thoughtful
现在你在thoughtful
;你没有checkout
个新的分支来使它们成为现实,这一步完全没有效果,因为你做了以下事情:
# Hmm, I didn't mean for that last commit to be in master
git checkout master
现在你在master
。
# get the previous commit's hash
oldhead=$(git log | awk 'BEGIN{commitcount=0; } /^commit/{ if (commitcount++ == 1) { print $2 }; }')
当你刚刚使用master~
或HEAD~
时,你已经跳过了 ton 的箍来获得之前的提交。 那是你获得“之前”提交的方式,而不是通过检查git log
。将来,要撤消上次提交,请使用git reset --hard HEAD~
。
git reset --hard "$oldhead"
您已将提交master
更改为。现在它是上述命令发现的任何提交,可能是newfile.txt
之前的提交。使用--hard
会导致Git更新工作目录,因此newfile.txt
消失了;如果您省略了--hard
,newfile.txt
仍会在目录中,但会在git status
中列为新文件。
git checkout thoughtful
您已返回thoughtful
,其中包含newfile.txt
,正在更新您的工作目录并重新引入newfile.txt
。
答案 1 :(得分:1)
理解这一点的基础是你必须将分支可视化为指针到提交,这是分支的HEAD。每个提交都指向一个或多个父母。分支(主等)是指针。不多也不少。
创建thoughtful
时,您创建了另一个指向与master相同的提交的指针。然后,您将主指针移动到上一个提交。您没有删除提交或类似的东西,您将主指针移动到上一次提交。并且您的thoughtful
分支/指针仍然指向您想要的提交。你处于你想进入的状态!
PS:要获得旧的HEAD,请使用git reflog
或引用HEAD@{1}
等名称。此外,在这种情况下,HEAD~
也会给你正确的。{/ p>