This was the mental leap of the day for me. A small leap, but a cool one (for me):
- Git represents commits in the repository as a Directed Acyclic Graph
- A branch in Git is just a pointer to a node in that graph.
- Master is just another branch and as such, it’s just a pointer into the graph.
- Once you’re done working in a branch and the work has been merged back into master, there’s no need to keep the branch label around. The story of how the commit happened is still in the DAG.
- “Deleting” a branch is really just removing that pointer into the DAG. Therefore, it’s safe to delete branches that have been merged back into some other line of development.
Whereas in the other SCMs I’ve used (Perforce, Subversion), branches are usually seen more as a copy of some set of a tree into a new namespace or directory. For example, in svn you generally cp your trunk into someting under /branches/, like /branches/awesome-feature, and then merge your changes back in later. If you then delete that branch to clean up your branches folder, you pretty much lose that hunk of history. Furthermore, svn doesn’t really deal well with the branched history when showing the change history for a file in trunk futher down the road. With Git and gitk, you can easily see the branch and merge points and figure out what changed when.