_git: refactor and fix git diff completion

Before this, there were several cases where the completion
would offer the wrong things:

$ git diff branch -- <tab>

would try to complete "changed in workdir files", but needs to
complete all "tree files in HEAD".

$ git diff --cached -- file1 file2 <tab>
would try to complete "changed in workdir files" but needs to
complete "changed in index files".

...

After this change all possible combinations are taken into
account and completion should work properly.