Since you mostly want, at the moment, to look at a past commit, you probably should just check out that commit as a "detached HEAD". In detached HEAD mode, you are on no branch at all. Instead, you have checked out some historical commit, which you can now see and work with in your work-tree.
To exit "detached HEAD" mode, pick any branch name and use git checkout name
. That puts your work-tree back to the way it should be to work with the latest commit on the named branch, while also putting you on the named branch.
You can also—at any time, regardless of branches—use git diff
on any two commits to compare them. Use git log
to show your current commit, including its full hash ID, and previous commits, including their full hash IDs. Then, using your mouse to cut and paste the hashes, because commit hash IDs are way too hard to use otherwise, run:
git diff <hash1> <hash2>
Git will compare the snapshots in the commits specified by the two hashes, and show you what's different in those two commit snapshots.
Meanwhile, to answer the question you did ask:
So if I do a hard reset, would that also have an effect on the files in the online repo?
No. Not immediately for sure, because your repository is your repository, and their repository—the online one—is their repository. Nothing you do in your repository affects them at all until you have your Git call up their Git and ask it or tell it: make some change(s).
When you do a git reset --hard
in your repository, you:
Reset your work-tree.
Your work-tree is where your Git puts the files you can see and work with. Git does not use them directly. This is actually the last step of git reset --hard
. If you use git reset --mixed
or git reset --soft
, Git skips this step.
Reset your index.
Your Git keeps a copy of all of your current files in its index. Git also calls the index the staging area—these are two terms for the same thing. Doing a git reset --hard
tells your Git: Make all the index copies of files match the commit copies. This is actually the second step of git reset --hard
. If you use git reset --soft
, Git skips this step.
Change the commit identified by your current branch name.
This is the first step of any of these kinds of git reset
. Your current branch name, such as master
or testing
, currently identifies one specific commit. All other commits that are on the branch are found by starting1 at this one commit and working backwards.
When you use git reset --soft
, git reset --mixed
, or git reset --hard
, you get to pick out any commit you like, anywhere in your repository. Use git log --all --decorate --oneline --graph
to get a really big view of every commit in your repository, including their shortened hash IDs. You can now pick any commit you like, use your mouse to cut-and-paste its ID, and use git reset
to make your current branch name that one particular commit. The one commit your branch named before? Well, that one no longer matters much: the branch name now names the commit you picked out. Git will start there and work backwards through time to find all the earlier commits. Any commits after that point are no longer on your branch.
You can pick the commit that the branch already names! If you are on master
, and master
names commit deadcab
, and you git reset --hard deadcab
, the first step of the git reset
is to change master
from naming commit deadcab
to instead name commit deadcab
. This of course changes absolutely nothing: the name still identifies commit deadcab
. So the only observable effect is the reset to the index, and the reset to the work-tree.
If you pick some other commit, though, this changes the commit identified by the branch name.
Later, when you run git push
, you have your Git call up some other Git. Your Git talks with that other Git. Your Git gives them any commits that you have that they don't have (but that they need—your Git generally won't give them commits they don't need), then your Git will ask their Git: Hey, other Git! Please change some of your branch names, so that your branch names specify these particular commit hash IDs. The branch names your Git asks them to change, and the hash IDs your Git asks them to use, generally come from your branch names, using the hash IDs your branch names specify.
It's at git push
time that your Git sends things to the other Git. At git fetch
time—note that git fetch
is the first part of git pull
—your Git calls up their Git, but in this direction, your Git gets new commits from them, and then your Git updates your origin/*
remote-tracking names,2 rather than doing anything with any of your branches.
1I mistyped this as "staring at", at first. That's kind of appropriate. Git has to stare at the commit for a while, to find the previous commit. Then it stares at the previous commit, to find the next one back. :-) Each commit lists the hash ID of the commit that comes before it. These are the parent commit IDs that you'll see talked about elsewhere.
2This assumes you have exactly one remote, named origin
, which is typically true, but not actually required.