38

Understanding Refs, branches and dangling commit in Git?

 4 years ago
source link: https://itnext.io/understanding-refs-branches-and-dangling-commit-in-git-192251773c7c?gi=497a40347ed2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Understanding Refs, branches and dangling commit in Git?

Image for post
Image for post
Just a free stock image

Have you ever wondered how “HEAD” works on git? how branches are assigned, switched and created? what is detached HEAD state? Just bear with me for some minutes and you won’t bother about it in the future now (if you are a genius and never make mistakes).

If you understand this article you can fully understand the concept of reset, rebase and revert.

Some knowledge you should already know

  • what are commits? (just the feeling, not the definition)

(Skip if you know already) Commits are just the changes that are saved in a project, every time you change a file it will keep a track of those changes by assigning it a unique hash (a random 40 characters that are almost unique), just like checkpoint you save in a game and can go at any of the checkpoints and start your game from that checkpoint.

Refs or References

Refs or references are the pointers to commits.

that’s it. But let’s look at it from the other side:

Every git enabled project have .git folder where all the dirty work is done under the hood, and it is where all the data about refs are stored.

Image for post
Image for post

refs

So if you see the directory structure of .git/refs where all the references are stored, you will find there are two types of refs

  • branches (heads)
  • tags (this i will skip as it’s easy if you know refs)

his “heads” folder has references called branches, here there’s currently have only branch: master .

So, what is a branch?

A branch is just a pointer to a particular commit.

Let’s understand it deeply. I am assuming you know how to commit changes in a project (git add .&&git commit -m "your message" ). I have made a git initiated project and added a file name “hello.txt”, and commit it with the different messages as shown:

Image for post
Image for post

git log

And these two commits are connected as the latest commit will have the parent commit as the previous one before it. That means:

Image for post
Image for post

parent of 2nd commit is the first one

A branch is simply the movable pointer to one of these commits. The default branch name in Git is called master. As you start making commits, you’re given a master branch that points to the last commit you made. Every time you commit, the master branch pointer moves forward automatically.

So, currently master points to this commit:

Image for post
Image for post

state 1

So what’s a HEAD?

HEAD is how a git knows what branch you’re currently working on. It’s a pointer that points to the name of the current branch. It moves automatically when you checkout a new branch or make a commit to a branch. if it tops over your head let’s see it practically.

Now suppose our current project is in state 1 as shown in the above diagram, let’s make a new branch

git checkout -b branch1
Image for post
Image for post

what are the branches we have currently

now we have two branches in .git/refs/heads. and our current branch is branch1 .

Image for post
Image for post

state 2

branch1 is created which points to the same commits where master was pointing at (last commit). And now HEAD is pointing at branch1.

If you want to see where HEAD points at currently you can check by seeing what the “HEAD” file contains in the .git folder.

cat .git/HEAD
Image for post
Image for post

head points to branch1 in refs folder where all the references are stored.

Now, what happens if i make another commit working while working on branch1 ?

echo "change on branch1">hello.txt
git add .
git commit -m "commit 3"
Image for post
Image for post

HEAD will move with the current branch it points to, i.e., branch1.

so if i move back to master, HEAD also moves and points to master, so we can say:

HEAD is a pointer that generally points to the current branch we are working on, hence proved!! (yeah, right!).

After moving back to master, you again commit something and that will be on master branch like this:

git checkout master // switched to master
echo "changing the master branch file">hello.txt
git add . && git commit -m "change content in master branch"

Now this will happen:

Image for post
Image for post

but if you want to see the contents of a specific commit? That’s a bonus for you if you have reached here(thanks!).

Headless/Detached HEAD state?

If you want to go and see what were the contents of the 1st commit, then you will checkout that specific commit.

What git will do, it will point HEAD to that commit

git checkout 68c94
> // You are in 'detached HEAD' state...
Image for post
Image for post

state 5

now the contents when the first commit was made are in the “hello.txt” file because we are back in time!!!. you can see where HEAD points now

Image for post
Image for post

head points to that commit

You can go back to master by this:

git checkout master

But if you want to change something in Detached head state and made a commit

Image for post
Image for post

state 6

Now HEAD will points to that commit, but as this commit doesn’t have any branch referenced to it and if we go back to master branch, this commit will be garbage collected and hence is called a Dangling commit.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK