}
+ closeDir(dirPtr);
}
Today’s post is slightly unusual - we won’t talk about code, or coding conventions, or about how much more clever Rust is than C++ (which is a lot), today we’re going to talk about Process. And source control. This snippet of code is small, and ultimately not particularly important, but it highlights a not often talked about process in software engineering.
So the codebase I’m working in now has a dependency on a “SDK” provided by one of our vendors. It was added several years ago by a junior developer on the project [1], and since the “SDK” was not much more than a few C files bundled together it was copied into our repository. Over time, somebody discovered and fixed a bug in this dependency involving a directory handle leak and requiring the above fix.
Time passed. People left the team. I joined the team. The fixup!
commits got squashed. And then I had to upgrade our version of the dependency. Check that there were no commits (since they had been squashed). Get the latest version from GitHub. Copy it in. Everything worked.
Until six months later when we ran into the same bug.
The moral of the story is - tracking dependencies is non-trivial. What we do now for this particular dependency is we have a README
file which explicitly lists the commit hash that we copied the dependency from, and (manually maintained) patch files for the changes we have applied to the dependency. Ideally, if your tooling supports it (in C++ this can be difficult, Rust’s cargo makes some aspects of this easier), you should track dependencies in a separate repository which mirrors the source repository. If your company allows it, upstream any changes you make, so that you don’t have to worry about tracking your changes.
[1] Who would later become my boss, so they weren’t junior for long.
This blog series updates every week at Programming for Maintainability