In all the tutorials I see of using SVN or Git, they always show them updating individual files. I may work on 100 files in 1 day, is it normal to work on many files and at the end of the day, just do 1 commit for all the files instead of doing each file individually that I modify?
I typically break it down into units of work. If modifying all 100 files accomplished one unit of work check it all in together at the end of the day. But it's more likely that you touched 5 or 10 files for one task, then 20 files for another, etc., etc. I would recommend performing a check in for each of those. If for no other reason, your check in notes will be more accurate and more useful.
I don't like 1 commit a day. That feels more like a backup than source control.
I recommend committing files together that were changed as part of the same task/bugfix/feature, otherwise, they should be separate commits.
If all of your files for a particular day are part of the same feature, then that's fine. If, however, the files modified are for multiple, unrelated tasks, then this makes reverts and merges more complicated later on.
It's normal, but sometimes smaller commits are better than commit only at the end of day. If you are working with a big team and you commit only at the end of the day you probably will have conflicts when you update (before the commit).
Smaller commits are better when you and your team do code review too. So, you commit only 5, 10 files and the reviewer will review the code more easily. If you commit 100 files the reviewer will have much more work.
You generally want to group commits into logically related changes, all with one commit message.
You should always commit working code; don't commit something that's half done and breaks the build, which could also break someone who's trying to find out which commit introduced a bug by testing older versions. Each commit should contain a small set of changes that are all related to each other.
I wouldn't recommend batching up all of your changes for the day into one commit. If you need to look through the history later on, it will be hard to find the change you need if an entire day's work is crammed together into one commit. If you need to revert a change, it's best if you can revert an entire commit, instead of having to selectively revert a file at a time.
Of course, on some days, you will have a complicated change that takes an entire day to create; in that case, if it's all one logical change, then do one commit at the end of the day. Be reasonable, there are no absolute rules here.
A best practice is to make atomic commits, that is, commits that implement one complete modification (ideally, allowing your source tree to compile). This frequently involves touching many files in a single commit.
(Answering for Subversion.)
Well, it's generally considered ideal to commit a group of files as a self-contained "change". E.g. if you're working on a website and you add a new image to a page, your commit would be something like:
$ svn add header.png
A header.png
$ svn commit index.html header.png -m "Add new header to main page."
A header.png
M index.html
Revision 123 committed.
It really does make the history of the repository more meaningful if a given revision corresponds to a single feature, bug fix, or refactoring (etc.). There are two things to avoid:
- Having more than one change in a revision. If you change your mind about one of the changes, it's a bit trickier to find it and back it out without affecting the other changes conflated with it.
- (Less serious, perhaps?) Having a change spread over several revisions. It's nice if, after every revision, the contents are in a workable state (which might mean compilable and generally correct for a program, or well-formed HTML for a website). This also means it's easy to target any given change for backing out or review.
I know it's hard to remember to do this for all changes, and I have been guilty of committing a bunch of unrelated stuff with the message "backup misc changes" or something equally useful. These are lapses and one or two don't hurt. But it really is nice to see a history that says: "Revision 1, Implement X (modify A and add B). Rev 2, Fix bug Y (modify C). Rev 3, Refactor Z (modify D and E and rename F to G). Etc."
It's normal. Just make sure that the code compiles before commiting. The technique is called "atomic commits", AFAIR. It has a lot of advantages:
- more smaller commits are a better history for the file and repository
- you can exactly pinpoint a given location in time when a bug happened by reverting
- examining a single file will give you more info on it's history.
Note, that in the way that VCS's are implemented there's little impact on space consumption due to a large number of commits.
Consider separate branches for different features/bugs
Unless all the files you edit are part of the same feature or bug, you might want to consider branching for each bug/feature. Commit files together as a group (atomic) to each of those branches until they are done enough to be merged back into the trunk. This avoids the classic conflict of files having modifications in for two features and needing to release only one of them right away.
svn/git make this style of branching easier than some other version control tools.
As others have mentioned, it's best to commit in small batches, where each batch contains a self-contained change.
But this isn't just to make your version-control history more useful. It also improves the quality of your work, especially if you combine it with detailed commit comments.
You'll find that, before each commit, you need to take stock of what you've done, in order to write a useful comment. This will lead you to think through the consequences of your change, and you'll probably remember some side-effect that you didn't test, or something that you need to fix.
In addition, it will keep you focused on one task at a time. If you're keeping dozens of changes in your head at once, you'll end up forgetting something. By committing changes individually, you'll be able to focus on the quality of each change.