Families of software systems evolve in space, by introducing and removing features, to be available for different operating systems, and platforms, and offer functionalities to satisfy different users' requirements. In addition to evolution in space, families of software systems also evolve over time, when features are revised due to bug fixes and enhancements to keep the systems operating properly. For dealing with evolution in space and time of families of software systems, preprocessor-based systems managed in version control systems (VCSs) are the most used mechanism among existing ones. Preprocessor is one of the most widely used variability mechanisms for implementing open-source as well as industrial families of software systems within a software product line (SPL). One of the advantages of preprocessor-based SPLs is the easy creation of different product variants by selecting or deselecting different functionalities, i.e., features annotated in variation points in the source code with preprocessor directives. Moreover, preprocessor directives are pieces of text, and text can be tracked by VCSs, which makes their integration convenient. A negative side effect of the development of a system with preprocessor directives in a VCS is that for understanding and managing features developers have to perform manual analysis of preprocessor directives within multiple files of the whole platform, which can be a complex and time-consuming task. This is because preprocessor directives obfuscate the code, which makes it harder to understand, comprehend and maintain. Moreover, VCSs do not offer proper support to retrieve and analyze the changes at the level of features annotated in the source code. In addition, often changes of a single commit touch and affect multiple features, which can be tangled and scattered over different files and variation points. Thus, determining which features were actually revised/changed is an infeasible and error-prone task without additional tool support. Further, reusing and propagating a feature implementation across different versions can be very challenging and expensive. As preprocessor-based SPLs managed in VCS are widely established and well-integrated into development processes, it is necessary to bring up new solutions addressing their existing limitations for managing variants and their versions. One of the limitations of preprocessor-based SPLs managed in VCS is that VCSs do not offer support to keep track of changes and propagation at the feature level as a feature can have different implementations in different versions of a system. Therefore, the goal of this thesis is to overcome such limitations and challenges to deal with evolution of families of software systems in space and time. In order to propose a novel solution, this thesis first presents an empirical study of the feature life cycle in preprocessor-based systems managed in VCSs to understand how features evolve and learn the challenges and limitations of these mechanisms. This empirical study relies on an automated approach presented in this thesis for mining repositories of preprocessor-based SPLs managed in VCSs. This study showed the need for better support at the level of features. This thesis thus presents findings and challenges concerning feature location, and feature revision location, i.e., to locate different implementations of a feature at different points in time. The findings and challenges also refer to the composition of new configurations based on features and feature revisions, analysis, reuse, and propagation of features implementation in different versions of a system. This thesis also proposes an automated approach for mining, analyzing, and reusing feature revisions; and for feature revision location and composition of new products. Both approaches are realized in publicly available tools.