I can't speak to your experience on TFS, since I've never used it, but your description of it sounds somewhat similar to Perforce.
> History is linear, full stop, and conflicts are handled by essentially forcing a rebase on commit.
This is similar to Perforce, but not something I miss. That forced rebase in Perforce has the very real possibility of causing breakages, and there is no way (at least in Perforce) to reliably handle it.
I also don't think history should be linear; the cheaper branching model in Git in my experience leads to people actually taking advantage of it; contrast this to Perforce, where branches were expensive: people wouldn't bother.
At least in the case of Perforce, the fact people didn't use branches forced them to put all of a feature into a changeset (Perforce's closest equivalent to a commit), which was usually way too much; this results in multiple, distinct changes being squashed together. The lack of cheap branches makes it hard to build a change off of two in-progress changesets, again because the system cannot efficiently represent that state.
And then there was just tooling: Git's add -p option for splitting off partial files into a separate commit, the ability to rework the convoluted history that came from my discovery of how best to implement something to something that encapsulates discrete changes that can later be reverted or cherrypicked gracefully (without reverting everything, unless that's really required) are to me, extremely useful tools that just don't exist elsewhere.
> Some admin does branching and merging and emails us if there are weird conflicts, we don't worry about that. Why make it more complicated?
(To be clear: this does not match my understanding of Perforce; branches there are possible without an admin.)
I just simply can't fathom why someone would want to have to go through another human for a branch. It seems like so much bureaucracy for something that, as Git shows, does not require it.
> why source control isn't a problem solved 100% by tooling in a way that requires little to no interaction at all. To them, hearing that they need to read a chapter about the internals of a source control system before working on a project
I think because, if we accept that history is not linear, and should not be represented as such, then history must therefore be represented as a DAG. A DAG, in my experience, is about the point where people start trying to cheat, for whatever reason, with incompatible and flawed mental models. This bites them in the ass at some point, and they can't understand what they're doing wrong within that flawed mental model, because the model itself is flawed. (And I see this all the time in software engineer, not just with Git. People are too quick to analogize permanently something to something else that is at best a crude approximation.)
Now, as another poster in the comments notes, I'd temper with the above with: some of git's tooling and UI could be better. The mix of "index"/"cache"/"staging area" to all mean the same thing, the variety of things "git reset" can do, etc. all are terrible UI on top of a superior model, but do contribute to the confusion newcomers experience. I hope some day this changes.
> At least in the case of Perforce, the fact people didn't use branches forced them to put all of a feature into a changeset (Perforce's closest equivalent to a commit), which was usually way too much; this results in multiple, distinct changes being squashed together.
First add a feature flag for your feature, then you can have as many small changelists as you like.
This doesn't help at all with deep refactoring. The "git way" of producing small, self-contained changes covers all possible changes, not just feature additions.
Good point, thanks! In my experience all big refactorings (short of a rewrite) can be done incrementally if you're clever enough, and that has a lot of benefits. But maybe doing them in another branch is a valid approach too.
> History is linear, full stop, and conflicts are handled by essentially forcing a rebase on commit.
This is similar to Perforce, but not something I miss. That forced rebase in Perforce has the very real possibility of causing breakages, and there is no way (at least in Perforce) to reliably handle it.
I also don't think history should be linear; the cheaper branching model in Git in my experience leads to people actually taking advantage of it; contrast this to Perforce, where branches were expensive: people wouldn't bother.
At least in the case of Perforce, the fact people didn't use branches forced them to put all of a feature into a changeset (Perforce's closest equivalent to a commit), which was usually way too much; this results in multiple, distinct changes being squashed together. The lack of cheap branches makes it hard to build a change off of two in-progress changesets, again because the system cannot efficiently represent that state.
And then there was just tooling: Git's add -p option for splitting off partial files into a separate commit, the ability to rework the convoluted history that came from my discovery of how best to implement something to something that encapsulates discrete changes that can later be reverted or cherrypicked gracefully (without reverting everything, unless that's really required) are to me, extremely useful tools that just don't exist elsewhere.
> Some admin does branching and merging and emails us if there are weird conflicts, we don't worry about that. Why make it more complicated?
(To be clear: this does not match my understanding of Perforce; branches there are possible without an admin.)
I just simply can't fathom why someone would want to have to go through another human for a branch. It seems like so much bureaucracy for something that, as Git shows, does not require it.
> why source control isn't a problem solved 100% by tooling in a way that requires little to no interaction at all. To them, hearing that they need to read a chapter about the internals of a source control system before working on a project
I think because, if we accept that history is not linear, and should not be represented as such, then history must therefore be represented as a DAG. A DAG, in my experience, is about the point where people start trying to cheat, for whatever reason, with incompatible and flawed mental models. This bites them in the ass at some point, and they can't understand what they're doing wrong within that flawed mental model, because the model itself is flawed. (And I see this all the time in software engineer, not just with Git. People are too quick to analogize permanently something to something else that is at best a crude approximation.)
Now, as another poster in the comments notes, I'd temper with the above with: some of git's tooling and UI could be better. The mix of "index"/"cache"/"staging area" to all mean the same thing, the variety of things "git reset" can do, etc. all are terrible UI on top of a superior model, but do contribute to the confusion newcomers experience. I hope some day this changes.