Fetch is read-only with respect to your work: it writes objects and remote-tracking refs, so you can inspect what arrived with git log main..origin/main before deciding to merge or rebase. It does download the objects (they land in .git immediately), and it happily runs with a dirty working tree because it never touches it.
Official docs