Version control should contain code and configuration which is needed to build the application.
This means that:
Temporary stuff which was introduced for a short amount of time (the time required to pinpoint the location of a bug, or to experiment with a feature of a language, for example) shouldn't be in a version control: keep it until you need it, then simply remove it when doing the commit.
Local files which are proper to a particular machine may be kept in a branch.
I would avoid keeping them just locally, since it's too painful to redo all this stuff when your laptop is stolen or a virus forces you to reinstall the OS (and, by the way, you find that your last backup was done two years ago).
On the other hand, be careful with file structure: local config is OK, until it becomes overwhelming, and forces you to make a single change in every file of every of 42 developers participating to the project.
Watch for opportunity to remove the particularities between the machines. It may mean:
Giving an access to a dev SQL server to replace local instances on developers machines,
Using package distribution services like Pypi or npm for public packages and their private counterparts for in-house packages,
Ask members of the team to install the same versions of software,
Make software updates as transparent as possible,
Or make it possible to deploy the OS and the needed software on a machine in one click (plus the time for every developer to install his preferred Vim vs. Emacs, Chrome vs. Firefox, etc.)
Project files. Paths may need to be edited in order to reflect the layout on the current PC.
Why not using the same layout on every PC? Paths within the project should be relative to the project file, which means that it doesn't matter where the project is located. Versions of software and libraries are better to be the same to avoid cryptic bugs which appear on some machines only, and are impossible to reproduce for other members of the team.
In a project created with Visual Studio, you may find:
The files themselves. Paths being relative, it doesn't matter whether on my machine, the project is located in
H:\Development\Hello World Project\ while other members of the team checked out the project into
The dependencies, i.e. third party and in-house libraries. Both types should be handled by NuGet which makes all conflicts-related discussions obsolete. If you don't have the same version of the library I have, ask NuGet to update the dependencies. As simple as that (when it works well, which is not always the case).
Note that it is crucial to keep in-house libraries in a private NuGet as well. Having a bunch of libraries stored in a shared folder or sent by e-mail across a team leads to anarchy and depressive CI servers.
The settings. It's crucial that the team shares the same settings. If half of the team decides to treat warnings as errors and half of the team keeps warnings as-is, the members of the first part of the team will spend their time removing warnings generated by the developers from the second part of the team.
The utilities-related settings. Those are tricky, because some members of the team may have installed some utilities, while others haven't.
It is strongly recommended to have the same toolset installed. If some programmers want to use StyleCop, but others don't, the team won't get the job done. If some use Code contracts but others don't, they will have the same issues.
Makefiles. For example optimization may need to be turned off during debugging, but not for the CI server.
Keep several makefiles in version control. It is not unusual to build a debug version on CI server as well and to push it to a client which experiences a tricky bug.
Dirty ugly hacks. For example return 7 in the middle of a function, in order to test something, depending on the function, and suspected to break at value of 7.
I would avoid such code in the first place. In order to test something, use unit tests. If it really takes a few seconds to swap some code for the purpose of debugging, then do it, but you'll remove this code in a few minutes anyway, so there is no need to commit it.
As you describe it, you should write a test. For example, if you want to be sure that:
public int CelsiusToFahrenheit(int temperature)
throws an exception when
temperature is inferior to
AbsoluteZero constant, you shouldn't play with code itself. Instead, create a unit test which will:
- self-document your code,
- increase the reliability of your code,
- ensure that maintainers can rely on regression testing when modifying the method above,
- serve to other developers of your team who may need to do the same test.