I am not a fan of Git. While some people may find it intuitive, I consider it one of the most complicated programs I have ever tried to teach. Some of that complexity comes from its inconsistent command syntax and needless jargon, but I realized a few days ago that there's a deeper cause.
To explain it, I have to go all the way back to March of 1968, when Edsger Dijkstra's article "Go To Statement Considered Harmful" appeared in Communications of the ACM. In it, Dijkstra argued that arbitrary use of the GOTO statement led to programs that were hard for both human beings and compilers to understand, and that we should instead restrict ourselves to a handful of control structures like for loops, if/else statements, and subroutines.
That might seem like an obvious truth today, but it wasn't at the time. It took a decade for structured programming to become dogma, i.e., for programmers to agree to limit themselves to a small subset of all possible flows of control when building software.
We haven't had that collective epiphany yet when it comes to distributed version control systems like Git. At its core, Git is a way to construct and manipulate a directed acyclic graph of changes to a project. Git allows programmers to make almost any change to that graph they can imagine, and the results can be just as hard to understand as the tangled flowcharts of patched and re-patched assembly code.
In practice, though, most of us manipulate the change graph in a small number of stereotyped ways, just as most FORTRAN and assembly language programmers used GOTO to build things that are recognizable as nested loops and conditionals. That makes me wonder when version control will have its structured revolution—when today's best practices will be enforced rather than encouraged. When it happens, I'm certain that the old guard will point out useful things it doesn't allow, and optimizations it doesn't permit, just as they did in Dijkstra's day.