Git doesn't track changes "within commits". It sounds like you should use revert
to "undo" your offending commit. After reverting, you can reimplement your changes, minus the bugs.
In general, you'll want to make your local commits small and isolated, so that they can easily be reverted and cherry-picked between branches when needed. When a single commit contains loads of unrelated changes, it is hard to "undo" only the buggy parts.
Before pushing to the remote repository, some people use rebase
to "squash" commits and clean up their local history; effectively "merging" small, related commits. The remote history is a team asset.