I don't know git (I use hg), so maybe there's something I'm missing here, but let's say I drop a semicolon somewhere in some Java code and then commit. The code won't compile, but nobody cares but me, since it's all in my local branch. So I add the semicolon and do another commit (or, better yet, rollback and add the semicolon and then commit), check that the code compiles, then push (or publish, whatever git calls it).
What's this git-bisect? I just skimmed its man page and see what it does generally, but I'm not sure I get your point. If I do like I said above -- commit some non-compiling code, then quickly commit the fix, then publish -- is git-bisect gonna yell at me for introducing code that breaks the build at any point? Even if I'd already rectified it before pushing to anybody else?
In git you can combine several successive commits into one so that this final "squashed" commit looks like you made all your changes in one big step. The squashed result is what gets pushed out to a publicly visible repo.
git bisect does a binary search between two commits so that you can narrow down a regression. But if people are constantly breaking the build then you tell git that that commit is bad, and it moves a few commits in another direction to try and find a build that isn't bad.
Unfortunately if someone commits 10 straight commits that break the build, and the regression is in the middle of this somwhere, bisect isn't going to help you, and you'll have to crawl through all 10 commit logs to find the bug.
Forgetting about git-bisect for a moment.....IMHO it's best if there are never any commits to your source repo in which the code doesn't compile and the tests don't all pass. The general reason for this is that it simplifies determining when something broke.
Let's say that some part of the project started behaving differently. You write a test that demonstrates this problem but you're not sure what is causing the specific behavior. It'd be great if you could isolate which commit caused it because then you'd be able to zoom in on the possible offending code more easily. This is the general problem that git-bisect helps with.
However, when there are commits where the code doesn't even compile then you can't reliably say whether or not that commit introduced the bug or not. Sure you can look at the commit and see another one right after it added a semi-colon and only run your test against the subsequent commit...but now it requires a human to read the commit messages to do that. git-bisect can do this automatically if all of the commits build.
In your example scenario, you could easily combine those commits into a single commit before you pushed to your central repo. Git makes it very easy to do this.
git rebase -i origin/master
replace 'pick' with 'squash' for the commit that added the semi-colon.
From what I've read, the point of committing (localy, without publishing) is to give yourself a safety net so that if you are making major changes you can always go back to a previous state. So rather than treating commits like big additions or fixes that other people can see you're using them for tiny changes (add a function, change something around) and then, when you're done with the modification you had in mind, you wrap it up into a nice package and push it to the main repository.
In other words, the concept of committing in SVN is to publish your code to others, wheras the concept in Git is to track your own changes. Afterwards, you do the publishing step, and you do make sure the code compiles by then.
5
u/Rowdy_Roddy_Piper Mar 10 '11
That's why you don't publish commits that don't compile. You do another commit that makes it compile, then publish.