38

I'm a sole developer at my work and while I understand the benefits of VCS; I find it hard to stick to good practices. At the moment I'm using git to develop mostly web apps (which will never be open sourced due to my work).

My current workflow is make lots of changes to the development site, test, revise, test, be happy and commit changes, and then push the commit to the live site (so if I'm working on a big new change; I may only commit once a week; but my IDE has a good undo history for uncommitted stuff).

Basically, I'm only using git when switching between machines (e.g., work dev computer to home dev computer or to live machine), but during the day I don't really see the benefit. This leads me to have long laundry lists of changes (and I have trouble finding good msg for each commit; and whenever I'm in a rush - I tend to leave crappy messages like 'misc changes to admin and templates').

How often should I be committing? Should each one-line change get a commit? Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh? What I am missing out on by having bad VCS habits?

9
  • 2
    Maybe one of your hangups of why you feel like VCS doesn't work for you is because you are using Git as a solo developer? Git seems like overkill to me for a single developer, perhaps something simpler with less features like SVN will be easier to use?
    – maple_shaft
    Commented Jan 10, 2012 at 18:09
  • 6
    @maple_shaft: I haven't used Git, but Mercurial is about as simple as Subversion for basic solo developer tasks. (Simpler, actually, since creating the repository-equivalent is easier.) Commented Jan 10, 2012 at 18:26
  • 15
    Why would git be overkill? Commented Jan 10, 2012 at 18:30
  • 1
    @maple_shaft the real benefit comes later. No need to settle for less.
    – user1249
    Commented Jan 10, 2012 at 21:53
  • 3
    It's worth mentioning that for DVCS like git and mercurial, to reap the benefits of an offsite backup of your source control (as mentioned in some of the answers) you'd need to push regularly, not just commit.
    – tugs
    Commented Jan 10, 2012 at 23:16

10 Answers 10

23

You are missing a lot.

I'm solo too, in a way. I commit every time a make a significant change, or before I start a significant one so I can go back if I screw things up, and every now and then even if I'm not making anything big. Not everyday really, but close. Sometimes a few times a day.

What I get is that I can go back anytime I want. Which is a lot. Also, having the branches ordered helps.

I guess it gives me a lot of order.

I'm using svn, and I'm getting sick of it. But cannot spend more time learning anythings else.

Good luck.

3
  • 1
    I had avoided version control for a long time as I was under the impression that it was too bulky/ugly/annoying. A few months ago I decided to get familiar with Subversion and now I swear by it.
    – user43349
    Commented Jan 10, 2012 at 19:13
  • 1
    I have several solo projects: some on Github, some not. I always use git even if I'm just building something for the express purposes of learning a particular API/tool. It enforces good habits for the real projects where it is more useful, as @jbcolmenares describes.
    – sarumont
    Commented Jan 10, 2012 at 19:34
  • 2
    I'll counter your "cannot spend more time learning anything else" with hginit.com. Count the time you spend being angry at svn for one week, then take that amount of time to read hginit the next week.
    – tdammers
    Commented Jan 10, 2012 at 20:25
18

You should commit often. You should certainly commit after reaching some logical milestone. If that takes longer than a day, you should at least commit at the end of your work day, or better yet, break up your work into smaller chunks.

There are many reasons for doing that. For example, what if your computer crashes? It is much better to lose only a day's worth of work than a week's or a month's. Another reason is that frequent commits make it easier to isolate a bug. You can do a binary search and figure out which small change caused the bug.

Another thing: before you commit, you should do a diff and look at all the changes you have made. This allows you to check that all the changes make sense, and that you have not forgotten anything. This also helps you to come up with a better commit message. And, of course, this is another reason to commit often: it is much easier to go through a day's worth of changes than a month's worth.

5
  • "what if your computer crashes" - files are saved to disk quite frequently and backups made nightly (if you meant if the hard disk breaks). However +1 for the binary search for bugs could come in handy. I'm pretty good at quickly finding 95% of my bugs; but every now and then there is the truly bizarre bug arising from a seemingly inconsequential change in another part of the program.
    – dr jimbob
    Commented Jan 10, 2012 at 20:10
  • Yes I do mean "if the disk breaks", or "if the ceiling caves in", or "if an EMP device goes off nearby". :) Anything that may cause a loss of data. Committing often is the easiest way to back up your work, and it allows you to easily have an off site backup, by using a remote version control server.
    – Dima
    Commented Jan 10, 2012 at 20:26
  • 1
    @Dima: you'll need to push and not only commit to have your backup
    – liberforce
    Commented Jan 16, 2018 at 14:32
  • @liberforce Not all version control systems have a push operations. This answer is from 2012. I was using subversion at the time, which is not distributed. So, no push.
    – Dima
    Commented Jan 16, 2018 at 15:02
  • 2
    @Dima: sure, but the OP was using git, so the instructions could be misleading as you didn't say you were talking about SVN.
    – liberforce
    Commented Jan 16, 2018 at 15:45
10

To get the most out of CVS you should work on one feature/bug-fix at a time, and commit when that feature/bug-fix is complete. By doing this you'll gain:

  • commit messages will will be easier to create and will make more sense;
  • easier tracking of future bugs back to the changes that introduced them;
  • easier reverting to a previous state (even if that means losing a failed feature but keeping bug-fixes that occured afterwards).

Also, since you switch between PCs you should have at least two branches:

  • a "Ready to go" branch that always works (excepting the bugs you are working on in the development branch, of course)
  • a development branch that may be in an unrunnable state from time to time (like during your trip home from work ;) .
2
  • 1
    +1 for the ready to go branch! I don't know how many times I get asked to show the software as the boss and prospective clients walk by. It is nice to have a version that actually works and not in a state of flux.
    – bluebill
    Commented Jan 10, 2012 at 23:26
  • A version that works and is tested usually is tagged. That is what you should show, unless the boss wants to see the latest changes. In that case, you just git stash and show what you have, or checkout a specific commit. Of course, if you have big changes that are a work in progress, those should be in a separate work-in-progress branch, so your master branch is the de facto stable one.
    – liberforce
    Commented Jan 16, 2018 at 14:38
7

Should each one-line change get a commit?

If that is what fixes a bug, sure.

What I am missing out on by having bad VCS habits?

I worked with a guy who had "bad VCS habits". He loved to work all by himself and he was in charge of a product line that brought in something like $1,000,000/year. He'd only make committs when the boss nagged him. Then one day his hard drive crashed. After getting a replacement set up for him, we discovered his last check-in was 6 months previously. Since the VCS was Source Safe, you can guess what else went wrong - the last commit was corrupted. We had to go back more than a year to get a non-corrupted version of his product line. He didn't get fired, even though he should have been.

Another anecdote involves myself. I used to store code for hobby and research projects on removable hard drives. One day, my apartment was broken into. The laptop (which was broken) and all the removable hard drives were stolen. Every DVD (with the exception of Red Dawn) was stolen. None of the desktop computers were stolen. If I had offsite source control, I would not have lost 15 years worth of projects, especially since some were based off academic projects - many of the profs left academia to go to private industry so those projects vanished into a corporate IP black hole making the lost code impossible to recover.

How often should I be committing?

I break it down into a few metrics:

  • How much work are you willing to lose if your computer dies? or gets stolen?

  • If this fixes Bug_1234, then check the code in with the comment "fixes Bug_1234".

  • If this is a logical delivery/milestone, then check it in with a comment like "Bug_1234, form_xyz" (or Task_1234 as appropriate).

  • Always check in code on Friday evening before you head home. Also do a check-in (or undo the checkouts) of everything before leaving on vacation.

  • Whenever the company policy dictates.

1
  • 1
    I agree the guy should have been fired. Not commiting, even at least for the releases, is crazyness. How can you find bugs that appeared in version 1.2 if you don't know what code is in 1.2? Was the guy just doing copys of the code and zipping on his hard drive?
    – liberforce
    Commented Jan 16, 2018 at 14:43
5

Do not think in terms of number of lines changes. Think in chunks of functionality. VCS allow you to give a heading in a central place for each functionality chunk so you can easily see the "what has happened here" with e.g. git log.

Also, IDE's like Eclipse allow you to point to a given line and go to the commit that brought it into the shape you see. In other words, you can go directly from a source line to the commit. If the commit is small and has a good message, it is much more helpful than "fixed tons of bugs".

4

I'd say the biggest thing you're missing out on by grouping changes together like that is the ability to track down when and where bugs were introduced.

In my experience, there have been a couple of times where some bug is noticed two-three weeks after it was introduced and having to sift through a week's worth of commits is difficult that long after the fact. In these cases, it was helpful to simply binary search through the commits to track down which individual change caused the problem. These bugs were mostly memory usage bugs on C++ code, so it may not happen as often for your project.

Other benefits come into play when developing on a team - simple commit comments, easier merges, relating commits to bug fixes, etc.

I'd guess with your workflow that if you do start committing daily or semi-daily, you'll need to use tags or bookmarks to keep track of which version of code is in use on the live site. I'd say that's the most important thing to keep track of.

4

I am a solo developer too, I use SVN, and I love it. I have even written a tool to convert the structure of my database and the test data in it to xml so that I can include that in source control.

I usually commit whenever I have completed an autonomous unit of work. Sometimes, if I perform a bunch of trivial and unrelated single-line fixes here and there then I commit all of them together, but if a single-line fix happens to occur between two unrelated big autonomous units of work, then it gets its own commit, there is nothing wrong with that.

Also, I always commit code which compiles, and almost always code which also passes all the basic tests. If not, I make sure to include "DOES NOT WORK" in the commit message. The only case when this happens is when I have done important changes which I do not want to lose even though they do not quite work yet, and on top of this I am about to embark in a great refactoring adventure that I am not sure whether it will be successful. So, then, I use the repository as a backup of the work I have done so far before risking to mess it up and have to throw it away.

This means that I always commit when my source code needs to be committed; it makes absolutely no sense to have morning commit or evening commit rules. It is the state that the code is in which dictates whether or not it is time to commit.

The messages that you put in the repository do not matter much. If you absolutely cannot come up with something meaningful, it is still better to commit with a blank message than to not commit at all when you should.

If you can't think of a good commit message because everything you come up with sounds stupid, bear in mind that this is okay; commit messages are expected to state the obvious, so they are bound to sound stupid to you when you are writing them. But trust me, if you need to examine old revisions a month later you will be grateful for even the stupid messages over no messages.

1

Commit each time you do a "logical" change. For example if you're implementing a new feature, you're doing it step by step. Each of those steps usually depend on each other. So you can just commit those steps separately, and explain in the commit message why each step is required.

The commit message is really important. You must avoid telling what you're doing, tell why you're doing it. The code already documents the changes, but in 6 months you'll be happy to see why you did them.

This is also useful if by chance someone jumps in and you're not alone anymore. Even just for you, a clean history makes it easier to use a git blame to know when and why that line that has a bug has been changed.

Making small commits instead of big ball of mud changes also allows you to test the intermediate state. You can stash the changes if you have to release something urgently. If you introduce a bug while it worked before, you can stash and check if it's your uncommitted changes that introduces the bug, or if that was in an older commit.

You can also unleash the power of git bissect that will tell you the commit that that this nasty bug. If the commit is 2,000 lines long, it still helps but not that much...

Another thing is that it's the first step for continuous integration (CI) and then continuous deployment (CD). CI and your tests can be triggered on a new commit, hence telling you each time you push your changes if they break something or not. This way you can know if it's safe to deploy or not, and be notified of that at the moment the problem is introduced and not just before your release when you're in a rush.

About your other questions:

  • don't commit stuff that you didn't even compile, unless you're willing to rewrite your history for that (using git rebase --interactive).
  • a one line change deserves a commit if it has a separate purpose (fixes a bug, or is unrelated to your currently uncommitted changes). Use git add --patch to stage those.
  • no need to force yourself to commit before dinner, unless you have important stuff you can't afford to lose. In that case, you may want to commit in a separate branch your work in progress.
  • committing and pushing to a remote repository is a backup. If you commit and push only once a week, you can in the worst case scenario lose one week of work.
0

How often should I be committing?

As a solo developer I generally commit whenever I feel I have made a significant change, after basic testing, and when I leave a project at the end of the night.

Should each one-line change get a commit?

No, unless that one-line change is going to significantly change a feature or bug.

Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

Probably not. At least for me I do most of my testing and coding on a 'working copy' and commit after I am happy with my changes. In many IDE's it will show me what changed before I actually make the commit and give me an opportunity to attach notes to the commit

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh? What I am missing out on by having bad VCS habits?

I am not very familiar with VCS or what bad habits it causes. I think I have mostly shared my opinion on this in answer to the first question.

In response to the general question postulated, you seem to be mostly using commits as branches which is addressed in another responders post. I'm not sure which IDE you are using that has a good undo history etc, but I haven't found one that I felt was good beyond restarts of the IDE and moving in between machines.

2
  • 1
    I'm not sure how I read that incorrectly multiple times, but I kept reading that as 'VSS' as in Visual source safe. I am fairly familiar with some different version control systems including SVN and GIT and use them as a solo developer frequently, but probably have a few bad habits myself considering that I haven't really used them in the context of a large multi-developer scenario.
    – dbuell
    Commented Jan 12, 2012 at 23:24
  • Well, as I've battled with SourceSafe for more than 3 years, my comment still stands: Lucky you! To give you an example, VSS6 could handle repositories of about 200mb - 300mb, after that if you were lucky a few files would be randomly corrupted. Of course there where multiple fixes, and workarounds, and VSS was never intended by MS to be a full blown vcs, but consider yourself lucky you never had to deal with it...
    – yannis
    Commented Jan 12, 2012 at 23:31
0

I'm a habitual committer and I found that suits me, but admittedly my commit messages are almost always like,

Age:  9 mins [*] Working on implementing and testing PaintSystem.
Age: 17 mins [*] Working on implementing and testing PaintSystem.
Age: 37 mins [*] Working on implementing and testing PaintSystem.
Age: 52 mins [*] Working on implementing and testing PaintSystem.

So I can't exactly say that making such frequent and habitual commits to my branch (mercurial) has exactly encouraged the most detailed commit logs. Sometimes I'll even commit code halfway done if, say, my wife asks me to go out for dinner at which point I'll just hastily copy and use the previous "Working on [...]" commit message.

My commit log patterns are typically like, "Working on [...] Working on [...] Working [...] Completed [...] Started working on [...] Working on [...] Completed [...] Started working on [...]"

On the flip side though, it has saved my butt. Sometimes I do run into an edge case I didn't anticipate and test against, at which point the frequent commits help me figure out exactly where I introduced the mistake.

So I don't know about the best habits and I'm certainly not one to listen to as far as ideal commit logging habits, but I can certainly say that committing more frequently can definitely help out when you need to perform a regression.

Should each one-line change get a commit?

I've committed one-line changes before but usually tricky ones and maybe I was short on time. My commits don't always resemble perfect and complete units of work or change. As said, sometimes they're just the result of my wife asking me to go out for dinner unexpectedly.

TBH a lot of my commits which follow that "Working on [...]" log pattern are not modeling coherent units of change (why I often cannot come up with a message better than "Working on [...]") but just the result of me taking a breather, like making myself a cup of coffee. The "Completed [...]" message indicates the end of that unit of work, and there I often write a much more detailed message along with the first "Started working on [...]" type messages when I just start working on something. If you average commits like once every 15 mins, then those "Working on [...]" messages are more like in-betweeners for what someone might commit in one bulkier commit with a more detailed message.

Should I commit before any test (e.g., at least for syntax/compiling errors and then have to totally undo it; as the idea didn't work or the message is a lie)?

I just go ahead and commit it before even running tests sometimes (again if I had an unexpected event). Also even though I'm solo, I do push to a server (just one running here at home on a LAN) that does CI. That might seem like overkill but dunno, I got so used to leaning on that in my former workplaces. Plus I don't wanna be bothered having to run all my unit and integration tests by hand each time. I like having that all tied to just pushing. If a test fails it's easy enough to work in a forward-moving fashion where I do the regression, correct the mistake in the latest rev, and keep going. That said, I do at least build the code against a debug build before I commit.

Should I make sure I commit each morning/afternoon before I stop working for dinner while its still fresh?

I like to commit before I go out and have a break between programming. I didn't really put much thought into why exactly until I encountered this question. I suppose it's to prevent myself from picking up where I left off without a commit log there in place of where I left off that I can diff and so forth. Hmm, I need to get back to you on that since it's maybe not theoretically needed given how frequently I commit. I still feel more comfortable committing and pushing before I leave the computer for whatever reason. Some of it might be that former psychological fear of, say, the computer catching on fire after I leave and having project managers back in the days when we were using SVN with the devs sometimes going for weeks without commits breathing down our necks and constantly reminding us to check in code as often as possible while reminding us that our code is the company's property. Also it's a little bit more efficient especially with the pushing so that my CI process can start running all the tests while I'm away so that I can come back and see the results.

Oh and sometimes I get a bit drunk after I leave and it's usually a bad idea to try to write complex code while drunk (though not always; one time I came up with a really nice context menu system after having an eureka moment while drunk, but I only had like 6 beers and it wasn't that complex to code). If I attempt to do that, at least I committed the soberly-written code before I left to revert back towards instead of mixing the drunk code with the sober code, at which point my commit log might read like, "Reverting back to code written before Jagermeister shots." I don't do this very frequently unless I got a drunken code inspiration, but in those rare cases, it really did help that I committed something before I went out and got drunk.

1
  • Rule of thumb for you: if you have two consecutive commits with identical messages, you're almost certainly doing it wrong. Either they should be one commit, or you should figure out what's different about them and write log messages that reflect that difference (e.g. "define new paint data" and "set paint data properly" rather than "working on paint system" x2). Commented May 16, 2018 at 16:43

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