Why doesn’t global $wp_query not get hooked?

If you look at the Action Reference, you can see the order things happen.

Note where init is, the query object doesn’t exist until the wp action.

// ...
init
└─ widgets_init
register_sidebar
wp_register_sidebar_widget
wp_default_scripts
wp_default_styles
admin_bar_init  
add_admin_bar_menus 
wp_loaded
parse_request
send_headers
parse_query
pre_get_posts
posts_selection 
wp
// ...