今天使用git的时候在终端发现这样一条信息
HEAD detached at head
心里一惊,艾玛这是什么状态?
其实我们知道,git checkout本质上是修改HEAD里面的内容来让它指向不同分支的,而HEAD文件指向的分支就是我们当前的分支,但是有时候HEAD不会指向任何分支,严谨的说是HEAD指向了一个没有分支名字的修订版本,此时恭喜你,已经处于游离状态了(detached HEAD).这时候我们在进行commit操作不会提交到任何分支上去.
这个时候输入git status查看当前状态发现我没有在任何本地分支上也验证了刚才的猜想,而这时候我又作死的进行了commit操作,git提示我
然后我欢天喜地的git checkout ask_11_16切换到工作分支以为万事大吉,艾玛坑爹啊,我特么辛辛苦苦写了一天的代码呢?不过这时候我们回看上面那段提示,智能的git告诉我如果我还想要这次提交的话,可以创建一个新的分支,同时把本次提交的id告诉了我:fef4501.
那么这时候我已经有了一个思路:
输入
$git branch temp fef4501
使用git branch 分支名 操作ID 这句命令能够创建一个新的分支,但要注意此时我们还没有切换到这个分支上,这个分支上面代码跟我刚才提交完之后的一样.
输入
$git checkout ask_11_16
意味着我已经切换到ask_11_16分支,这个分支是我之前想要提交的分支.
然后
$git merge temp
这行命令过后我们已经上次commit合并到ask_11_16上了,此时终端状态为
Your branch is ahead of 'origin/ask_11_16' by 1 commit.
我们只需要$git push即可把本次提交push到远程分支.
这时候检查代码,perfect!正式我们想要的状态.
大功告成,至于temp分支已经没有了利用价值,本着过河拆桥的精神我不得不输入
$git branch -d temp
来删除temp分支.
git是一个很优秀的版本控制工具,利用得当能让我们在团队协作时候如鱼得水,但是万一有操作失误,也会让很多不熟悉git命令的人各种发愁,下面贴一个git命令大全,非常实用
通常情况下,HEAD指向一个分支;同时,每一个分支对应一个特定的commit(确切的说,一个分支上可以有多个commit,但是只有一个顶层commit,而且commit之间是简单的线性关系)。我们来看下面这个包含三个commit的例子,其中目前在master分支上。
HEAD (refers to branch 'master')
|
v
a---b---c branch 'master' (refers to commit 'c')
^
|
tag 'v2.0' (refers to commit 'b')
在这样的状况下,如果进行一次提交,当前分支将指向新的提交点。具体来说,git commit创建了一个新的commit id,它的父节点是的commit的id是C。这个时候,HEAD仍然指向master分支,而且指向commit id是d的提交点。
$ edit; git add; git commit
HEAD (refers to branch 'master')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
有时,如果能够检出到一个不在分支顶端的commit点是很有用的(通常情况下,我们直接运行命令git checkout mater,这样checkout到master的最新commit上);同样,如果能够创建一个不属于任何分支的提交点也是一件很有用的事情。运行接下来的两条命令,看看会发生什么。
$ git checkout v2.0 # or
$ git checkout master^^
HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
注意,现在head已经指向commit b,这就是所谓的dedatched head状态。从这里我们也可以看出,head是当前index的状态,而不是当前分支(的最近commit节点)。这仅仅意味着head指向某个特定的commit点,而不是指向每一个特定的分支(的顶端节点)。如果我们此时提交一个commit,看看将要发生什么:
$ edit; git add; git commit
HEAD (refers to commit 'e')
|
v
e
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
注意,此时产生了一个新的提交点,但是它只能被head索引到,不属于任何一个分支。当然,我们还可以给在这个“无名分支”的基础上继续提交。
$ edit; git add; git commit
HEAD (refers to commit 'f')
|
v
e---f
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
实际上,我们可以进行任何git的常规操作。但是,让我们开看看如果我们运行git checkout master将会发生什么:
$ git checkout master
HEAD (refers to branch 'master')
e---f |
/ v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
此时,我们一定要注意,e f已经处于无法被索引到的状态。最终e和f将被git的默认回收机制所回收,除非我们在它们被回收之前创建一个指向他们的索引。如果我们没有从commit f离开的话,可以用接下来的命令创建一个指向f的索引。
$ git checkout -b foo (1)
$ git branch foo (2)
$ git tag foo (3)
1.创建来一个foo分支,指向f,接着更新head指向分支foo,此时,我们不再处在detached head的状态
2.同样创建了一个foo分支,但是head仍然指向master分支,仍然处在detached head的状态。
3.创建了一个新标签foo,仍处于detached的状态。
如果我们从f处离开,我们必须首先恢复他的主体名称,接着我们才可以创建指向它的索引。例如,为了看看最近的两个由head指向的commit点,我们可以使用如下的命令:
$ git reflog -2 HEAD # or
$ git log -g -2 HEAD
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!