Here's an imperfect solution
Track all your changes in the Change Set itself.
In my orgs where changesets are used; I open up a change set and give it a label like
Sprint xx.0 - Oppo Discounts
Then, each time I touch a class/trigger/VF page/VF component or metadata item, I've trained myself to add that item to the changeset immediately. Rather than take notes, I use the changeset itself as the list keeper.
Obviously, I sometimes forget to add something in the heat of the moment and this doesn't get discovered until I deploy the changeset to my staging sandbox where there might be deployment validation errors. In that circumstance, I go back to the changeset, clone it and change the label to Sprint xx.1 - Oppo Discounts
and add a comment into the description field as to what was added (i.e. forgotten) in the prior version of the changeset. Then, rinse and repeat.
You can also use Eclipse IDE Deployment tool to tell you what you've changed versus the target org and use that to double check your change set manifest.
Using a consistent naming convention for the changesets helps keep track of what is going on over time, especially if you deploy to multiple sandboxes/PROD
Of course, other orgs use GIT + Jenkins so the above won't always apply to everyone.