I have been using git for several years now. But like any other tool, you don’t REALLY know all its power without using it in the craziest situations. I’ve just discovered a core aspect of git that totally drives me nuts given what it can do!!!
Git is a distributed version control system, right? Those of us using it with github are probably well aware of pull requests, making local commits, and doing various day-to-day operations. But something I didn’t understand until I had to process a pull request from the Spring community was exactly WHAT a git commit was.
Git commits are hashed. The don’t use counters, because they must be unique across any machine. You can’t depend on the counters working correctly. Instead, the idea is that people can develop separately, in another repository, and then submit pull requests to make a contribution. I as the developer can then merge your pull request. Sounds great, right? But did you just skim over that that sentence, “merge your pull request“.
What are we doing when we “merge your pull request“? It typically means we are pulling changes from your forked clone to mine, but once you realize that there is zero requirement for a relationship between your fork and mine, you discover that commits can be pulled into ANY repo and branch.
For Spring’s getting started guides, we have a central repo where people can write entirely new guides, and submit them as pull requests. But we don’t merge them there. Instead, we create a whole new repo and pull in the commits there. And we do that after you have made your contribution. If you look at those commits, it will appear as if everything was created, developed, and published there. But it wasn’t.
For any guide, the tentative author first creates a draft for a guide. Authors are encouraged to create a fork of that central repo and then start making their edits. At that point, everything can be pushed up to a branch. The author crafts a pull request. From there, we could merge back to the original master, but we don’t want to. Instead, we want each guide in a separate repo to suitably manage each guide separately. This lets us take all of the author’s handiwork, and put in that separate repo.
Basically, commits are self contained. If you develop something on one branch, and I development on another branch, it’s possible to merge both of these efforts into a third branch in a totally separate repository. And it doesn’t matter if one is a forked clone of the other. Clean things up, and we can turn this all into a pull request back to the original master. Or it can go elsewhere.
The point is, breaking up work into commits, sharing them with others on branches, whether on your fork or not, you can keep things nicely segmented. Then it becomes easy to hammer out issues and fold things together. And the side effect is that ALL commits retain their history, status, and who wrote what. You can squash things if you wish, whereupon some of the history is flattened. But this type of flexibility is incomprehensible when using something like subversion.