git ls-files is preferred cause it doesn't need to create any commit object.
git ls-files --recurse-submodules -z | tar --null -T - -czvf output.tar.gz
# git ls-files
#   --recurse-submocules
#   -z, split output lines with null
# tar
#  -T -, read files from stdin