120

I'm never sure when a project is far enough along to first commit to source control. I tend to put off committing until the project is 'framework-complete,' and I primarily commit features from then on. (I haven't done any personal projects large enough to have a core framework too big for this.) I have a feeling this isn't best practice, though I'm not sure what could go wrong.

Let's say, for example, I have a project which consists of a single code file. It will take about 10 lines of boilerplate code, and 100 lines to get the project working with extremely basic functionality (1 or 2 features). Should I first check in:

  1. The empty file?
  2. The boilerplate code?
  3. The first features?
  4. At some other point?

Also, what are the reasons to check in at a specific point?

13
  • 10
    before you go home, you commit to your own working branch.
    – Reactgular
    Commented Nov 22, 2012 at 16:53
  • 60
    The first commit should always be made after creating a Sourceforge project, setting up a website, configuring the mailing list, and blogging about the project for several years. :)
    – Kaz
    Commented Nov 22, 2012 at 18:26
  • 15
    What's the downside to committing too early or often? Commented Nov 22, 2012 at 21:08
  • 13
    mkdir myproj; cd myproj; git init; start work. Commented Nov 23, 2012 at 6:59
  • 10
    I learned how to manage progress saving from the quick-save button in video games. The rule goes something like: Will I mind having to redo that part ? Save : SaveAnyway; I take the same approach to source control, I don't wait for something to work or be anywhere near complete, I just wait until I've figured something out or made enough changes that I don't want to have to try figuring that out again or make those changes again, then I check in. That's why people suggest saving after project creation; Creating projects is annoying, check in so you absolutely won't have to do it again. Commented Nov 23, 2012 at 15:18

18 Answers 18

102

You should commit as soon as you have a sensible "unit" complete.

What is a unit? It depends on what you're doing; if you're creating a Visual Studio project, for example, commit the solution right after its creation, even if it doesn't have anything in it.

From there on, keep committing as often as possible, but still commit only completed "units" (e.g. classes, configurations, etc); doing so will make your life easier if something goes wrong (you can revert a small set of changes) and will reduce the likelihood of conflicts.

9
  • 27
    I commit damn near constantly to a work branch, and I merge that branch to the mainline in units. It gives the best of both worlds in that the mainline is made of units with small sets of changes to revert, but the topic branch can let me back up just a little at a time. Commented Nov 22, 2012 at 17:13
  • 17
    A commit is never too small! Don't refrain yourself from commit your changes! Commented Nov 22, 2012 at 19:49
  • 1
    I'd say +1 to many small, frequent commits, depending on your work flow and how many people are interested in your repo to get their work done. Git's ability to re-write history a bit so that those 15 commits on FooSerializer can become one thing before you push helps with this.
    – user131
    Commented Nov 23, 2012 at 0:28
  • 1
    @loldop: That depends on the version control software you're using. Let's say you're using Git: you can stash what you've done, do the fix, commit it, reapply the stashed changes and restart working on them. In Subversion, you can do another checkout of the repository in another folder, fix the bug and commit to the repository there without affecting your refactoring. Or create a patch file, revert your edit, fix the bug, commit, reapply the patch. There are many ways to do it.
    – Albireo
    Commented Nov 23, 2012 at 10:52
  • 1
    Maybe it is a good answer to the 2nd, 3rd commit etc. But the first should be just empty.
    – Felipe
    Commented Nov 23, 2012 at 12:44
144

As far as I'm concerned, your source control repo is part of the basic project setup, so I commit right after I generate my empty project.

7
  • 29
    Commit early, commit often. Commented Nov 22, 2012 at 19:46
  • 11
    I agree with this more than the accepted answer. I also view source control (I mean DVCS) as a big undo button if I royally screw things up. I would also highly recommend using semver (via tags) and starting of with version 0 Commented Nov 23, 2012 at 0:15
  • 2
    Thanks @AntonyScott I agree 100% with the accepted answer, but when I wrote this, I had this vision of muddying the waters with a 1500 word essay on how I manage source control and why. So I decided to keep it simple and to the point. Commented Nov 23, 2012 at 0:24
  • 2
    Yes, +1. If you feel bad about an empty commit, start with the .gitignore (or equivalent) as Xion wrote in another answer [programmers.stackexchange.com/a/176845/5405]. That's a very natural first commit. Commented Nov 23, 2012 at 9:13
  • I noticed the "long answers" flag on the question, and can't help but think it's referring to this answer. AFAIC I answered the 'why?' question with the "source control repo is part of the basic project setup" part of the answer. Like I said, I could write an essay on my complete philosophy about how I use source control, but it would only detract from this answer. If anybody has a specific question about my answer, I'll be happy to answer it, but otherwise I don't want to fluff up this answer for the sake of verbage. If you want to delete it, go ahead. Commented Nov 23, 2012 at 16:24
77

Yesterday

...in alternative, if you're unable to time-travel...
(maybe your car can't get to 88mph, or your flux capacitor just snapped)

Now

New projects should be committed on the bloody spot, it's crazy not to, and contemporary DVCS systems just removed every possibile excuse to avoid commits: git init . ; git add * ; git commit -m initial-commit now, before it's too late, as it might already be.

One more sensible, arguable, question could have been: "When should I merge my commits to a shared source control on a team managed repository on an established project?" (note the adjectives, adjectives are important) And I have the feeling most other answers are actually trying to reply to that.

Your personal branch should be commited to like crazy, at least once each day, before bedtime. You might just wake up the morning after, and find you have no clue of what the hell you were up to, the previous night. The VCS should cover you against that, and having the opportunity to rollback to a very recent sub-version-of-a-sub-version that compiles nicely, runs smoothly, and/or passes tests might be your best option.

2
  • 3
    I don't mind commiting changes that don't compile, especially at the end of the day. Next day you have something that doesn't compile but you still have your commit history - if you don't want your history "dirty" there are options for rollback in every good DVCS (I think we all agree DVCS are the only way to go.) Commented Nov 22, 2012 at 19:51
  • @LeonardoHerrera I understand your POV, although in interpreted language projects with multiple entrance points, you end up committing some non-compiling branch with legitimate reasons (like sharing bug fixes on a different entrance point) it certainly can be done way better and way nicer, but then it sorta becomes a matter of tastes... and de gustibus non est disputandum.
    – ZJR
    Commented Sep 17, 2014 at 22:25
21

I would say commit as soon as possible. The main purpose of source control is allowing you to go back in case something goes wrong, and this resonates with "commit early and often" practice.

Personally, my first commit typically contains just the .gitignore file (or equivalent) with few filters I know will be needed, like *.py[co] for Python code. Basic project setup and/or first simplest prototype is what usually follows.

1
  • I do something similar. Since I use GitHub, I also always have a basic README file, even it just contains the name of the project. I find having the file there from the get-go makes it much more likely that I'll update it in the future :). Commented Jan 26, 2013 at 21:46
15

The first commit can be a README file with as little as one line summary of the project, or enough information about the project's first milestone. The broad topics can also include:

  • Introduction
  • Project description
  • Project structure
  • Coding conventions
  • Instructions on how to:
    • build
    • test
    • deploy
  • Known issues and workarounds
  • todo list
  • Terms of use

The practice of updating the README before making changes to a project is also referred to as Readme Driven Development and it allows you to think through the changes before investing time in making those changes.

Anybody who wants to contribute to or use this software will then start with the README.

12

If you've done work that you wouldn't want to lose, it should be in your source control system.

This certainly applies to distributed systems like Git. If you're using a centralized system, and the only way to check something in is to make it visible to everyone, you might want to hold off -- or you might considering setting up your own local git repository, and submitting to the centralized system when you're ready.

3
  • 3
    My rule is this, with the addition that I also want it to be a "point in time where the code compiles". Commit that which does not compile and bisecting gets that much more annoying, if you ever have to find when you broke something.
    – Warren P
    Commented Nov 23, 2012 at 0:55
  • Wouldn't a temporary branch address that, at least for git? I haven't used git bisect much. Commented Jan 27, 2013 at 20:34
  • I use mercurial without rebase so I treat all commits as permanent
    – Warren P
    Commented Jan 29, 2013 at 2:17
7

My rule of thumb is to check in once my solution file (or other build script piece) is done, even if it contains a few files that are empty. It's good practice for when more than one person is working on the project. That file tends to have the worst merge issues initially as people are adding things to the project so needs committed early and often.

Even if you're the only one working on the project and it's only got one file, I find it easier to follow the same workflow and save the thinking for the problem at hand.

6

Not sure if it was mentioned.

But make sure that what you commit runs/compiles! So no syntax errors, etc.

Nothing more frustrating than to checkout code that's broken.

2
  • indeed, makes sense! Commented Nov 28, 2012 at 1:30
  • I disagree. If my code doesn't compile when I want to commit, I write WIP somewhere in the commit message. Then I can just ignore those commits when I need the latest version that compiles.
    – Minthos
    Commented Dec 12, 2012 at 12:27
5

Other point of view more related to software testing (TDD approach) would be committing as soon as you have new tests cases in green. This would mean you have a new "unit" of code completed.

1
  • To cover a method you might(mostly) need several unit tests for it. It's not really true to say if you make a test pass, then it means you finish a unit of work. It's not even true to say finishing that method is a unit of work either. Commented Feb 16, 2017 at 4:33
5

Just before you do something silly.

For those of us without magical powers, that means little and often.

If you're working by yourself, do it everytime you get a drink, or whatever.

If you're working in a team, you probably need to make sure that the thing compiles, so that if someone else gets latest, they won't get a bag of errors. But other than that, as much as you can.

4

About 2~3 hours into the project.

Just joking. There is not one good answer that will fit all situations. First of all, if you have a distributed version control system (like git or Mercurial) then commiting to your local repo is not going to preserve your data in the case of catastrophic failure. But a private remote repo may cost you money, e.g. on github. You will preserve the commit history, but in my experience you are not going to need that until your project is a bit advanced.

Also you don't probably want too much churn at the beginning, especially if you are moving files around. Committing changes will be a burden if only a small one. You may even decide to throw the thing away. But if you lose changes which are not trivial to replicate then you will miss having made a backup copy, and version control systems make for extremely valuable backup systems.

Some people nowadays use DropBox or similar to store their code. It may be a good compromise at the beginning of a project since it takes zero effort to set up. It is however a barbaric habit in serious software development, especially if several people are touching the code at the same time.

So, I tend to set up version control whenever I have something that is valuable, i.e. not trivial to replicate. Value is subjective (and depends on one's capacities) so you will have to make your own judgment. At that point I store a second repo on an external disk, or on github if it is a public project or my paying account will hold it.

3

Many people have already answered "Right away", and I 100% agree. I also like Xion's suggestion to start off with the VCS's ignore patterns (i. e. .gitignore or equivalent).

I guess it's pretty much agreed upon that there are no downsides to early commits. I'd like to add upsides:

  • You're less likely to commit stuff that you chose to discard but that's still lingering around. When I start a fresh development, I'll code and discrad stuff quickly, and when I committed later, when there's already a bunch of files, I have accidentally committed stuff only to delete it in the next commit. This, as opposed to small, or even empty, commits, is true noise in the history.
  • If you are a systematic type and have typical first steps in your projects, having those as commit points may be instructional to you or to others, and it might even provide an opportunity to branch off at a certain point and create a reusable project stub. I have worked on Maven-based projects where this was useful (because in setting up a Maven project, some small first steps can already define quite a substantial base, and while those steps are not much to do, they may require enough thinking to warrant reusability).
2

It may depend which VCS you are using.

With Git, I commit an empty directory (or with a nearly empty README file). The point is that I can go back and reset my branch to that empty state if I want to completely start over while I'm still early in the development process (before pushing upstream). I would then commit my "generated" files (e.g. visual studio solution). Then when I am actually coding I'll start committing each unit as you normally would.

With SVN, you are pushing upstream with each commit so you really don't get the luxury of starting over like you do with Git. In this case, it may not be beneficial to commit early if you think you'll be doing major revamping early on in the process. That's going to be up to the person coding though.

2

When I start a new project I usually start by committing that before any code has been added. A general rule of thumb I've always followed is: if your PC crashed and wiped all your data what code would you prefer not to have to write from memory. Ten years ago before TDD and better programming practice I was quite optimistic about what I could remember. Now, I tend to be more cautious. As a lot of other posters have said commit early and commit often. You are not losing anything by doing it.

I'm working on my own for most of the time so I must confess I'm getting slack but I generally commit before I go home. That way if I don't make it in tomorrow then my colleagues can pick up where I left off.

I'm currently using Tortoise/SVN at work.

2

Commit the empty project right away. Keep committing several times per hour you spend working on the project. Commit even if the code doesn't compile. I mark such commits with "WIP" in the commit massage to keep track of them.

I also have a script that automatically commits all my projects every 10 minutes to a backup repo, just in case I forget to commit manually. Let's call it my cloud-backed undo buffer.

Check in (aka. push) the project to a team repo when you need your team to see your code. Which is probably before your code is ready to be seen by your team, if you're anything like me.

If you want to be nice to your team, squash your commits before pushing them to the team repo.

1

I have gone through all the articles and i think we already got lots of good solutions but i would like to share my methodology with you.

While working on framework creation (right from scratch) lots of changes are going to take place for each module until the module is completed or finalized. So I always have 2 locations one is named as DYNAMIC and other is STATIC. When changes are going on and framework is not yet finalized it’s been committed in DYANMIC location and once it is completed and finalized I move that to the STATIC location. So I have a complete Source Control.

Thanks

0

With any application, you're going to spend some time designing the components. You should know, roughly or in full detail, your name spaces, projects, external references, 3rd party libraries etc.

If you're on a team, I would suggest your lead, or whoever is chosen, to create the base project, get the dependencies set, and check that skeleton (foundation which your project will be built on) in.

You also want to ensure you have your task, release, trunk, etc. branches spec'd out before checking in so your process is solid.

If you are working on a new "task" for a project that's already under way and you're in your own task branch, do your nightly check-ins so you preserve your work.

0

Usually I check in whenever I add something new, but try to separate stuff in discrete commits.

That means, if I add a new dependency, I make the changes until they either compile, or they are big-enough that it would be lost time to do them again, from scratch. If I have a bigger task, I try to commit multiple times, when it makes sense (once per function, every time I make it compile and run successfully, etc).

I also commit when I want a backup point (i.e. "if what I try now won't work or becomes too complicated, I want to come back to the code as it is now", or when somebody asks me to drop what I am doing and fix some urgent issue).

If you use a centralized source control system, you cannot commit arbitrarily for backup points, because a commit that doesn't compile/work affects everybody in your team.

Usually when I start adding boilerplate code (e.g. add a new webapp in a django website), I commit every operation I do.

If I follow a tutorial to generate/write code, I use step names in the tutorial for commit messages. This way, I can diff revisions and see what a tutorial step did, at any later point.

Let's say, for example, I have a project which consists of a single code file. It will take about 10 lines of boilerplate code, and 100 lines to get the project working with extremely basic functionality (1 or 2 features).

It would depend on how difficult adding the stuff is:

  • if it were trivial to add the boiler plate code, I would add it and commit right before starting on the other code (this way, if I make a mistake or introduce a weird bug later, I can simply revert to the boilerplate code and start again).

  • If the code were non-trivial, I would commit every time I added something new (anywhere between every two lines of code changed, to a hundred or so).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.