Git is cheap
coderwall.com
coderwall.com
Commit early, hell yeah!
Branch often, umm, no. I feel that the excellent branching features of modern DVCSes have made people lazy and afraid to confront the inherent concurrent nature of working in parallel with people on the same codebase. Sure, if you're a 200 person team, there might be no way around it some decent branching setup. But don't forget: every feature branch means postponing continuous integration.
Continuous integration is the core of any productive and effective agile-ish team. Daily standups are nice, backlogs are lovely, but without continuous integration you can't get that design-develop-test cycle short enough to deploy/demo early and often.
Therefore, when working on a product or component with a limited team size (say, up to 15 people that are in close contact with one another), I believe that it is best to get your code on the mainline as fast as possible. Often, in git terms, the simplest way to do this is simply directly committing and pushing to master. Doing this helps signal conflicting concurrent work early, and it helps avoid double work. It encourages necessary but unforeseen design sessions before the work is done, rather than refactoring sessions afterwards.
The only strong downside to super-fast continuous integration that I can see is the chance that you "break the build" (or the tests, or whatever your situation has that needs to be OK for developers to be able to add features). If the team is in close contact, this is typically fixed within minutes ("hey Mike, you broke xyz.cpp" "oh damn, sorry, i'm right on it"), and if it isn't, well, git has cherry-picking features for a reason! You can use the tools to avoid the broken code for a few hours until the guy who broke it is back from the hairdresser.
Sure, you can do good CI with feature branches, but people have to be disciplined, and push their feature branch with master very often. Like, multiple times per day. I've never seen that work in practice. This doesn't mean that it can't work in practice, but it does mean that "branch away, buddy!" may be bad general advice.
When committing straight to master, the danger is of course that people hold back pushing their commits over the line entirely, which is bad too, but I find that once the horrible, horrible "whoever breaks the build gets pie" rule is replaced by the "whoever pushes more than x changed files/lines at a time gets pie" rule turns that culture around just fine.
I'll be the first to admit that this might work less well with e.g. highly distributed teams in different timezones. But that's hardly the most common scenario.
Continuous integration is called that for a reason. If you do A-few-times-a-week-integration, then call it that. And in my opinion, you're missing out.
Unless you're doing big commits (which we can all agree are bad), or the features you build in are trivial, the features are going to need more than one commit. At which point you either make the master non shippable (which is a bigger problem in continuous integration than integrating every 5 minutes), or you don't push often, at which point you're actually doing branching but your local feature branch is called 'master'.
The workflow you describe sounds more like "hey let's just edit the files on the server - make sure you don't hit "Save" before you make the complete change" than CI (at least my interpretation of it).
It's possible that you and the OP are talking about different things here. For me personally I branch a hell of a lot to organize my work locally. The vast majority of these branches will never be seen by anyone but me (they get merged into master when I'm done, and I just push master).
First, there are plenty of features and especially refactors that reasonably require a few days of work in order to be complete. How is committing half-finished or partially executed features in the build is useful?
Second, there is the case where you are juggling development of multiple features at the same time. It is clearly better to have these in their own branches so they can be worked on independently of each other rather than working with a tangle of unrelated and unfinished changes.
https://github.com/daleharvey/pouchdb/pull/158
You can see here a PR failed CI, a new commit was made that passed CI, its was then merged.
Its a workflow made in heaven for me
Perhaps I misunderstood something here though. Does anybody have any thoughts on this idea?
Builds/testing can happen on any branch, any repo. I'd like to have some local testing take place (for syntax at a minimum) before anyone submits changes to a shared branch.
And I think large scale OSS projects like Linux and Chrome are evidence that this approach works quite well.
Explicitly. You can't share branches between repos, but git does a good job of making it look like you can. master and origin/master in your repo are physically different things from master in someone elses.
I don't mean to single you out but I've seen developers with really, really nutty workflows because they didn't understand this.
The implicit branch here is any local code. It's clearly diverging from the authoritative repo (whatever that is for your workflow and VCS)
My point was that any workflow that doesn't operate in a shared source directory already has those local "branches". You might as well acknowledge it and roll with it.
(Doesn't diminish your point about master & origin/master. I think this link is a propos to that: http://wheningit.tumblr.com/post/32959730634/when-the-office... )
Two branches are two branches, even if they point to the same commit. Update one branch, the other remains unchanged.
I've been working on solving this problem over the last year. We added the ability to Bamboo (CI server by Atlassian) to detect new branches as they are created in the remote repository and automatically test the merge with master and optionally push the branch to master if everything is OK. If the merge or the tests fail, Bamboo lets you know immediately via email/XMPP/HipChat/etc.
Yes, it relies on developers being disciplined (read: responsible and professional) enough to push back to master in order to have the merge tested and the tests run.
Developers actually do it though because the benefits to having their feature branch tested regularly against master are huge: code is regularly merged and tested with master to ensure integration state and other team members are isolated from changes that can potentially damage development velocity.
Anyhow, if your interested in learning more, see my blog post called "Making Feature Branches effective with CI". I'd love more comments and thoughts if you have them.
http://blogs.atlassian.com/2012/04/bamboofeature-branch-cont...
Disclaimer: I am product manager for Bamboo @ Atlassian
Branching often means not having to worry about the impact of making an experimental change: it may not go anywhere but you want to be able to try something out. You don't have any heavy lifting to start or to clean up.
And establishing good branching strategies are essential for any project that has any kind of parallel development. It doesn't matter if it's one developer or 200.
The difference is that instead of having dozens of half-features in the integration branch at once, you have an integration branch with no dead code that you can actually ship (continuous deployment, anyone?) because your fully-integrated feature branches only make it in when they're ready, no matter how big or small the feature might be. It also means that experiments or major new features can be worked on and then discarded, or simply shelved in favor of higher priority work.
git commit (in my_branch)
git checkout master
git pull
git checkout my_branch
git merge master
(possibly resolve conflicts)
Ta! Da!!Continuous integration AND branching.
git commit
git fetch
git merge origin/master
No need to switch your current branch to pull.Once I started branching things got quicker and more effective because I could bounce between tasks without affecting my deployment (master branch). In five days of frantic coding using git branching I now have a clean easy deployment of about 750 lines, which I iterated on through four different branches and, probably over 3000 lines of code.
It's not perfect, but it's eliminated any apprehension about aggressively changing my application, and made me far more ambitious. I feel great about it.
What I meant to say more clearly is that I probably iterated through the creation of that web application so quickly because in five days I committed to git 75 times. In my time at Microsoft I don't know that I would have made 75 commits in a year, and creating new branches was very costly.
I got numbers on my git repository by using GitStats: http://gitstats.sourceforge.net/
It took me a matter of minutes to zero in on the exact commit that broke the app on that one machine. This would have been something I would have spent hours, possibly days trying to figure out by going over every tiny config detail (it wasn't a config issue).
Bisect is a powerful little tool to have in your back pocket when you know something you introduced at some time broke something and you need to find out what. The smaller and more "relevant" you keep your commits, the easier it will be to use. Obviously the opposite is true, if you have these massive commits which change large amounts of different files and/or multiple features, bisect becomes significantly less useful, almost worthless.
Just a pet peeve. Git is most certainly not cheaply made.
We currently have everything under one big SVN directory. I use git for personal stuff so it's always a pain to work in SVN.
I'm working on moving a dev team from SVN to git myself; the plan that people seem to be happy with is to use git as a drop-in replacement for an iteration or two while people get used to the new tools, and then start introducing people to the more advanced features as and when they seem appropriate, hopefully ending up with a git-flow style workflow.
You can make git-svn work for non-trivial setups but it took me a lot of trial and error, failed merges and git stashes to make it work for me.
Right now I have this workflow:
git add filename(s)
git stash
git svn rebase
git svn dcommit
git stash pop
The worst is failed merges in git svn rebase...Think about how the Linux kernel works. A single person at the top who has final say in the final product, a lieutenant responsible for each smaller group working on one subsystem.
Insist on keeping your history clean. Good commit messages and comprehensible changesets are necessary to make sure the code is understandable by code review, future maintainers, and when different teams' code needs to interoperate.
See http://nvie.com/posts/a-successful-git-branching-model/
Using a CI server to test merging branches back to master and running the tests make it a lot easier to know when its safe to merge back to master (I left a comment in the comments earlier about how this can be done).
In SVN is easy to create repositories. Not as easy as on GIT, but very easy.
Also, you can attach different commit-hooks to every repository, related to each project.
It's there that git wins, with it's better understanding of how content moves around, and the ability of the merge tool to see the history and identify the common ancestor.
In git, it just creates one file with a 40 byte hex.
This technique is in fact extremely similar to how Git works.
Even if you do commit to a branch, where publishing is less of a problem, you still might regret a typo in the commit, which cannot (easily) be retroactively fixed whereas in git you can fix your private/unpublished commits as much as you'd like with virtually no drawbacks.
Incidentally you can edit previous log messages in SVN, it's just that most servers have it disabled, for traceability.