Why is git so hard? Is it that it encapsulates concepts that are inherently difficult to grasp? Or is it just that I need to think about things in a different way? I still feel after 5 years of git use that I am useless with it.
Have you tried spending some time learning how it works and reading through the manpages?
In my experience, as long as you hold onto the cognition that a repository is a collection of files and commits are, in effect, diffs, git won't ever really make sense, since none of what it does could be feasibly implemented with diffs. It's actually much simpler than that, hence the name.
When I first started learning git, I had only experience with SVN and Perforce. Both typically led to egregious practices (branches are directories?) and actual merges were rare (rather, you manually merged and just made a new commit). I felt they were a huge hindrance and were actually constantly in my way, a sort of mandatory bookkeeping I had to maintain.
When I started working for a company that heavily uses git, I buckled down and read through pro git (available at http://git-scm.com/book for free), the user guide (https://www.kernel.org/pub/software/scm/git/docs/user-manual...), and the man pages of the commands I was using. One day it just clicked and all made sense, and it was the only logical solution to SCM. Now I can't live without git. In my personal projects, step #1 is to git init a new repo. In working, git is never in my way, and rather provides me with incredibly powerful tools for massively increasing my productivity through workflows that just aren't possible under SVN/P4.
Because you're thinking about it wrong. They key to understanding git is to understand its data structures. Once you understand basically how it works, then all the wacky commands become shorthand for manipulating those data structures. It's really not a complicated system.
You don't really have to understand the data structures any more than in any other VCS.
If you're on Subversion and ignore that the repo is basically a counted list of big file trees with properties on the nodes, you won't get branching right.
If (FSM forbid) you're on MKS and ignore that it keeps per-file version histories somewhere in the belly of the expensive server, you'll try silly things like creating new files on a branch.
And for Git, you learn that there are commits, trees and refs.
> But why do I have to understand its data structures?
You don't. But if your mental model of how Git works is wrong – and if you came from another SCM system, it probably is – figuring out how Git actually works is the only way to fix it.
You don't have to if you don't want to. But it's by far the easiest way to understand things. It's not actually complicated.
The whole point of git is the weird database. I'd tell you to go use another system if you don't like it, but that's not really an option anymore. So I'd instead just suggest that you do yourself a favor and spend an hour learning about it; you'll be far more effective as a result.
You don't really have to understand its data structures to use it but, as with anything, having a more accurate mental model of the tool is a great help in figuring out how to achieve your specific aims.
That was the original value proposition made by Linus when he first create Git. This was largely out of necessity because it all happened over a very few short days in the panic of losing BitKeeper support for the Kernel.
However it is no longer true. Git is very much a SCM and is being developed as an independent tool, not just as a platform for tool development.
And still, Git, compared to most centralized VCSes, forces you to consciously design the versioning workflow. Where will the repositories be, who pushes where under what circumstances, what repo makes the golden releases, will you merge the upstream into feature branches or will you rebase, all that.
That makes it harder to introduce Git in an organization where nobody brings along enough Git experience to design all that upfront.
Looking into what you said, that is what happened.
I'd always heard that said about the tool we used today to point out "It does way too much for a single SCM, you have to find what YOU need a SCM to do and use that".
If you don't need anything that it's offering, fine, don't use it.
I need lots of branches amongst my team. I tried to use Perforce branching and I found out I was pounding nails into my eyeballs.
I'd be surprised if any of the other SCMs that can do what git does have significantly different models of behavior. I know Darcs is quite similar (though it can be a little smarter about merges sometimes).
The git model seems to not try to abstract away the details of the backend but rather give you tools and shortcuts to do common operations on it. As a result, the answer to "can I do this with git" is most often yes. But that comes at the added cost of having to know what's going on.
- Its user interface is inconsistent and poorly designed.
As I worked through this website (which is great by the way) it struck me that by focusing so clearly and completely on the underlying object graph that's supposed to lead to nirvana for learners, the site does a great job of highlighting the obtuseness of Git's command set.
I mean you've got a great honking big graph on the screen, another big honking graph to the side, and you're asked to "make this one look like that one". This should be so easy now that you see it - essentially drag and drop albeit with text commands - it should have almost no pedagogical value (if you built a model in Lego then it would literally be child's play). Yet even having identified what I needed to move and where I wanted to move it, the challenge remained - what is the weirdly named command I must type to make that (and only that) happen? Which way round are the arguments again? (eg. 'git rebase', to move stuff from the current branch to somewhere else, versus 'git merge', to 'move' stuff from somewhere else to the current branch, always gives me pause.)
I'm most grateful to this website for telling me about 'git branch -f <branch name> <destination>' as a way to repoint a ref. To think that all this time I thought you had to checkout the ref, reset --soft, then maybe checkout again if you wanted to get HEAD back to where it started (all the while dealing with the side effects and possible conflicts with your working directory). None of the tutorials or books I had read, such as "git for computer scientists", "Think Like a Git", or the "Pro Git" book ever mentioned (correct me if I'm wrong) that fairly fundamental operation despite schooling me quite thoroughly in the "think of the object graph" mindset. (Yeah it's in the man page, but then there's a lot of stuff in the manpage so noticing it is the problem there. And I tend to assume any option named "--force" is something that I shouldn't be messing with. Why not "git repoint-ref" or "git move-ref" anyway? Git has so many top-level commands already, it doesn't seem like they're worried about polluting that namespace.)
Indeed, in most small-medium project scenarios it may be an overkill.
But, if the people involved are proficient using it and the learning is not a issue, there is still git goodness to be used (or even dare I to say: to enjoy).
I find myself using A LOT of local branches while developing. Not only they are cheap to make/destroy, it's pretty flexible to manipulate it (ya, rebase).
When you are comfortable with things like staging, stashing, branching, rebasing, rebasing interactively, using -p (patch) in commands and reflog git enables you wonderful workflows (note the plural).
There is this gap between awkardness/frustation and power/enjoyment when using git. Tools like these help people jump it.
> It is an overkill for a small project with a central repository - what we usually have, leading to a large conceptual overhead.
I strongly disagree. All my projects use git and the majority of them are small with a central repository.
As someone who learned Git and SVN at the same time, I think git has an undeservedly bad reputation. There are many workflows where Git is much easier to grasp conceptually (initializing a new repo, branching, how do I work on an airplane?) I think people who are comfortable with SVN tend to forget that, other than the confusion around staging, it's easier for rank beginners to learn the basics of Git than the basics of SVN.
If for someone Git is too hard then Mercurial is a great choice. Better (safer, more powerful) than SVN and perhaps even - easier.
(Just now I am converting some scientific collaborators to use Mercurial for small projects. Still, for code I use Git... but mainly because of GitHub.)
Until a better way comes along, we still mostly develop software with code in a bunch of files. And we still mostly depend on the shitty filesystem for all that. That's what Git does. Frees me to some extent from the shitty filesystem.
Personally I think Git is always useful but I reap far, far more dividends on big projects where the forking, branching and merging give me support for software engineering as the social craft that it is.
I find that learning git oftentimes has to do with remembering how to do things, not understanding them.
Generally, Git can be summarized fairly easily, but when it comes to workflow, I think you just need the practice of doing it.
Branches and submodules make a bunch of sense, but I think it's deceptive and fruitless to describe the whole fetch-pull-rebase-reset business as something that's trivially simple and logical.
I don't know if those four followed from one flow of thinking, or whether they just co-exist as option for handling your project.
The Django Book is one of my favourite programming guides ever, because it describes why the different features and shortcut functions exist, which gives a flow (chart) to the tools available to you in Django.
With Git, I often just see a lot of users bickering over whether they should rebase, pull, and whatnot, and people start sounding like they just advocate their own workflow instead of a logic intrinsic to how Git was designed.
You can pick up monads in half a day (on the example of IO, List, Maybe, Reader, State), but learning git takes several days of reading books and docs and then months of practice.
Monads would also NOT bite your behind if you skip understanding the underlying theory. Git will.
I believe that for the most part we are trying to use git as a chainsaw.
The problems that we have run into usually stem from hand-jammed scripts that attempt to automate the process of creating release branches (hotfixes, etc). Not to mention the original workflow using git wasn't to actually use feature branches (either locally or remotely) and just use it like Subversion.
Since we've introduced the git-flow scripts this has become easier because we can "abstract away" all of those operations. But this really just moves the cheese because then a majority of your developers may not understand how and what to actually do if presented with a real issue with git.
In particular, the appendix on internal representations made everything make sense. Once you understand that commits form a DAG with a set (branches, tags, HEAD) of roots, it makes a lot of sense. Or so I thought.
"This talk is not for the Git beginner, but a more advanced look at "weird internals stuff" and obscure commands that will reveal a sort of internal API that is there for you to use and help expose you to certain intrinsic software design insights that can be had from looking at Git at this level."
Today people want continuous integration and continuous deployment. No branches, no local aggregation of different versions of essentially the same thing. Just check-in and check-out. For production code a CVS that makes you think (like Git) is the wrong CVS. When the Git hype abates programmers will hopefully re-invent simple and pragmatic approaches to version control.
Great job! I really loved LGB. One small complaint: level advanced2 could be solved with 3 commands instead of 5, if only you recognized the "--onto" option in "rebase" command :)
- commands on the right (to see them all the time and learn eventually), or example files in the folder,
- on the level-chooser - 'empty' for starting just with the command line (e.g. for level-building).
That is it implicitly assumes that someone knows what are branches, why to use them, when to use them (and when - not).
E.g. 'lightweight' as a feature, not - goal. Sure, this tutorial assumes some level... but if one is a master at branching, then one does not need to learn it from a graphical tutorial.
Awesome work! Would be neat to adapt this idea to show a realtime visual 'map' of a project as you're working on it. Watching your commits/merges as well as others' while they're happening could even be useful.
I'm noticing that the Merging in Git level (level 3?) gives you 6 steps to complete, but then complains that you didn't do it in 5. Is this a bug?
I like it, and I will use it. However, I'm finding all the slidedown / slideup animations distracting. I read fast, and just want to hit next until I can start typing. Other than that, I'll let you know when I play with it otnight.
Why is this posted and upvoted on to the front page at least 3-4 times a month? It's a great resource, but I don't think that warrants pushing other stories down as it resurfaces so frequently.
I agree -- I'd rather come back every ~6 months with big updates rather than have the link submitted constantly. I'm always planning to submit it myself when I reach a big milestone but someone always beats me to it... it gets a fair amount of organic traffic and Github switching to the .io domain for pages probably made it fall through the cracks of the HN submission map.
On the off-chance that you are not trolling: The site requires JavaScript.
On the on-chance that you are trolling:
You go to the repository and raise an issue regarding the fact that there is no obvious "This site requires JavaScript" message for those who access the site without JS.
It doesn't work for me in firefox on linux. But, works fine on chromium (although it requires more vertical real-estate than my 13" laptop screen has).
Great stuff there, I actually learnt from what I thought was an interactive tutorial for beginners. The commands (like 'reset' to go back to the beginning of a level) are not that straightforward from the beginning though. Also I haven't found how to actually see your solution yet (not that I have really searched for it, but it would be nice to have a big button).
Level 3 Intro - Create a branch, checkout, commit, checkout master, commit, merge. It says it can be done in five commands and I'm doing it in six (following the above steps very closely). What am I missing?
git checkout -b will make the branch and check it out at the same time.
You can always use "show solution" to see what we are using as the benchmark. Command discovery is a bit hard to communicate in this app -- I added the helper bar at the bottom for the most common commands but I only have so many pixels...
Oh really? Nice! Was it an academic setting or a professional one?
I am working on origin lessons right now (see link above) but I could actually make a file staging version if necessary. What other gaps of knowledge do you think it could fill?
Im actually going to use this in a presentation Im giving to my research lab as well. I tried to do something similar by drawing on the board but this is BY FAR one of, if not the, BEST tutorial I have ever seen. Actually seeing the images created and change in real time is worth 1 million words explaining them. Thank you so much!
I use it both for personal projects that will never have another human look at them, as well as for large multi-user projects.
In what was is it too complicated for most use cases? Most use cases involve "code being worked on by multiple people", in which case it has seen great success.