Actually, there are as many practices as many companies there are. Meaning: every company has a little bit different conventions than others, but there are some common best practices that are generally used in most places.
I will present you with a commonly used scenario:
- All the source code of the project and anything that is required to build it is under version control. Anyone should be able to build the entire project with one click.
Furthermore, unnecessary files (object files or debug binaries) should not be added to the repository, as they can be regenerated quite easily and take up space.
- Every developer should update and commit to the version control a few times per day. Mostly when they have finished the task they are working on and tested it enough so they know that it doesn't contain trivial bugs.
- Again: anyone should be able to build the project with a single click. This is important and makes it easy to test for everyone. Big advantage if non-programmers (eg. the boss) are able to do so, too. (It makes them feel to be able to see what the team is working on exactly.)
- Every developer should test the new feature or bug fix they are adding before they commit those to the repository.
- Set up a server that regulary (in predetermined intervals) updates itself from the repository and tries to build everything in the entire project. If it fails, it sends e-mails to the team along with the latest commits to the version control (since which commit did it fail to build) to help debug the issue.
This practice is called continuous integration and the builds are also called nightly builds.
(This doesn't imply that developers should not build and test the code on their own machines. As mentioned above, they should do that.)
- Obviously, everyone should be familiar with the basic design/architecture of the project, so if something is needed, different members of the team doesn't have to reinvent the wheel. Writing reusable code is a good thing.
- Some sort of communication is needed between the team members. Everyone should be aware of what the others are doing, at least a little. The more, the better.
- Unit testing is a very good practice that makes testing the basic functionality of your code automatically.
- A bug tracking software (sometimes called time tracking software) is a very good means of keeping track what bugs are there and what tasks the different team members have. It is also good for testing: the alpha/beta testers of your project could communicate with the development team this way.
These simple things ensure that the project doesn't go out of control and everyone works on the same version of the code. The continuos integration process helps when something goes terribly bad.
It also prevents people from committing stuff that don't build to the main repository.
If you want to include a new feature that would take days to implement and it would block other people from building (and testing) the project, use the branches feature of your version control.
If that is not enough, you can set it up to do automated testing, too, if that is possible with the project in question.
Some more thoughts
The above list can be very heavyweight at first glance. I recommend that you follow it on an as-needed basis: start with a version control and a bug tracker, then later on set up the continuous integration server, if you need it. (If it's a large project, you're gonna need it very soon.) Start writing unit tests for the most important parts. If it's not enough, then write more of them.
Some useful links:
Continuous integration, Daily builds are your friends, Version control, Unit testing
Examples:
Subversion is a pretty decent version control software, and for example, VisualSVN is quite easy to set up if you use a Windows server. For client, TortoiseSVN worked best for me. You could use Git as well. Some people prefer that over Subversion. Here is a comparison.
As for bug tracking software, we used Mantis at my previous workplace. (In my current workplace, I had to write our own one from scratch.)
For continuous integratin software, there is Teamcity for one (also, CruiseControl and its .NET counterpart are notable).
Answer to your question "who decides the main design of the project?"
Of course, that would be the lead developer.
In companies, the lead developer is the person who talks to the financial / marketing people of the project, and decides the arcithecture according to the financial capability of the company, the planned features the requirements from users, and the time that is available.
It is a complex task, and usually more than one people are involved. Sometimes members of the team are also asked to participate or brainstorm about the design of the entire project or specific parts.