That “It’s really pretty simple, just think of …” tooltip totally kills me. I wonder why git seems so obvious in retrospect, but so daunting to the newcomer. Is it the unpredictable commands?
Kind of reminds me of learning to pay attention to state in codebases. Once you catch on to the unwieldyness of variables with too wide of a scope (e.g. globals) it leaps out of the page in less well written code.
If you were going to do a 10 minute git intro focusing only on the data structure used by git and none of the arbitrary command interface, what would you cover?
That’s really nearly everything. Then to actually use it, you map manipulation of the above into commands, which is not as straightforward as it perhaps should be but is also not as difficult as I think people make it out to be (commit, reset, branch and rebase hit probably more than 95% of uses).
I would call it the “staging area” (just seems less confusing to me) and while it’s essential to use, from the user perspective it’s mostly a technical detail of git commit. Advanced use of the staging area, while very powerful, is not integral to advanced use of git.
(As an aside, the lack of a staging area is one of the things I really miss when using Mercurial, especially since it gets a half-assed accidental partial implementation by not automatically tracking new files anyway.)
The commands are certainly the stumbling block in my case. I get along fine with Mercurial, and I used Monotone before that. I have no problems conceptualizing a DAG. But the Git command line just doesn’t agree with my tastes.
Emacs is weird for modern users, but it’s consistent with itself and natural for the early 1980s. A frame is always a frame, a buffer is always a buffer. This hasn’t changed in over three decades of Emacs' existence. The world around Emacs changes, but Emacs fundamentals remain immutable.
Git is not consistent with itself. Over the years, they couldn’t make up their mind if it should be called a cache, an index, or a staging area. Thus, there are vestigial remnants of --cached or --staged in git diff, but the manpages usually call it an “index”. They couldn’t decide if interactivity should be done with --patch or --interactive, so git add and git rebase flip/flop between that. The help system is all over the place with git -h foo, git help foo, git foo --help and git foo -h all doing slightly weird and inconsistent things. The famous git koans contain more examples.
The git UI is about as intelligently designed as a human body full of appendices, blind spots in the retina, and fragile knees.
The commands are arbitrary, and not very uniform, or predictable, that’s true. But the backing data structures feel natural now. I’m fine with looking at it as New Jersey design, it fits that mold.
I used to use the command-line wrapper Easy Git to fix inconsistencies in Git like the ones you mention. Easy Git changes commands, flags, and documentation to refer to concepts consistently. For example, it has eg stage and eg unstage commands, and extra documentation like eg help topic staging. It also has usability improvements like telling you in eg status when a rebase is in progress.
Sadly, the version of Easy Git on its website has not been updated in a long time, and some commands no longer work with the latest version of Git – most notably eg status. But I’ve just discovered a mirror of a more-recent version that may be usable.
Where it more often rubs me the wrong way is when the problem wasn’t very hard to begin with, but is now annoyingly complex because of git (or sometimes, because of some other infrastructure’s specific way of using git).
The traditional way to send in a smallish patch to an open-source project: edit some files, run ‘diff’, mail the patch. This is pretty easy for me to do. And most projects, unlike the Linux kernel, move pretty slowly and don’t have a ton of concurrent development, so issues with patch-tracking and branches are uncommon.
But now many projects (even those slow-moving ones) want contributions through git, which requires a whole song-and-dance around cloning repositories and upstream masters and local branches and pull requests… all for a 5-line patch! The song-and-dance gets even worse with the project-management stuff people have put on top of it. Github isn’t that fun to begin with, but hardly the worst… my least favorite experience was probably making a 2-line bugfix to Mediawiki, which required not only dealing with git’s nonsense, but also with gerrit’s nonsense. I’d estimate I spent about 20 minutes tracking down the bug, 2 minutes fixing it, and an hour figuring out how to submit the patch.
Github seems to recognize the process is really heavyweight for small changes, so they’ve made it possible to edit projects without dealing with git at all, if you’re doing very small changes: just click “edit” in the web interface, and the whole clone/branch/commit/pull-request circus is hidden behind the scenes. I’ve used this a few times and it was a much nicer experience than the verbose way of doing it. Maybe they’ll expand this to handle more cases, which would mitigate the issue.
IMO, the format-patch workflow is under-appreciated. It requires no more infrastructure than a channel of communication and already integrates well with git (as one should expect, since Linux works that way and git was explicitly written to serve Linux’s needs).
This is quite similar to how I’ve taken to teaching Git to people. Start with a very practical introduction that provides real-world justifications for each of the major features (staging, commits, remote repositories, branches, forks/clones, merging).
Of course, you then follow that up with an explanation of how git works internally (what HEAD is, really, what the reflog is, and so on). Then some challenges after that, to make sure they understand things like the difference between merging and rebasing, how the Git garbage collector works, etc.
I have seen very few people who actually understand what HEAD is. Almost universally people think it means “newest” or “latest” instead of simply meaning the currently checked-out commit. You are always at HEAD, because by definition HEAD is wherever you are.
Worse, people often talk about the remote HEAD, whereas most remotes are bare repos with no HEAD at all. Example: homebrew has a --head option to pick up the latest master branch of a repo.
This confusion stems from a bad name. Git was aping CVSish langauge here, I think, but used the “head” concept to refer to something almost completely different.
That’s a really interesting perspective. Is it fundamentally impossible to hire / train 2.5k engineers smart enough to use Git well? It seems to me as if the root problem here is hiring “mediocre” engineers, although I would label someone who force pushes to resolve a merge conflict or doesn’t understand feature branching less-than-mediocre…
The entire attitude around Git very much revolves around the tool as an opportunity to show you’re smart. But once you remove that context, it’s just a tool, a side tool to help you do your main job, which usually writing code. Some engineers might have to an incentive to very involved with version control due to their position in the company but I suspect many will view version control as one more chore and thus their tendency not to learn more than the minimum doesn’t seem like lack of intelligence to me. If anything, I sympathize.
I think “cargo cult these commands” is a learning phase of git. Most people I know went through it, and slowly begin to grok how it’s all put together. I guess some people never graduate from that stage.
Switching an entire team of folks to using the forking model at Cisco last summer was really fun to explain. I learned more about Git by explaining the same ideas over and over again versus reading the manpages multiple times.
The comic implies that Git is stupid because it is complex. If anything complex is stupid, then that means stupid includes things like Google, databases, and operating system kernels (especially any that are security-conscious).
We use mercurial at work. It has less knobs to turn which makes things slightly easier, but the workflow is largely the same as when I use git: add things to a commit, commit it, and push/pull from the central authority. I can do more, but I rarely do.
I don’t care who you are, it’s not OK to brag about your own ignorance. If you don’t understand something, study it. That’s how most of us got here, not by doing funny drawings and leeching on a culture we don’t actually understand.
It’s probably worth exploring the reasons why so many people are ignorant, however. Or perhaps consider “go study it until you understand” may be off putting advice.
We’re all ignorant in various areas, for various reasons, but it’s not acceptable to brag about it. We are defined as a species by our thirst for knowledge, not by a devil-may-care attitude when faced with the unknown.
I’m quite surprised no one has mentioned The tale of Three trees in my experience most of the devs that struggle with git are the ones who don’t get what head, index and work mean then bang their heads trying to understand why “the file didn’t get pushed.”.
I wish git included a gittutor command to go over these fundamental concepts.
That “It’s really pretty simple, just think of …” tooltip totally kills me. I wonder why git seems so obvious in retrospect, but so daunting to the newcomer. Is it the unpredictable commands?
Kind of reminds me of learning to pay attention to state in codebases. Once you catch on to the unwieldyness of variables with too wide of a scope (e.g. globals) it leaps out of the page in less well written code.
If you were going to do a 10 minute git intro focusing only on the data structure used by git and none of the arbitrary command interface, what would you cover?
That’s really nearly everything. Then to actually use it, you map manipulation of the above into commands, which is not as straightforward as it perhaps should be but is also not as difficult as I think people make it out to be (
commit
,reset
,branch
andrebase
hit probably more than 95% of uses).You forgot the index, it’s not really part of the storage model but using it is essential to using git.
I would call it the “staging area” (just seems less confusing to me) and while it’s essential to use, from the user perspective it’s mostly a technical detail of
git commit
. Advanced use of the staging area, while very powerful, is not integral to advanced use of git.(As an aside, the lack of a staging area is one of the things I really miss when using Mercurial, especially since it gets a half-assed accidental partial implementation by not automatically tracking new files anyway.)
The commands are certainly the stumbling block in my case. I get along fine with Mercurial, and I used Monotone before that. I have no problems conceptualizing a DAG. But the Git command line just doesn’t agree with my tastes.
I think it’s a combination of a terrible UI on top of tools for grappling with an actual hard problem. Me, I just let magit handle the nastiness.
And now you replaced the nastiness with Emacs, which is itself another set of nasty.
Well, right. But I have 25 years of Emacs muscle memory.
Emacs is weird for modern users, but it’s consistent with itself and natural for the early 1980s. A frame is always a frame, a buffer is always a buffer. This hasn’t changed in over three decades of Emacs' existence. The world around Emacs changes, but Emacs fundamentals remain immutable.
Git is not consistent with itself. Over the years, they couldn’t make up their mind if it should be called a cache, an index, or a staging area. Thus, there are vestigial remnants of
--cached
or--staged
ingit diff
, but the manpages usually call it an “index”. They couldn’t decide if interactivity should be done with--patch
or--interactive
, sogit add
andgit rebase
flip/flop between that. The help system is all over the place withgit -h foo
,git help foo
,git foo --help
andgit foo -h
all doing slightly weird and inconsistent things. The famous git koans contain more examples.The git UI is about as intelligently designed as a human body full of appendices, blind spots in the retina, and fragile knees.
The commands are arbitrary, and not very uniform, or predictable, that’s true. But the backing data structures feel natural now. I’m fine with looking at it as New Jersey design, it fits that mold.
I used to use the command-line wrapper Easy Git to fix inconsistencies in Git like the ones you mention. Easy Git changes commands, flags, and documentation to refer to concepts consistently. For example, it has
eg stage
andeg unstage
commands, and extra documentation likeeg help topic staging
. It also has usability improvements like telling you ineg status
when a rebase is in progress.Sadly, the version of Easy Git on its website has not been updated in a long time, and some commands no longer work with the latest version of Git – most notably
eg status
. But I’ve just discovered a mirror of a more-recent version that may be usable.When I have to interact with git repos, Mercurial is my improved UI wrapper.
Where it more often rubs me the wrong way is when the problem wasn’t very hard to begin with, but is now annoyingly complex because of git (or sometimes, because of some other infrastructure’s specific way of using git).
The traditional way to send in a smallish patch to an open-source project: edit some files, run ‘diff’, mail the patch. This is pretty easy for me to do. And most projects, unlike the Linux kernel, move pretty slowly and don’t have a ton of concurrent development, so issues with patch-tracking and branches are uncommon.
But now many projects (even those slow-moving ones) want contributions through git, which requires a whole song-and-dance around cloning repositories and upstream masters and local branches and pull requests… all for a 5-line patch! The song-and-dance gets even worse with the project-management stuff people have put on top of it. Github isn’t that fun to begin with, but hardly the worst… my least favorite experience was probably making a 2-line bugfix to Mediawiki, which required not only dealing with git’s nonsense, but also with gerrit’s nonsense. I’d estimate I spent about 20 minutes tracking down the bug, 2 minutes fixing it, and an hour figuring out how to submit the patch.
Github seems to recognize the process is really heavyweight for small changes, so they’ve made it possible to edit projects without dealing with git at all, if you’re doing very small changes: just click “edit” in the web interface, and the whole clone/branch/commit/pull-request circus is hidden behind the scenes. I’ve used this a few times and it was a much nicer experience than the verbose way of doing it. Maybe they’ll expand this to handle more cases, which would mitigate the issue.
IMO, the format-patch workflow is under-appreciated. It requires no more infrastructure than a channel of communication and already integrates well with git (as one should expect, since Linux works that way and git was explicitly written to serve Linux’s needs).
I would draw pretty trees on a whiteboard and repeatedly say “GIT!”
I use Git, but fully admit I probably have no clue how to actually use Git.
Funny, that.
Git-it Guide was probably the best plain, clear English tutorial I used to learn git, as well as some aspects of GitHub.
But it’s not inside out or bottom up, the only approved ways of learning git.
This is quite similar to how I’ve taken to teaching Git to people. Start with a very practical introduction that provides real-world justifications for each of the major features (staging, commits, remote repositories, branches, forks/clones, merging).
Of course, you then follow that up with an explanation of how git works internally (what HEAD is, really, what the reflog is, and so on). Then some challenges after that, to make sure they understand things like the difference between merging and rebasing, how the Git garbage collector works, etc.
I have seen very few people who actually understand what HEAD is. Almost universally people think it means “newest” or “latest” instead of simply meaning the currently checked-out commit. You are always at HEAD, because by definition HEAD is wherever you are.
Worse, people often talk about the remote HEAD, whereas most remotes are bare repos with no HEAD at all. Example: homebrew has a
--head
option to pick up the latest master branch of a repo.This confusion stems from a bad name. Git was aping CVSish langauge here, I think, but used the “head” concept to refer to something almost completely different.
[Comment removed by author]
That’s a really interesting perspective. Is it fundamentally impossible to hire / train 2.5k engineers smart enough to use Git well? It seems to me as if the root problem here is hiring “mediocre” engineers, although I would label someone who force pushes to resolve a merge conflict or doesn’t understand feature branching less-than-mediocre…
[Comment removed by author]
Yeah,
The entire attitude around Git very much revolves around the tool as an opportunity to show you’re smart. But once you remove that context, it’s just a tool, a side tool to help you do your main job, which usually writing code. Some engineers might have to an incentive to very involved with version control due to their position in the company but I suspect many will view version control as one more chore and thus their tendency not to learn more than the minimum doesn’t seem like lack of intelligence to me. If anything, I sympathize.
I think “cargo cult these commands” is a learning phase of git. Most people I know went through it, and slowly begin to grok how it’s all put together. I guess some people never graduate from that stage.
git is just a brane that maps commits to distributed merge-points http://tartley.com/wp-content/uploads/2010/12/I1546manifold.png
Switching an entire team of folks to using the forking model at Cisco last summer was really fun to explain. I learned more about Git by explaining the same ideas over and over again versus reading the manpages multiple times.
Google has some ridiculous amount of code, say ten million lines.
I imagine it is difficult to wrap one’s brain around so much that is so complicated.
Does that mean that Google is stupid?
I’m not sure what your point is. Everybody I know knows how to use google. Nobody complains (for serious) that googling is too hard.
I meant the software behind Google.
The comic implies that Git is stupid because it is complex. If anything complex is stupid, then that means stupid includes things like Google, databases, and operating system kernels (especially any that are security-conscious).
It gives me hope for Mercurial that people are still making this commentary despite git’s dominance. La Résistance Mercurialaise lives on!
We use mercurial at work. It has less knobs to turn which makes things slightly easier, but the workflow is largely the same as when I use git: add things to a commit, commit it, and push/pull from the central authority. I can do more, but I rarely do.
I don’t care who you are, it’s not OK to brag about your own ignorance. If you don’t understand something, study it. That’s how most of us got here, not by doing funny drawings and leeching on a culture we don’t actually understand.
It’s probably worth exploring the reasons why so many people are ignorant, however. Or perhaps consider “go study it until you understand” may be off putting advice.
We’re all ignorant in various areas, for various reasons, but it’s not acceptable to brag about it. We are defined as a species by our thirst for knowledge, not by a devil-may-care attitude when faced with the unknown.
I don’t think xkcd is autobiographic.
I’m quite surprised no one has mentioned The tale of Three trees in my experience most of the devs that struggle with git are the ones who don’t get what head, index and work mean then bang their heads trying to understand why “the file didn’t get pushed.”.
I wish git included a gittutor command to go over these fundamental concepts.