A lot of people simply don't understand 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 is like hearing they need to understand the details of how a transmission works before they go and drive an automatic - it's inane detail about a workflow they shouldn't even have to deal with because technology has solved the problem, or should have by now.
I was on a team that was forced to transition from TFS to git. Among those who weren't excited about it, the majority of the questions, challenges and issues weren't even as far down the road as how to use git, they were mostly along the lines of "why do we have to do all this other stuff now? Today I go to this screen, click this button, my work is now safe and other people can see it." History is linear, full stop, and conflicts are handled by essentially forcing a rebase on commit. 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?
These folks didn't need git tutorials, they needed to be convinced that curation and management of source history was one of their job responsibilities, which was tough because it really wasn't previously, at least not in any meaningful way.
> ... hearing they need to understand the details of how a transmission works before they go and drive an automatic
I feel like a much better metaphor is the difference between understanding that turning the steering wheel turns the car and understanding that turning the steering wheel turns the front wheels. You can drive a car without knowing that, but at some point you will find that not knowing that prevents you from having an intuitive grasp of things like parallel parking.
In software engineering, an even more apt analogy is understanding how compilers/interpreters work. You can do a lot of programming treating those as black boxes that make your program run, but eventually you have to have the deeper understanding.
Interestingly, it is really difficult to explain how the rudder doesn’t just change the boat’s direction when teaching sailing.
It especially happens after a student has just begun to understand that they can only move in some directions relative to the wind, and they feel stuck with the boat pointed straight into the wind. You have to move to change your heading, and you have to change your heading to move? The first reaction is to feel like the rudder is broken.
Additionally, being "stuck" pointing straight into the wind isn't a situation where you are stuck with zero velocity indefinitely. The wind is forcing you backwards, and the arrangement of the rudder and keel/centerboard is unstable for going backwards without changing direction. Even if you don't know what you are doing you'll generally point one way or the other enough that you can then fill your sails again and have more normal control.
Ways to make this faster include pushing the main sail on a small boat out to the "wrong" side, tightening the front sail on the "wrong" side of a larger boat, and positioning the rudder only a little off center so that the slowly moving water relative to the boat is less turbulent.
Probably the only time when it is an actual problem is when people are drifting into some obstacle. It seemed to take students a matter of seconds to regain control of their boat when they were surrounded by large expanses of water. When they were frantic, their intuition about what they needed to do when in a hurry prolonged their loss of control.
Those people have not worked on large enough teams; we had 50+ committers to an SVN repo before switching to Git, and it was very apparent where the limitations with that 'simple' workflow were.
I don't know how many committers have been on the average project I've worked on, but it's probably 25+, and I've worked on several with 50+ - and I don't know how you'd even make Git work at that sort of scale. Obviously people do actually do this, so I assume it must work somehow; I just don't see how it's going to work particularly well.
The larger projects I've worked on have typically used Perforce, but I used Alien Brain (which is pretty terrible) for some of the older ones. The check in/check out workflow, which is the same in each case, is basically what makes it all work once you get past a handful of people. Just simply being able to see who else is working on a (almost certainly perfectly cleanly mergeable) file that you're contemplating modifying is a big time-saver.
(I've used SVN, at a much smaller scale. It has similar Lock/Unlock functionality, which is a good start, but the performance in general of that seemed to be really bad. Locking a few hundred files might take a full minute, for example. Meanwhile, Perforce will check out 1.9 gazillion files in ten seconds, and that's only because it takes nine seconds to change NTFS permissions for that many files.)
> I don't know how many committers have been on the average project I've worked on, but it's probably 25+, and I've worked on several with 50+ - and I don't know how you'd even make Git work at that sort of scale.
Well, I actually don't understand how you can make it NOT work :) You obviously have to work with branches split per projects/sub-projects and different repositories for different apps. You have to find your branching model that works for you, it doesn't always works with a dev branch (we don't do that, we have bug, feature, release and master branches).
SVN is so out of this league that I don't even try to understand why people use it.
When you've got a lot of people, you've got a lot of changes - that's the long and the short of it. This is one thing the check in/check out model (as exemplified by Perforce, among others) is really good for managing. When you go to check out a file, you find out straight away if someone else has it checked out.
If you're just going to make a quick tweak, you'll probably risk it. Either they check it in first, and you've got a very minor merge, or you do it first, and they've got a similar minor merge. Not a big deal, in either case. (And when your gamble doesn't pan out, tough luck. No sympathy from anybody. You knew the risks.)
But, if you're going to make a very large, sweeping change, you'll probably be a bit more cautious. And that's fine: you can go over and talk to them, or message them, or email them, or whatever, to find out what they're doing, and coordinate your modifications appropriately.
I've literally never once found this less than somewhat useful. It's, like, the source control analogue of static typing: a huge pain in the arse if you're not used to it, but, if you've seen it play out, it's a mystery how anybody gets any work done in its absence.
(Of course, if you use git, maybe you can just email/Slack/etc. everybody on the team before you go to edit a file, just in case, and then wait for anybody to mail you back before proceeding... well, I don't deny that would work, assuming everybody checks their mails/Slack/etc. regularly enough. After all, I hear people get work done in dynamically typed languages too! But just think how much better things could be, if the version control system could look after this for you!)
I don't understand the hatred for perforce. It works really well. The times I need an offline branch to work on and keep history of commits are very rare.
I moved from git to perforce when I switched companies, and even though I actually really like git and consider myself reasonably proficient, I don't mind perforce.
My one real pain point with it isn't so bad, but I dislike how perforce tends to work at a file level instead of a commit level. It's hard for me to make several related changes which all touch the same files, like a series of patches which all refactor the same area of code, but which I would like to review and discuss separately, and potentially revert some/all of.
It's hard to manage this with shelves, because perforce can't handle unshelving the same file in two different CLs. I could submit all the changes to a separate stream, but perforce streams just don't usually work well for us, and it's still hard to experiment by constantly making and rolling back changes.
I guess I'm probably only used to this workflow because I have experience with git, but this is the time when I really miss the granularity of a git commit (and I'm doing a pretty gigantic refactor right now... so it's hitting me quite hard).
I recently had to do something similar with an ancient SVN repo, that had to stay in SVN.
I simply started a git repo in the same base directory as the SVN repo, and did my work in there. Every time I merged a branch back to master I committed to SVN's ^/branches/dev. Just add `.svn` to `.gitignore` and `.git*` to the SVN prop ignore.
You _will_ want to merge from upstream (Whatever Perforce's equivalent to `svn up` or `git pull` is) often, I was merging from upstream before every SVN commit (SVN mostly forces you to do this, `svn status --show-updates` is a huge help here but I don't know if Perforce has a similar feature).
same. i mean, it could be that perforce has great visual tools and people prefer complicated, esoteric cli tools. it has the perception of being more hardcore.
perforce's APIs are actually pretty good as well. they aren't documented that well, but they are easy enough to build some complicated tools with.
Hmm... I have to say the APIs and command line tooling is not where Perforce shines ;)
I found the APIs generally a disaster, and rapidly gave up on them. It was much easier to just run p4.exe and scrape the output. But... oh god. That's not saying much. The command line client was shit too. It eventually proved possible to get everything I wanted, but the data was never quite in the right format, the available queries were never quite suitable, and the results were never quite normalized enough. In the end I had to run p4.exe several times, discarding a lot of redundant data while doing this, and then cross-referencing the multiple sets of results afterwards to get what I wanted.
(One thing I had hopes for initially was p4's supposedly Python pickle-friendly output. But this was no good either! - since, from memory, p4 produces multiple pickles'-worth of data in one go, but Python will only read one pickle at a time, so you couldn't actually read it in from Python without a bit of work. Really made me wonder whether anybody actually tested any of this stuff. Really felt like the thing had been coded by a bunch of Martians, working from a description of the process made by people who'd never used Python and weren't even programmers in the first place.)
Sure but for me, even on a solo project git works so much better than svn because I can create multiple branches and easily rebase or merge them as needed.
When exploring ideas I might have 3 or 4 possible paths and it’s really nice to have the option of breaking them into different branches until I figure out the right path.
Oh, I agree - but I already know git fairly well. IME those people who have been using TFS solo for a decade have a much harder time seeing the benefits, because they're totally alien to the development workflow that they have become used to.
You don't even really have to be that many people on a project for some limitations to become apparent.
With TFS and SVN, it's already enough to have stable versions you need to backport fixes and the occasional feature to in order to end up in branching hell, for example.
> A lot of people simply don't understand why source control isn't a problem solved 100% by tooling in a way that requires little to no interaction at all.
This is true of basically all problem domains: "Why isn't X easy? Can't you just do Y?" And it usually just indicates that the person asking the question doesn't appreciate how difficult and nuanced a real solution to X is.
Real-world problems are often difficult and have non-obvious, sometimes-intractable challenges. "Easy" solutions often cause more problems than they solve — there's a reason why more complicated tools like git have taken over from less-capable tools like Subversion and CVS.
that can happen, but it can also serve as an excuse.
in git, for example, why can’t i switch branches with uncommitted changes? it makes no sense why i can’t do that, but yet, there it is.
> there’s a reason why more complicated tools like git have taken over from less-capable tools like Subversion and CVS.
i don’t think the reasons have much to do with usability or even capability. i came to git from perforce, where the latter was much easier to use, reason about, fix issues, and has much better tooling, in particular visual tools. it’s also amazing how slow git is.
> in git, for example, why can’t i switch branches with uncommitted changes? it makes no sense why i can’t do that, but yet, there it is.
Except you can?
[stouset:~/Development/some-project] some-branch(+8/-4)+ $ git status
On branch some-branch
Your branch is up to date with 'origin/some-branch'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: path/to/file1
modified: path/to/file2
no changes added to commit (use "git add" and/or "git commit -a")
[stouset:~/Development/some-project] some-branch(+8/-4)+ $ git checkout master
M path/to/file1
M path/to/file2
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
> i don’t think the reasons have much to do with usability or even capability. i came to git from perforce, where the latter was much easier to use, reason about, fix issues, and has much better tooling, in particular visual tools. it’s also amazing how slow git is.
Perforce isn't free. git's popular predecessors were.
That said, I've found in my experience that way more people seem to hate Perforce than seem to hate git.
You only can switch like that sometimes, and it would have been more intuitive if there was an implicit per-branch stash and stash pop when switching branches, which would always let you switch.
> in git, for example, why can’t i switch branches with uncommitted changes? it makes no sense why i can’t do that, but yet, there it is.
Because the working tree having uncommitted changes being blown away would be terrible data loss or a conflicting merge, so when that could happen, git prevents it.
Use `git stash` to stash your uncommitted changes before switching branches and you'll no longer have data loss.
If you want to apply those changes again use `git stash pop`.
If you don't want those changes use `git stash drop`.
Why isn't there a commandline option to checkout a branch and do a stash operation at the same time?
I think the implication is that switching branches shouldn't blow away your uncommitted changes. And one shouldn't have to stash their changes to switch branches.
> This is true of basically all problem domains: "Why isn't X easy? Can't you just do Y?" And it usually just indicates that the person asking the question doesn't appreciate how difficult and nuanced a real solution to X is.
Upvoted because this is so true, yet it is also only half the story -- let's call it the ignorant or lazy users half. The other half is the ignorant or lazy developer side: that is, developers who don't properly prioritize the 90% use case, and who don't appreciate or understand the natural mental models they should be accommodating and treating as problem constraints.
> they needed to be convinced that curation and management of source history was one of their job responsibilities, which was tough because it really wasn't previously, at least not in any meaningful way.
Getting people to be responsible for the whole is hard.
Similar experience here - I had a team of developers who had to move off of an internal TFS server to Bitbucket / git. I gave them all of the reference/doc links, gave them a brief overview about how git in fundamentally different than a centralized VCS. At the end of several sessions w/git (using git bash on Windows), their comment to me was: "But we're using to clicking on buttons in Visual Studio"
Visual Studio has a GUI for git, if your developers feel more comfortable that way, but in my limited experience I've had to help a few others who accidentally committed more files than they intended to using it, so the opaqueness of the GUI may be a disadvantage here.
The problem is even deeper than that, with a lot of IDE developers and particularly Visual Studio ones there entire world is in the IDE, anything outside of it may as well not exist, anything the IDE can't do is impossible. Many wouldn't even be able to compile there own projects if you took the IDE away.
An email I got the other day was "we can't debug problem with x because it's built on the CI server" and the problem was in the first few milliseconds of startup so "attach to process" was no good, even if they knew that was possible. The idea of using a debugger outside of the IDE (mdbg in this case) never crossed their mind.
IDE's a great for coding, but too many devs are way to reliant on them.
Why shouldn’t they be? Why should compiling a file or debugging a project require so much command line hackery? Why can’t IDEs actually do what they promised (integrate dev tools and make them more usable)?
It is so weird that in the 90s I could do MORE in my IDE than I can today, somehow our tools have trended to increasing complexity while IDE advancement has come almost to a stand still, with a preference to simpler less integrated ones (e.g. VS Code).
I used to feel the same way, especially as a VIM user. Why is every IDE worse than VIM, and why do I have to learn a new IDE for Python, C++, PHP, and Java?
Enter the Jetbrains IDE. The same basic program for almost every programming language and a terrific VIM plugin to boot. It's on the order of $100 per year. Well worth the cost, and the only non-FOSS code on my computer other than the MP3 codecs.
I usually don't use the built-in Git commands in PyCharm, but I do use the built-in terminal to perform Git operations. The only Git work I do with the IDE directly is resolve merge conflicts, because that specific tool is terrific.
I disagree that this is the case. I see it more as git is a DAG, and git's toolchain is simply a set of tools for manipulating the DAG.
It's not so much that git is a leaky abstraction as it is that git isn't an abstraction. If you don't know what a DAG is or how commits, files (e.g., blobs), trees, etc. are mapped into the DAG, of course you're going to have a hard time!
That's almost patently false, since `git checkout` is pretty much just a tool that takes a commit (or a name that points to a commit, like a branch or tag name) and updates the working tree, index, and the HEAD pointer to match the contents of the commit, with some extra safeguards to make sure uncommitted data isn't lost.
Three examples (that cover 95%+ of use-cases):
$ git checkout some-branch
> Updates the index and working tree to reflect the contents of `some-branch`, and updates the HEAD pointer to indicate we're on the `some-branch` branch.
$ git checkout -b some-branch
> Updates the index and working tree to reflect the contents of `some-branch`, with the "convenience" of creating it first through wrapping `git branch`. This is identical to calling `git branch some-branch; git checkout somebranch`.
> Updates the index and working tree to reflect the contents of the named file on the current or named branch/commit/tag/whatever.
TL;DR, `git checkout` has a very clear and well-defined responsibility: update the filesystem and index to reflect the contents of some commit. Various flags and options cause it to perform reasonable variations of this core responsibility (create a branch that doesn't exist first, or update individual files rather than the working tree as a whole). If the commit-name provide is a branch (and you're not checkout out individual files), it also updates the HEAD pointer to point to the named branch, so git "knows what branch you're on".
I would be absolutely astonished if you could write the git internals (or even just knew how they worked) and the idea of a tool to make the filesystem look like the internal contents of the repo wasn't immediately apparent. You might not have realized that that's all that `git checkout` does, but once you understand that, it's extremely straightforward.
So it always updates the HEAD pointer, except when it doesn't, and you give it the name of an existing branch that represents the commit to change your working tree into, except when you specify -bf to use the HEAD commit, and except when you specify -b and a branch name that doesn't exist. You can also specify start_point to use instead of HEAD.
So, the checked out commit is the second ref specified, or HEAD, unless the flags are such that you can only specify one ref.
Git checkout also "merges" uncommitted changes with your new HEAD, which you didn't mention and makes me wonder why the command isn't called "git merge".
I can forgive the '-b' creating a branch as a convenience. Having checkout perform safe operations by modifying HEAD when you pass a branch but destructive operations on the working tree when you pass a pathspec is too much. I appreciate your attempt to build a mental model for checkout, but I just don't find modifying HEAD and destructively overwriting working changes to be related operations.
I don't think leaky abstraction correctly describes the problem here, because the leaky thing (the fact that history is not linear, and multiple people edit the same files, and that everything is distributed) is not actually an abstraction. In my mind, Git forces you to deal with the fact that history is inherently nonlinear, and then you can choose to create a linear history by the way you use Git.
Git's main abstraction is the fact that everything is a content-addressable blob. This "leaks" but it's not a major contributor to the problems people have using Git, at least from what I've seen.
> In my mind, Git forces you to deal with the fact that history is inherently nonlinear, and then you can choose to create a linear history by the way you use Git.
That is not the problem with Git. Mercurial or Darcs also force you to deal with it all the same yet are not anywhere near the UI clusterfuck that Git is.
> This "leaks" but it's not a major contributor to the problems people have using Git, at least from what I've seen.
It absolutely is, because it leads to commands having unintuitive and incoherent behaviours and thus to the porcelain being impossible to model top-down.
Unless I'm misunderstanding, you seem to be saying that being a programmer implies having a desire to understand every program's internals. But I don't care how Photoshop stores the 30-layer document I'm editing, and I feel like I shouldn't have to. I can't see why Git should be treated differently.
That's a great question and I had to think a lot about how to answer it. I think there are 2 aspects to consider whether something is worth learning: relevance to your current skills, and use of the knowledge.
We insist, especially when hiring, that programmers know something about the internal design of other software that they use, but don't develop, on a day-to-day basis. Any programmer, depending on programming specialty, that doesn't have some idea about design of their operating system, networking stack, databases, or hardware would flunk out interview processes (and probably rightly so). The reason we insist on this specialized knowledge is because most of the time these things work fine, but when they don't the good software engineer proves their worth by being able to dig deeper.
Version control software is used just as frequently as any of this other software. But somehow there seems to be this feeling that it's not worth learning about and should just be a black box (I think package managers are treated similarly). Understanding git internals and design is a valuable software engineering lesson in and of itself.
The other aspect is having knowledge of Photoshop file formats is of limited utility unless you're an Adobe employee or Gimp developer (I don't know if the spec is open or not). Photoshop itself is closed-source and not so extensible or scriptable as an open-source command-line tool.
That's not true for git - knowing git internals reaps productivity benefits in your other work too. Treating it as a black box robs you of the knowledge to do some really cool stuff.
Broadly speaking this applies to any other software tool used by programmers - the more you know of its internal details, the more proficient you'll be in its use.
So in both respects (practical and from a learning standpoint) I think knowledge of git internals for a git-using programmer is a desirable thing.
While I mostly agree with you, I used linear VCS systems (mostly Perforce and SVN) for decades, and I still have no idea how they actually work. Git is fairly unique in that it basically forces you to understand how it works in order to use it, which I think is a major failing. I mean, it's nice that you can understand it and that that knowledge means that you can be more effective with it, but I don't think it should be compulsory. Currently it is compulsory for anything but the simplest workflows.
This doesn't seem specifically a linear vs distributed VCS thing, as much as it is a unique property of git. I previously used Mercurial, and at no point did I feel I had to understand how the VCS stores its commit graph in order to know what running some set of commands will do.
git is unique in its apparent assumption that it's nothing more than a series of convenience scripts that let you work on the raw filesysten representation a bit more easily. In a way it's more a filesystem-level representation of a DAG with some sugar on top, than it is a DVCS.
> This doesn't seem specifically a linear vs distributed VCS thing, as much as it is a unique property of git. I previously used Mercurial, and at no point did I feel I had to understand how the VCS stores its commit graph in order to know what running some set of commands will do.
Ditto. I've used Darcs, Mercurial and Bazaar, all are distributed, all have various levels of issues, but none of them required that I understand everything from the storage model up in order to actually get a grasp on them. I still have better intuition for Mercurial than Git (and long for a number of its features like GIVE ME FUCKING REVSETS ALREADY) despite not having seriously used Mercurial in years and having no idea whatsoever what goes under the CLI (and not caring a whit).
I think the argument would be that you need to understand what those 30 layers in Photoshop represent and how they interact with each other, not how they are stored.
Specializations exist because nobody can be an expert or even reasonably well informed about how everything works, even their own tools. I don't expect most professional engineers to understand the internals of their text editors or their compilers for that matter. Why should we expect it for something like a source control tool?
The reality is that in basically all profressional domains you are expected to be able to use, at a profressional level, the software required to do your job.
For developers that includes version control and package managers, amongst other things.
Do you need to know how git is implemented? Of course not. No more than you need to know how your compiler converts source code to executables.
...but understanding the basics of the tools (eg. what paths and layer groups are, to compare to photoshop), isn't something you can just wave your hands in the air and say 'not my problem'.
That isn't what I'm arguing; of course we must know how to use our tools. If that requires also understanding implementation details, even trivial ones (e.g., "it's a DAG"), or if the interface and words used to describe the usage are non-standard, awkward, or worse act to obscure what is actually going on, the tool and/or its documentation is poor.
For example: in this case, knowing what a branch is, how to create and delete one, and how to merge with one is necessary. Knowing that the branch identifier is a hash, called a "reference" or similar jargon and what that entails, internally, is superfluous and adds pointless complexity: if that's really required then git isn't good. I have more important things to think about as a developer than what internal machinery operates git.
The fact that commits are organized in a DAG is absolutely not an implementation detail. It's one of the core concepts of distributed version control.
It's also kind of silly to call git's terminology "non-standard". Git was the first truly widely used DVCS, so if anything, git's terminology is the standard terminology by definition.
> I have more important things to think about as a developer than what internal machinery operates git.
That could be extended to other tools like firewall configuration, TLS setup, library details, logging configuratoin, monitoring, etc. But you won't get very far in fixing any problems if you don't read documentation and investigate further.
But most of us aren't version control engineers; we just use version control as one of many tools in our toolbox. I think a more accurate analogy would be that a taxi driver doesn't need to understand how an engine works.
A taxi driver does not to know how an engine. But I'd be amazed if a professional race car driver didn't understand their car.
We all expect software engineers, regardless of specialization, to understand operating systems, networks, databases and hardware at a better-than-layman level. Try saying "that's just a tool in my toolbox, I don't care how it works" about one of those topics in an interview.
We're stretching the analogy a bit at this point, but assuming there are much fewer race car drivers than other driving professionals (taxi drivers, etc), wouldn't the professional race car driver be equivalent to something like the top 1% of software engineers? In which case, I agree, because I'd expect a software engineer paid in the top percentile to know (at least roughly) how all their tools work. But for everyone else, you can get really far in the industry without knowing how any of that stuff works under the hood (or at least not more than you have to for the work you do).
> Try saying "that's just a tool in my toolbox, I don't care how it works" about one of those topics in an interview.
I've met plenty of engineers who couldn't tell you how any of those things work at a low level, but still manage to maintain high-paying jobs. I've also had plenty of interviews where these topics never got brought up. Maybe that says more about hiring practices than anything else, but I think you're vastly overestimating the worth of that knowledge to most companies and individuals.
>I've met plenty of engineers who couldn't tell you how any of those things work at a low level, but still manage to maintain high-paying jobs. I've also had plenty of interviews where these topics never got brought up. Maybe that says more about hiring practices than anything else, but I think you're vastly overestimating the worth of that knowledge to most companies and individuals.
The question is also simply what you pay for and what is in a job description. To simplify, you have to pay a lot less for someone treating software solutions as blackboxes with known behavior then someone who understands what is done.
You can of course ask in an job interview about everything from compiler optimization to network intrusion detection to image processing, but you better should make sure that is actually what you need.
> To them, hearing that they need to read a chapter about the internals of a source control system before working on a project is like hearing they need to understand the details of how a transmission works before they go and drive an automatic
Shouldn't a mechanic have an understanding of how an automatic transmission works? Similarly, shouldn't a software developer have an understanding of how version control works? In general, a professional should have a very good understanding of the tools they use for their work as well as what they're working on.
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.
"These folks didn't need git tutorials, they needed to be convinced that curation and management of source history was one of their job responsibilities, which was tough because it really wasn't previously, at least not in any meaningful way."
I've had a very similar experience. IMO, your source control is an essential working tool, like your text editor, and you should be very proficient with it, but plenty of developers that I've met don't share that view.
I was on a team that was forced to transition from TFS to git. Among those who weren't excited about it, the majority of the questions, challenges and issues weren't even as far down the road as how to use git, they were mostly along the lines of "why do we have to do all this other stuff now? Today I go to this screen, click this button, my work is now safe and other people can see it." History is linear, full stop, and conflicts are handled by essentially forcing a rebase on commit. 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?
These folks didn't need git tutorials, they needed to be convinced that curation and management of source history was one of their job responsibilities, which was tough because it really wasn't previously, at least not in any meaningful way.