29

I work on a large Scala project where we use Git for version control. My workflow is to work on new features in my own branch and switch when needed. Various releases of the code are in their own branches. All very standard.

If I have to fix a bug in a certain version of the code, I'll switch to the correct branch, fix the bug, commit then switch back to where I was.

The problem is that although git is instant at switching to another branch once I'm there I have to recompile the code. Which takes several minutes. Then fix the bug, switch back to my own branch and do another recompile, which takes another few minutes. It seems to defeat the purpose of Git being so fast.

Has anyone else encountered this? Are there ways around it. I'm sure it's not a Scala specific problem (although Scala is epically slow at compiling).

update 3+ years later

I've been using @djs answer (git-new-workdir) for the last few years. It's worked very well for me. I have a master directory and several other directories (like production, next-release etc) that I switch to when I need to do work there. There's very little overhead and it means you can quickly switch to say, production, to test something, then switch back to what you were working on.

update 7+ years later

It looks like git-worktree is the replacement for git-new-workdir. To use:

cd ~/git/my-repo
git worktree add ~/git/my-linked-repo
David
  • 1,862
  • 2
  • 22
  • 35

4 Answers4

6

Assuming that your build system isn't overzealous about dependencies (maybe it thinks it needs to rebuild when it doesn't actually), the primary way to work around this is to clone your repository:

git clone my-repo my-repo2

You can then work in your extra clone, and push from it back into your main one. (You should only push to branches which aren't checked out, but that's the whole point here. You could also pull or even fetch and reset or branch -f if you wanted.)

And this won't really take up a lot of space, either; Git hardlinks the objects within the repository for local clones, so the extra space will just be the extra checked-out copy.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
6

Assuming you don't want to change your build process (hash-based instead of timestamped), you might want to look at the git-new-workdir script in the contrib directory of git source. Like the clone suggestion, you'll get multiple working copies, but instead of two independent repositories, you'll get one with multiple working copies. So, no pushing and pulling between local repositories.

It's a shell script and only runs on unix-like systems, but the concept can be replicated on modern versions of Windows.

djs
  • 4,626
  • 2
  • 28
  • 38
4

You could try using different target directories for different branches by overriding the outputDirectoryName. Maybe picking up the git branch name and setting the output directory to target-<branch>; although that would mean every new branch starts from scratch.

thoredge
  • 12,237
  • 1
  • 40
  • 55
  • I like this idea a lot. I'll try it out with sbt and intellij idea and see if they are amenable. – David May 19 '11 at 16:41
2

You can improve scala compile times drastically with by using [sbt][1] or the "fast scala compiler". Both allow to keep the compiler in memory, which improves compile times enormously.

Using one directory per branch allows to avoid so many recompiles. But that workflow is better supported by mercurial.

jmg
  • 7,308
  • 1
  • 18
  • 22
  • You don't really need a directory per branch. Two is usually enough; one is for your main work, and the other is for switching around all over the place. – Cascabel May 19 '11 at 13:42
  • Also, even if you can speed up the compiler, this can still easily be an issue in large projects, where a parallel build using all the CPU on a fast machine still takes several minutes. – Cascabel May 19 '11 at 13:43
  • @Jefromi: Indeed, yes. I tend to use between two and `n` directories, where `n` is the number of branches. – jmg May 19 '11 at 13:43
  • @Jefromi: Regarding the compiler: Yes, again. Nevertheless, I think both points of my answer are valid and helpful. And I would use both at the same time. – jmg May 19 '11 at 13:45
  • @jmg: Oh, totally - that upvote is mine. Just trying to point out that the multiple clones thing isn't too too scary, and it's definitely a good idea, even if you do other things to help out too. – Cascabel May 19 '11 at 13:46
  • We use sbt and fsc but a full compile still takes between 2-3 minutes (on a very fast machine). Switching branches can cause quite a lot of dependencies to change so a minute or two for a build is pretty normal. – David May 19 '11 at 14:54