I like the approach to covariant derivatives that starts with a connection. I'll quote myself (and fix a couple of mistakes at the same time):
Fredrik said:
Let V be the set of smooth vector fields on a manifold M. A connection is a map [itex]\nabla:V\times V\rightarrow V[/itex] such that
(i) [tex]\nabla_{fX+gY}Z=f\nabla_X Z+g\nabla_YZ[/tex]
(ii) [tex]\nabla_X(Y+Z)=\nabla_XY+\nabla_XZ[/tex]
(iii) [tex]\nabla_X(fY)=(Xf)Y+f\nabla_XY[/tex]
[itex]\nabla_XY[/itex] is the covariant derivative of Y in the direction of X. The covariant derivative operator corresponding to a coordinate system x is
[tex]\nabla_{\frac{\partial}{\partial x^\mu}[/tex]
The notation is often simplified to
[tex]\nabla_{\partial_\mu}[/tex]
or just [itex]\nabla_\mu[/itex].
The above only defines the action of [itex]\nabla_X[/itex] on vector fields, but note that condition (iii) above suggests a way to extend the definition to scalar fields. If we define
[tex]\nabla_Xf=Xf[/tex]
condition (iii) looks like the Leibnitz rule for derivatives:
[tex]\nabla_X(fY)=(\nabla_Xf)Y+f\nabla_XY[/tex]
So we choose to define [itex]\nabla_Xf[/itex] that way. Can we do something similar for covector fields? It turns out we can. Suppose that [itex]\omega[/itex] is a covector field. The closest thing to a Leibnitz rule we can get is this:
[tex]\nabla_X(\omega(Y))=(\nabla_X\omega)(Y)+\omega(\nabla_XY)[/tex]
so we choose to define [itex]\nabla_X\omega[/itex] by
[tex](\nabla_X\omega)(Y)=\nabla_X(\omega(Y))-\omega(\nabla_XY)[/tex]
for all Y. Note that this means that we define [itex]\nabla_X\omega[/itex] to be a covector field.
The same idea can be used to find the appropriate definition of [itex]\nabla_X[/itex] acting on an arbitrary tensor field. You can probably figure it out on your own.
Don't forget that the covariant derivative you're used to is the special case [itex]X=\partial_\mu[/itex].