I use Git every day and I wrote a Git guide and a Git Cheat Sheet in the past.
I consider myself a Git fan, but ...I'm not an expert of Git.
Commit, fetch origin, pull origin, push to origin.. that's my day-to-day of using Git.
And I do some Git:
The advanced things that Git can do blow my mind. It can be very complex, and I tend to avoid all that complexity. I almost never use Git in the command line, and use GitHub Desktop which is the simplest and nicest Git client ever.
Two things I do however use sometimes are cherry-picking and squashing commits.
Let's talk about that.
In projects where I'm the only developer, which means all my personal projects, I do tend to work on master when I can. For example if I'm doing a simple change, or adding a new post to the blog. Fast and non-breaking stuff.
In some cases however I do not use this approach, and instead I create a branch for a big feature.
This is also the default when working on a team-based or open source project.
You create a branch, and commit often. Committing early and often is a great advantage because you can work on your code with the confidence that you can always return back to a working state, or at least to a state you know that something worked.
You might do a series of quick commits where the message is "ok", "trying this", or "fix dumb mistake".
But at some point you need to converge to a stable state and commit the changes back to master, or to any branch you want.
You want to do one thing before that: squashing your commits.
GitHub can do that for you automatically when you are merging a Pull Request, and it's a workflow I've been using a lot on public Open Source repositories in the past.
Instead of seeing all the individual commits contained in a Pull Request, you only see one commit, and in the PR merge process you can write a detailed and dedicated commit message and description.
This will eliminate all the previous Git commits that diverge from the head of the branch you're merging to, and also remove all those commits where maybe you reverted changes, and so on.
This is squashing in the GitHub PR process. You can squash your commits outside of GitHub, too.
Once your work on a branch is done, you merge master (or any other branch where you want to merge) into it:
git merge master
so you can handle any update conflict there.
Then you checkout master, and from there you run:
git merge --squash <your-feature-branch>
This is just one of the possible workflows you can use, and doing all using GitHub is very simple and the option that can give you the least amount of headaches.