If you break it down and view them as terminal codes (or as the spec was designed, on a teletype), CR+LF is correct, and LF is not.
However, the inconsistencies of this over time have become really annoying. My long term pet peeve is in VB.NET when I have to do this:
' This works - using the VB6 interop
Split(StringName,vbCrLf)
' This doesn't work - using the native .NET function
' because .split is only expecting a Char, and not a String)
StringName.Split(vbCrLf)
Why would you want strings to be formatted using terminal codes? It's just textual data. It has nothing to do with terminals, other then the fact that terminals need to handle text. I see little reason that text should have to handle terminals.
With that said, CR+LF is just inefficient, since doing both of those tasks together is what is overwhelmingly desired for a newline.
Git for Windows asks during installation if you want to replace your Windows line endings with Unix-style. You can have it replace LF with CRLF on checkout and revert on commit, or you can just have it do the revert (swap CRLF with LF) on commit and not do the first replace. Or you can just leave everything as-is.
Interestingly, when manually making a multi-line string in Powershell, only the LF character ( `n ) is needed to make a new line. Using CRLF ( 'r'n ) gives identical behavior in most strings.
Though honestly, Windows just doesn't even matter any more to me, I haven't needed to touch an MS product in years...