Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ask HN: What is wrong with this git workflow? (davidyang.posterous.com)
26 points by aditya on May 20, 2009 | hide | past | favorite | 6 comments


Why wait 2-3 months to merge everything back into master? Why not do it every day? Or better yet, do it whenever a good bit of functionality (a story) is completed, which can be several times a day?

It's better to see where the dependencies are up front instead of waiting until the very end of the iteration.

Here's the ideal Git workflow, described by three different people but all pretty much recommending the same thing:

http://blog.hasmanythrough.com/2008/12/18/agile-git-and-the-...

http://gweezlebur.com/2009/01/19/my-git-workflow.html

http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-te...


Continuous integration should help to get rid of your merging headaches. I would merge way more often. The moment a developer has implemented and tested a bit of code -> Merge and resolve conflicts. 2-3 months are very long iterations. I think you should break your problems down into smaller parts.


In a nutshell, merge more and rebase less.

If you can avoid it, don't maintain long-lived actively-developed branches - especially several at once. You are certain to produce conflicts this way, and they will require some amount of manual resolution no matter what SCM you are using.

So my main suggestion is for everyone push their work onto the master much more frequently throughout the development period (whenever it's at a point where all tests are passing and it won't break things for other developers). Anyone working on a long-lived branch can then pull periodically (like, daily) from master and deal with the merge conflicts incrementally, before they've diverged too much.

"Often, what happens in a release is that topic branch 1 relies on commits from topic branch 2. We're not exactly sure how to best handle this, if we start sending patches from topic branch 1 into topic branch 2, will that make it harder for us to merge topic branch 2 into the system test branch?"

No, it won't make it harder. The developer of branch2 can merge from branch1. Git will see in the history that branch2 now contains commits from branch1 and that will help it with later merges.

"Is there a way to move the resolution of the conflicts back into the topic branches? I know this sounds ridiculous but instead of resolving the conflicts in the merge commit, is there a way we could push the resolutions into the proper branches so that the merged version really holds no real state?"

Yes. Instead of checking out master and doing "merge branch1" or "pull branch1", checkout branch1 and do "merge master" or "pull master". (As I suggest above, you should actually do this frequently throughout the development of branch1.) Then when you eventually finish with the branch1 and merge it back into master, all (or almost all) of the merging is already done and you won't have any conflicts.

"Where are the resolutions of the conflict stored right now?"

They're stored in the merge commits - any commit with more than one parent. But if you rebase instead of merging, you lose this information. That's why I say you should rebase less, and instead do "real" merges.

"If I start with a master branch, split off into four topic branches, then merge them back into master, it does a 3-way merge of the end points of each topic branch. If I do a rebase from the merge onto the original master branch, it seems to replay the topic branch lines in sequential order of commits on that line time-sorted by which topic branch was first spun off... is there a way to compress these multiple topic branches and conflict into one patch?"

If you really want to destroy all the branch history and squash everything down into one commit, you could continually "git pull --rebase" from 'master' to 'topic' during development, and then "git merge --squash topic" onto master when development is finished. You'll end up with just one commit.

But I wouldn't do that. If you're doing that, it says that you care more about how the history looks than about your actual development process. Merges may look "ugly" and make it take longer to read through your project history, but that ugliness reflects the reality of concurrent, multi-person development, and merge commits retain accurate history that helps tools like "git merge" work better with fewer conflicts.


Quick add-on comment: "git rebase" is a nice way for an individual developer to avoid spurious merges or clean up their history before pushing it to a shared repository. But (as Linus and others have said) it should never be used on commits after they've been pushed from the developer's workstation to the public/shared repo. That will rewrite history that other branches may depend on, and will cripple git's ability to intelligently do repeated merges between branches.


I think you've covered the important stuff here, but I'd like to add one point:

We do this because we have a requirement that we need to be able to rip out a topic branch at any time from this release

It's nice to be able to rip out topic branches at any time, but I would submit that once the topic branch is complete and its time to merge, the decision of whether to use it or not needs to be finalized. If you don't do that you're inflicting mental overhead on the developers to support the project manager's waffling. Depending on the nature of the topic and how modular and well-factored the code is, it may be more or less of a chore to maintain multiple branches, but unless both you're going to release both versions of the software, I say merge the branch ASAP and save yourself the trouble.


Yes, definitely. No software is going to make it easy to rip out any of five or six branches late in development. With five branches, this means that you might ship any of 2^5 == 32 different products, and you don't know which until right before it's released.

Merging late optimizes for the case where no branches are included, but as you've learned it makes it painful for the normal case where all (or most) do ship. Merging early optimizes for the case where all (or most) branches are included, but yes it makes it harder to remove a branch later on. Or you could always maintain each of the 32 possible release branches, and merge each topic branch continually with 16 of them... :)

As a compromize, you can merge frequently from master to topic, but then merge topic back to master only when you are fairly confident in it. (Hopefully this will be early for at least some topic branches, so that any conflicts with other topics can be resolved early.) And I totally agree with the other commenters who suggest shorter iterations and continuous integration.




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

Search: