This is my main workflow when using git.
(master)$ git pull
(master)$ git checkout -b my-feature
# make changes
(my-feature)$ git add [changed files]
(my-feature)$ git commit
# repeat the above as needed
(my-feature)$ git fetch origin
(my-feature)$ git rebase origin/master # try --interactive some time, it's fun
(my-feature)$ git push [origin|upstream|fork] my-feature
# open a PR
# make some fixes
(my-feature)$ git add [changed files]
(my-feature)$ git commit
(my-feature)$ git push [origin|upstream|fork] my-feature
# uh-oh, need to resolve conflicts with master!
(my-feature)$ git fetch
(my-feature)$ git rebase origin/master --interactive
# fix conflicts
(my-feature)$ git rebase --continue
(my-feature)$ git push [origin|upstream|fork] my-feature --force # never force master
# ok, my PR's merged, all done with that branch!
(my-feature)$ git checkout master
(master)$ git pull
# and we begin again
I've regularly been seeing help threads from people who somehow wind up hundreds of commits "ahead" of master. I don't know how you get git into such a mess, but hopefully the workflow above helps more people avoid it.