I've googled a lot but I can't find an answer.
For what I've understood, a commit should be applied each time a file is edited. Explaining what was the edit, why, etc.
Then I should push the commit to make the server version of the file synced.
What I can't understand is:
Why should I commit and not immediately push a file I've edited?
It is true that a very common thing you want to do when working with version control is: "record changes into a commit, then send that commit to a remote server". In fact, most Git GUI tools probably let you do this in one step. However, logically, "record changes into a commit", and "publish commit to a server" are distinct operations. In Subversion, only the server keeps track of commits, so you have to send the changes to it for this to happen. In Git, the local repository keeps track of commits as well, so it's possible to split them up.
Now, while doing the two in a single step is a common workflow, there are many situations when you might want to do something else:
You're not online at the moment, or the remote server happens to be down, or your connection to it is slow for some reason. I.e. sending changes is either technically impossible, or would interrupt your work and disrupt your concentration for too long. In this case want to delay publishing commits until later, but you want to keep working (and making commits) until then.
You expect you'll have to merge in changes from coworkers. This is a very big context switch from working on your code, and similarly to the situation above, you might want to delay this until you're done with your task so you can stay focused on it. (This, in fact, tends to be a very common problem in Subversion teams - the mentality that "merging is annoying" that makes people do one commit with all their day's work when they leave, without really resolving conflicts properly. Since resolving conflicts is easier with "nice" commits with a clear purpose, this creates a vicious cycle.)
You're contributing to a project by emailing patches. (This is how the Linux kernel used to be developped, and maybe still is. This requirement in fact influenced Git's design early on.)
You're making very frequent commits and maybe pushing them to a private remote repository for backup purposes. However, you want to use
git rebase to clean them up before publishing them - say, bundling a new feature with fixes to bugs found in the initial implementation into a single commit.
A nitty-gritty reason: you're committing to a feature branch that doesn't even exist on the remote server yet so there's nothing to push to. (Which is desired as well, feature branches don't necessarily need to be published widely.)
Basically, Git strives for maximal flexibility in order to support arbitrarily complex workflows. Now, you might not need this, in which case you can easily use GUIs or small shell scripts that will combine the stuff you need.