views:

114

answers:

4

In my current environment, we have a "clean" build machine, which has an exact copy of all committed changes, nothing more, nothing less.

And of course I have my own machine, with dozens of files in an "in-progress" state.

Often I need to build my application with only one change in place. For example, I've finished task ABC, and I want to build an EXE with only that change.

But of course I can't commit the change to the repository until it's tested.

Branching seems like overkill for this. What do you do in your environment to isolate changes for test builds and releases?

@Matt b: So while you wait for feedback on your change, what do you do? Are you always working on exactly one thing?

A: 

I prefer to make and test builds on my local machine/environment before committing or promoting any changes.

For your specific example, I would have checked out a clean copy of the source before starting task ABC, and after implementing ABC, created a build locally with that in it.

matt b
A: 

Something like that: git stash && ./bootstrap.sh && make tests :)

elmarco
+2  A: 

So you are asking how to handle working on multiple "tasks" at once, right? Except branching.

You can have multiple checkouts of the source on the local machine, suffixing the directory name with the name of the ticket you are working on. Just make sure to make changes in the right directory, depending on the task...

Mixing multiple tasks in one working copy / commit can get very confusing, especially if somebody needs to review your work later.

ionut bizau
A: 

I try hard to make each "commit" operation represent a single, cohesive change. Sometimes it's a whole bug fix or whole feature, and sometimes it's a single small refactoring on the way to something bigger. There's no simple way to decide what a unit is here, just by gut feel. I also ask (beg!) my teammates to do the same.

When this is done well, you get a number of benefits:

  • You can write a high quality, detailed description for the change.
  • Reading the first line of the description of each change gives you a sense of the flow of the code.
  • The diffs of a change are easy to read & understand.
  • If a change introduces a bug / build break / other problem, it's easy to isolate, understand, and back out if necessary.
  • If I'm half-way through a change and decide to abort, I don't lose much.
  • If I'm not sure how to proceed next, I can spend a few minutes on each of several approaches, and then pick the one I like, discarding the others.
  • My coworkers pick up most of my changes sooner, dramatically simplifying the merge problem.
  • When I'm feeling stuck about a big problem, I can take a few small steps that I'm confident in, checking them in as I go, thereby making the big problem a little smaller.

Working like this can help reduce the need for small branches, since you take a small, confident step, validate it, and commit it, then repeat. I've talked about how to make the step small & confident, but for this to work, you also need to make validation phase go quickly. Having a strong battery of fast, fine-grained unit tests + high quality, fast application tests is key.

Teams that I have worked on before required code reviews before checking in; that adds latency, which interferes with my small-step work style. Making code reviews a high-urgency interrupt works; so does switching to pair programming.

Still, my brain seems to like heavy multitasking. To make that work, I still want multiple in-progress changes. I've used multiple branches, multiple local copies, multiple computers, and tools that make backups of pending changes. All of them can work. (And all of them are equivalent, implemented in different ways.) I think that multiple branches is my favorite, although you need a source control system that is good at spinning up new branches quickly & easily, without being a burden on the server. I've heard BitKeeper is good at this, but I haven't had a chance to check it out yet.

Jay Bazuzi