Reputation: 51837
So I've heard of the branch-per-feature workflow using Git, and I've also read some reasons why this could be a bad idea.
My real question is this - if I'm developing just a small feature (like a simple regex time parser), after merging this branch back into the trunk, what happens (or should happen) to that branch? Does it just sit there? Since I created it for that one, very specific feature, I can't think of a reason I'd have to go back and use the branch. Should I somehow mark this branch as defunct, or do I just move on and forget about it?
Thanks
Upvotes: 6
Views: 1478
Reputation: 44468
The nice thing about Git and branches is that each branch is essentially a pointer to a commit. Once you've merged your branch, the commits that used to form your branch are now an integral part of the main history.
your branch
main
|
(main) -------x----x----x-x---x----x
\ /
(your branch) \--x--x-x--x-x---/
At this point, if you delete your branch using "git branch -d", you're left with:
main
|
(main) -------x----x----x-x---x----x
\ /
(your branch) \--x--x-x--x-x---/
As you can see, the commits from your branch are still safe. All that has changed is that the pointer called "your branch" has been deleted.
Note, that if you had not merged into main, then "git branch -d" would have failed. If you force deleted it at that point, you'd be left with:
main
|
(main) -------x----x----x-x---x--x
\
(your branch) \--x--x-x--x-x
Since there is no branch pointer at this stage, the commits are "dangling" and will be removed the next time git does its garbage collection.
Long story short, if your branch has been merged, you can and should delete it. If it has not been merged, you shouldn't.
Upvotes: 3
Reputation: 165004
When I use feature branches, I like to retain the fact that a feature was developed in a branch after the merge. That makes browsing the history much easier. It groups changes by feature or bug and makes it easier to know the most important thing: why a change was done.
Which is why when I merge, I deliberately disable fast forwarding with git merge --no-ff
. This retains the structure of the branch in history. Then I'm free to delete the branch label (git branch -d branch_name
), the merge point contains the branch name, and clean up the set of branches.
In contrast, when working on a branch I prefer to rebase the upstream branch. This keeps the history of the branch nice and clean, free of lots of upstream merge noise and conflict resolution. I will generally rebase upstream before merging to make the job of integrating easier (as the branch author I can fix conflicts and broken tests) and the resulting merge cleaner.
This approach retains the history of the branches while preventing old branches no longer being developed from clogging things up. It makes visualizing the history with gitk or GitX very useful.
I agree with the basic points in the article you linked, as you get more and more large feature branches which are worked on simultaneously there's more and more chance of conflict and integration problems. The isolation which makes them so useful becomes a liability. One of the solutions is to not have large, old feature branches. If you can bust a feature branch up into smaller pieces which can be completed and integrated, then you avoid the problem. This is often useful for many other reasons, like the poor slob that has to review the code.
If it is possible to continuously integrate a feature branch into mainline, then the feature branch must have useful, working, tested, documented work. If it has that, then those could be sliced off into their own branches.
I freely admit I may be reading too much into this, but one of the possibly telling flaws in the article is that the branches are named for people and not features. This implies that each branch is for "whatever Jim is working on" rather than "adding blue widgets". It implies a number of developmental problems...
A lot of this is not a technical problem but a social problem. Much of it can be solved by strong use of a good issue tracker strongly linked with version control, such as Github's. The main change is:
That second one is, unfortunately, discouraged by most project's bug tracking policies. The urge to have a patch ready before reporting a bug is a very strong one.
Good branch management requires good socialization which is facilitated by a good issue tracker with strong version control integration and a welcoming policy.
Upvotes: 14
Reputation: 3801
Two things to consider:
Maybe you should have a habit of rebasing these branches onto the tip of master (or wherever) before landing them. This way, they are strictly redundant as KingCrush suggests above, and can be destroyed to be recreated later if you find a problem.
Use rename to mark branches you're not sure if you'll need again with a specific prefix, so that you can scan past them quickly in a list of branches when you know you're not looking for an obsolete feature branch.
You could use some mixture of these techniques, e.g. always rebase, then rename branch foo to landed-foo, and then after a set interval (say, one release, or 30 days) delete the landed-foo branch.
Notice that if you don't rebase (and run any tests on the rebased version) you have no way to be sure that a bug found after it lands was actually in the code as developed, and not caused by the impact of merging it after development, so in this case you might want to keep the branch for a while. This will happen more often with invasive / very large changes, not like your question scenario.
Upvotes: 1
Reputation: 46424
The only reasons, that I can see, you would want to keep it around is:
Upvotes: 0
Reputation: 131961
Delete it, if you don't need it anymore. If you realize later, that you need it again, you can create it again. And because you merged the changes back into "trunk" nothing is lost.
Upvotes: 4