Work on a master branch for your regular work. When you develop a feature consider a feature branch, when its clear that you will do other things inbetween before the feature is finished.
For commits which produce code that does not compile (or has other obvious errors) use a local branch, which is never pushed. merge commits later and rebase them until it looks clean, than either rebase it onto master or as a feature branch you merge into master.
For a release, create a release commit, i.e. changing the version number in the readme, changing the ChangeLog entry from
1.1.0-dev () to
1.1.0 (2017-09-22) and similar. commit it for example with the commit message "version 1.1.0".
If you plan to support it parallel to newer versions, create a branch for v1.1.0, where you cherry-pick the bugfixes from master branch. For
1.1.1 you then create a correponding
version 1.1.1 commit and tag in the branch.
Leave old branches as they are. You never know when you will backport a very important fix for a customer who really wants to use the old version. You may consider to add a commit indicating the lack of support when a old version is no longer maintained. But a hint in the readme on the homepage and master branch may be enough.
Good versions never change. If your version 1.1.0 is broken, release a working 1.1.1 and just remove the broken packages for 1.1.0 from your website. Some sites like python pypi will not even let you upload a new package with the same version number, because people would never be able to tell if they have the broken or the working version.