开发者

Why use `git commit` when in a detached state?

Using git log I found an o开发者_如何学编程ld version of my project that I wanted to mess with. I did git checkout version52 causing the project to be in a 'detached' state, made some changes, then did git commit on it. I didn't realize this would commit in a detached state.

After this I went back to my master with git checkout master but when I do git log my changes don't show up anymore. I realize now that the changes are stuck in my version52.

I can get these changes applied easily enough with git merge version52 but I was just wondering, what is the point of being able to commit in detached states in git? As a newbie this had me confused for awhile and I don't understand why it's allowed, or when to use such a feature.

EDIT: Sorry, I wrote "disconnected" previously but I meant "detached". In git this happens when you decide to view a previously checked in version of your project.


For the future, you should have created a branch to work off

git branch branchName version52
git checkout branchName

or

git checkout -b brannchName version52

Edited after comment

The git object model, which I have written about here, simply tracks a tree of objects. A branch is a pointer to a commit. Although the two are related you don't have to have a branch pointing to the tip of a line of commits.

When you create a commit you are still creating a tree of objects that will exist in the repository until it becomes old and you run git-gc to clean up these orphaned commits. I think what you are worried about is that there is no enforced requirement for commits to be made in a branch. This creates flexibility in the tool that sometimes catches out users, but git is an advanced tool.

In your case you made a commit and then went back to your master branch and you thought you had lost your commits, but if you had looked at the output of git reflog you would see the sha of the commit you created even though it wasn't on a branch. You could have created a branch off here by git branch branchName <sha of commit>. Or you could have merged or rebased these commits with/onto another branch without going through the extra steps of creating and deleting a branch just for this. Okay, so this is only a couple of extra steps, with only a few keystrokes; but it is useful in a few cases.

The thing is that a branch is only a shorthand to a tree of commits, just as a tag is a shorthand to a particular commit. Except that when you make commits on a branch, the branch pointer moves along with the latest commit.

There is always the head pointer which points at the latest commit, that you have checked out, so you are never really 'disconnected'


Committing to a detached head on its own is fairly useless but it is also used during interactive rebasing, which allows you to rewrite the history of a tree, if you mark a commit for editing.

After git reaches such a commit while rebasing it stops the process and you are allowed to change this commit with git commit --amend or even insert new commits as you usually do. Most importantly, such commits belong to no branch as git status clearly shows, so you commit to a detached head.

Many Git users, me included, think that interactive rebasing is one of the more useful git features and it wouldn't work if committing to a detached HEAD was impossible.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜