Using git log
I found an old 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.
If you find yourself in the detached HEAD state, remember that you can always preserve your changes by creating and checking out to a new branch, then committing and merging the changes in the desired branch. If you do not want to save the changes, you can simply check out to any branch, and Git removes those commits.
When you use the git checkout command to view a commit, you'll enter “detached HEAD state”. This refers to when you are viewing a commit that is not the most recent commit in a repository. Detached HEAD state is not an error nor is it a problem. When you are ready, you can navigate back to the HEAD in your repository.
to get out of detached HEAD state. Generally speaking: git checkout <branchname> will get you out of that. This also tries to check out your last checked out branch.
However, if you run git checkout on a specific commit, you won't be at the HEAD of the branch, therefore Git can't add any commits you create in the correct place. As a result of this, you'll be "detached" from the end of the branch and you can make changes and commit them, but they won't impact any branches.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With