Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Am I wrong here?

It sounds like you may be a little fuzzy on how Git works.

> when you "remove" branch in git...it doesn't delete commits from tree...since it can lead to disaster

When you delete a branch, only commits and filesystem states that are no longer accessible from any other branch, tag, index, or stash become eligible for garbage collection. So in normal usage [1] [2], you shouldn't ever be able to delete the contents of any commit that exists in the history of any named commit.

A commit that is newly eligible for garbage collection will not actually be garbage collected during a grace period, I believe one week. During this time the commit is still accessible by commit hash [3].

Branches are kind of like variables in a garbage-collected language, and commits are like objects in that language. An object is eligible for GC if and only if there are no variables that point to it. Making new variables that point to the same object is a really lightweight operation since most of the data's shared. Unlike many OO languages, objects in Git are immutable, which means git can safely collapse identical copies of the same object to a single instance (an optimization which git is quite aggressive about).

> it can lead to disaster (if those commits were pushed already)

If you want to cause a remote repository to delete a branch, look at the --mirror and --delete options for the push subcommand. AFAIK, pushing the deletion of a branch has the same effect as if you deleted the branch locally on the machine you're pushing the deletion to.

> someone else could actually start new branch from commit which is in branch you just "deleted"

If another developer has merely fetched the deleted branch, their remote tracking branch will be deleted when they fetch again. If your colleague has created an actual local branch with the changes you deleted (as opposed to a remote-tracking branch), when or whether your colleague deletes that branch is entirely under his/her control [4].

[1] Using low-level git subcommands to force git to delete objects which are still referenced by other objects is abnormal usage.

[2] Corrupting the object database in your .git directory through unclean shutdown, hard drive failure, or vindictive hex editing is also abnormal usage.

[3] If you neglected to write down the commit hash before you deleted the branch, you can likely find it in the reflog. The reflog is a history of the commit hash at the tip of each branch. Alternatively, you can use git subcommands to browse the object database and find orphaned commits.

[4] At this point, git has no technological way [5] for anyone but your colleague to delete the local branch from your colleague's machine. Socially, of course, you can use project management techniques to encourage your colleague to delete the branch (e.g., if the official maintainers announce that the deleted branch is considered obsolete and will not support it or accept changes based on the version of the project in the deleted branch, that can be a compelling reason for people to stop using the copies that are floating around. Or your colleague's boss can tell him to delete it or be fired.)

[5] If you have git push access to your colleague's repository, or you have shell access to your colleague's user account, you can delete their branches. Footnote [4] is referring to the usual case where your colleague's machine is a private box where you have no access.



Thanks for your answer. I really was never aware of git's GC mechanisms before, that's why I was sure that commits still hold inside a tree. And you perfectly answered my question (well, at least parts that I understood all details about, I clearly see I'd need to read more some time later).

I still find mercurial's branching model "the right thing" in terms of tree showing development history inside a branch, or overall (multi-branch) history-review (where you clearly see which commit was made in which branch), but I now see that it's really nice from repository-cleanup perspective to have features git has, to deal with non-needed branches and commits (via different mechanisms).


Git's branching model is "the right thing" once you learn the idioms of git development.

For example, if you want to build a new feature, make a local branch so your changes are isolated. You can make work-in-progress commits that split up a large change into pieces, some of which may be experimental, contain debugging statements, or temporarily break things.

Then when you're satisfied your changes are bug-free, you can use an interactive rebase (git rebase -i) to turn the commits into clean patches that would be something you might e.g. send to the mailing list if you're working on the flagship Git project, the Linux kernel.

I like to keep my history clean, six months from now I won't be interested in all the bugs I wrote when I implemented a feature, and all the fixes that I came up with for them during initial testing. I won't want to see the implementation of that feature scattered over multiple commits. I just want to see one clean, bug-free patch that implements the feature.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: