Know Your Next Commit
This may be the hardest part. How can we know ahead of time what the next commit will contain? Similar to TDD (test-driven development), where we write a failing test before implementing the functionality that satisfies the test, many developers find this idea unintuitive at first. However, flipping the thinking process is exactly the goal. We don't try to predict what we will change, but rather we intentionally choose the scope of the next change. Knowing your next commit in advance turns the commit into a unit of software design. When choosing the commit scope, we don't need to know every line of code we will change in advance, but rather we choose a high-level goal that we want to achieve with that commit in the most direct and efficient way possible.
What if I don't know my next change?
Sometimes we may not be able to fully grasp the context well enough to choose the scope ahead of time, for example in legacy code. TCR (test && commit || revert) can be helpful in those cases. We can make exploratory changes until the scope becomes clearer. The clearer it gets, the more obvious it is when something really is out of scope. Some things are always out of scope; e.g., we are either working on a refactoring or on a behavior change. Also note that the intention for the next commit is usually on a higher level than knowing the exact files and parts of the code that will need to be changed, and while exploring the context the goal is to converge on that higher level goal.