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