In my experience, it's salvageable, unless you destroy information, but plain git doesn't do that unless you tell it explicitly to do such a thing. It also may destroy information on successful completion of a command, eg ‘git rebase’, but such commands are designed to rewrite history, so it's desired to happen if you use them.
Unfortunately, being salvageable doesn't mean it's easy to understand how to achieve that. You can do pretty much anything you want, but with the above safeties on, it won't let you easily clean up the mess, since “mess” is also information that you cannot destroy without being explicit that you want it.
The key into git is to understand how it treats commit trees and branch labels, and what each command does to the tree. That allows you the usual checkout, branch, merge, rebase, commit commands. There is also reflog, but I never wandered into that area yet.
On a more practical point, add something like the following aliases to your config file:
[alias]
lg = log -20 --graph --pretty=oneline --abbrev-commit --decorate --date=relative
st = status -sb
br = branch -v
‘git log’ is rather useless in its raw form at the command line, the above ‘git lg’ gives you a more readable 20 lines of log history in your current branch. ‘git status’ is really your friend while staging, rebasing, and resolving conflicts, but it tends to be a bit verbose, the above ‘git st’ makes it much more compact for the simple staging case. ‘git branch’ lists the branch, I found it useful to also have the commit log of the associated commit listed with ‘git br’. Likely you will find and add other useful aliases in time. (All git commands tend to have loads of options to tweak their behavior.)
For experimenting with commands, it can be useful to clone your repository locally at the disk first, ie “git clone path/to/existing/repo path/to/new/dir” (git is a distributed VCS, you can make copies of all repositories, including the ones you already have!). That way you can mess around as much as you like, and simply delete the cloned copy if you totally break it. Note that such a cloned copy is a proper git repo, its origin points back to ‘path/to/existing/repo’.
Finally, the ‘git reset’ command is the fastest way to move branch labels to any commit. It's the drop-big-bomb-on-it approach of git. and as such a potentially dangerous command. It may destroy entire branches (any commit that is not directly or indirectly attached to a branch label will eventually be deleted by git). In time, you'll find you won't need “git reset” much.