origin, upstream, and the remote-tracking shadow
A remote in Git is a named bookmark to another copy of the repository — typically a URL on a server like GitHub, GitLab, or your own gitolite host. By convention the remote you cloned from is named origin; nothing technically privileges it, but every tool and tutorial assumes it. Repos forked from someone else's project usually add a second remote called upstream pointing at the original.
What makes remotes useful is the remote-tracking branch. When you fetch, Git stores the remote's view of each branch under refs/remotes/origin/<branch>. These look like branches and behave like read-only pointers — origin/main is what your machine last saw on the server's main. Your local main can be ahead, behind, or in sync. The whole point of fetch is to keep this shadow accurate so you can compare your local work against it without guessing.
"Tracking" is a separate, optional configuration: a local branch can be set to track a remote-tracking branch, which makes git pull and git push default-correct without arguments. git switch feature/login on a remote-only branch creates a local branch that tracks origin/feature/login automatically (Git 2.23+). For new branches, git push -u origin feature/x sets up tracking on first push.
The mental model: there is a real server somewhere; origin/main is your snapshot of what it had at last fetch; main is your local work; upstream/main (if you have an upstream) is the original project. Fetch updates the snapshots without touching your work; merge or rebase integrates work into a snapshot or vice versa; push uploads your work to a server. Confusion almost always comes from forgetting the snapshot exists.