Hacker News new | ask | show | jobs
by dpcan 5104 days ago
NOTE: This is not a rant, I'm just trying to give you a peek into my mind as I tried out this tutorial. I'm doing my best to describe my confusion.

I have no clue how to use Git, and I've been trying to wrap my head around it for a while. Unfortunately, this is yet another tutorial that is very frustrating even though it's designed to target noobs like myself.

So, I added octocat.txt to my staging area. Success! ... Wait. Why do I care? What did I do? Staging what, for what? Huh?

I committed some random text. Or something. And I typed "-m". So does "git commit -m 'something random'" actually do something? What did I commit to? Arrrggg. Why did I -m !?

Then there's this one: git commi­t -m 'Add all the octoc­at txt files­'

So it understands plain English? Was that the random text? Is that just some sample text as part of the Tutorial or does that actually work on Git? Oh man, I'm now more confused than when I started.

...

Anyway, for some reason, everyone who tries to describe Git already has such a strong understanding of it and it's oddities, that they are, for some reason, unable to lay it out properly for a noob IMO. I cannot figure out how anyone figures out Git, I assume there was some serious hand holding, because I'm just not grasping it and I usually "get" this stuff rather quickly. Maybe that's the problem, Git isn't something you can just pick up quickly, maybe I need to buy a huge Git how-to book like the old days.

Sincerely, Frustrated in Programming Land.

26 comments

In a nutshell... a project can be described in terms of the changes a user makes over time.

In Git, these changes are called "commits".

Commits contain a change a user has made to the code and some additional useful metadata. This metadata includes the time the change was made, the user's name, a message to describe in general terms what the change was (that -m thing), and so on.

Git itself is a database that stores these commits. Each commit links back to the change before it, forming a chain.

If a single person is working on a project, this may be a linear chain of commits, but if multiple people are working on the same project, two people might make a change to the same text at the same time.

So maybe one person writes "The Nexus 7 costs £159", and another person writes "The Nexus 7 costs $199". If this happened, the chain would split; you'd have two valid changes made to the same text. The act of reconciling these chains is called a "merge". We might choose to use one version or the other, or to combine the two, such as "The Nexus 7 costs $199 (£159)".

That's basically it. The only other thing Git does is to allow you to give commits a human-readable name so you can refer back to them later.

Again, this is a gross oversimplification that describes only generic version control concepts and none of the powerful features that .

Go ahead and try explaining a rebase without trying to broach the concepts of time travel. How about why having a local copy of all commits/branches/etc related to the repository is helpful, or even at all possible, without relating it to a simpler client/server version control system.

Go ahead and try explaining a rebase without trying to broach the concepts of time travel.

A project can be described in terms of the changes users make over time, and that lets us undo any previous changes all the way back to the beginning of the project.

I don't think that explanation is overly technical or difficult to understand, and the generic features of version control which you dismiss are precisely those that make it most useful - the above paragraph in my opinion encapsulates most of what is useful about a VCS. To extend the above to cover a rebase:

A rebase is just merging other people's changes with yours, so that you end up with a merged version of the files, but with details that mean it looks slightly cleaner in histories - it's not even something many people will ever have to do. As to why having a local copy is useful, who cares, it's a detail of how the VC works?

This really is not rocket science - while git can at times be frustrating if you hit a particular problem which it doesn't consider important like expunging files from history, the basics are very very simple. You really only need 3 commands for day to day use:

  git pull (get other people's changes)
  git push (send your changes to others)
  git commit (commit a change to your local copy)
Actually for commit I just add all new non-ignored files (using an alias like this: "git add --all .;git commit -a -m") to save typing, otherwise I might have to use git add as well now and then, so I use commit "My message here". If the above commands are scary, there are various alternatives to VCS, but they're not as good - you can rename your files when you make a change, you can use something like Apple's Time Machine, etc. All of those work, but are not really as easy as VC when you're changing a lot of files.
The core concept of Git is simple. All its more complex features can be derived from the idea that Git is a database of commits (changes + metadata).

A rebase is the act of changing the parent, or base, of a commit. So instead of a change being made to version A, you make the same change to version B. No time travel metaphors need to be involved, and IMO only complicate a very simple concept.

The harder part is explaining why you'd want a rebase.

Anyway, for some reason, everyone who tries to describe Git already has such a strong understanding of it and it's oddities, that they are, for some reason, unable to lay it out properly for a noob IMO.

This is a common problem in teaching, technical writing, and other forms of technical instruction.

Even when a good teacher or writer sets out to deliver material to total beginners, it's very tricky to truly enter the beginner's mindset and cast away a lot of the mental abstractions built up over the years.

I think one way to improve this situation is to focus on results and casually use features and techniques along the way rather than focus on features and techniques and have contrived examples to show off them off. The fewer technical terms or domain specific language you can use up front, the better. (I should note I've been very guilty of the contrived example approach, but this is what it's all about.. experimenting and learning what really works for learners :-))

I think one way to improve this situation is to focus on results and casually use features and techniques along the way rather than focus on features and techniques and have contrived examples to show off them off.

Yes, exactly! You have to start with examples. Real problems and then suggest solutions. Too many teachers, I'd say the majority, start from the abstract explanation and only bring in the example in the end -if at all.

This isn't necessarily a problem. I can learn by immersion.

Good teaching shouldn't introduce too many concepts at one time, but giving incremental goals that require interacting with a few related concepts is ideal. Tediously spelling out all the details is good for a spec, but would hurt interest and motivation.

I sympathize. What is really necessary are not tutorials on how to use Git--it isn't that hard, after all, for most of us--but more of a description of actual workflow. Not HOW you issue Git commands; but how to use Git.

It would be interesting to read articles about how a single programmer uses Git, how a small programming team, how a distributed team uses Git. Similar articles about how a team producing art, or text (not programmers) use Git.

There's plenty of Git command tutorials already; let's hear about how you actually use Git.

I completely agree. If it helps, I wrote up some visual tutorials about version control in general that many have found helpful:

http://betterexplained.com/articles/intro-to-distributed-ver...

The idea is to build a mental model about what is possible vs. memorizing a bunch of specific commands. Once I wrapped my head around the concepts, the commands fell into place.

Looks good!

On my screen the text is light gray on white. Is that intentional?

Whoops! Thanks for the comment, the text should be a readable black on white (like this: https://skitch.com/kalidazad/er7an/intro-to-distributed-vers...).

Which browser were you using? (I just tried FF, Chrome, Safari) Thanks!

Thanks, really appreciate it!
Agreed. And not only for Git. For basically anything else in programming land you get to have either hands on quick guides or spec listing. There's serious shortage of good, moderately abstract, short overviews of what something actually does and how it does it.

Take Vim for instance. When I first got to it, I found only resources that are paraphrased with "this command does that. that command does that... nth command does that". Now, if only someone described buffers, tabs and windows to me (like in an article that was recently linked to here on HN), or told me that commands can be described as acronyms of verbs and nouns etc. I'd be much more proficient with Vim now.

For Node.js, I found some talks/presentations from its creator that really hit this spot.

I still haven't found anything like that for Git.

> For Node.js, I found some talks/presentations from its creator that really hit this spot.

Mind sharing the specific ones which worked for you?

> I still haven't found anything like that for Git.

I shared a nice conceptual tutorial about git in a reply in another comment of the same thread. Here it is, http://news.ycombinator.com/item?id=4200426

Sure. Sorry for not linking to any in the first place.

Here it is http://youtu.be/M-sc73Y-zQA. He got cocky later on, so I don't like very much his presentations of a later date. In this one, he's pretty nervous on occasions. It's cute. :)

I just glanced at the git tutorial provided - it seems it is up my alley. Will check it out later on.

Sometime back, I wrote about my initial Git workflow: http://veerasundar.com/blog/2011/06/git-tutorial-my-git-work...
Correction, what we need is both. Tutorials and a description of the workflow. The articles are all nice touches as-well. Knowing how my team could be more organized helps me want to try it out.

And just in-case I came across as an asshole, I liked your post and thought it was great :)

I figured out Git, and I'm not that clever, so don't worry!

The staging area (aka the index) is where you put things before they become a commit. You don't always want to commit all of your changes at once. The index is there so you can commit the changes you want instead of just committing all the changes every time.

`git commit` means "turn the contents of the index into a commit". A commit is a set of changes that logically go together denoting a version of the repository. A commit needs to have a message describing what the commit does. If you just type "git commit", it opens up an editor for you to type in your commit message. If you want to skip the editor, you can just pass in the -m flag, followed by your commit message in quotes.

Are you familiar with the shell? Are you comfortable with the concept of a linked list? If not, work on those--even if you don't use Git, it's part of being a better programmer. But if you do understand these things, you can fairly easily get a very deep understanding of Git.

That doesn't explain the fundamental part. Why is there a staging area in the first place?

Place yourself in the shoes of a subversion user, the workflow is very simple and intuitive given that:

  1. the repository is a (remote) place where my project is stored
  2. the local copy is where I modify my project
Then, a commit is just pushing your modifications to the repository where other people can go get them.

Now, with git you don't have a remote repository. Your local copy is itself a repository. Think about this for a second. Then...

If a commit doesn't push my changes to a remote repository, why do I care?

Well, if a commit allows me to have a local history of changes that I may not want to have in the remote repository, why do I need to stage my changes? Why don't I just commit them and be done with that? Isn't the files themselves a stagind area? Isn't this all redundant?

These are the problems a non-Git user faces. Why do I care about this complexity? In what whay does this make the process of making my changes accessible to others easier?

Answer: it doesn't.

Regular people are usually perfectly happy with their other VCS solutions. The ones that want them to see the light and start using Git for all its benefits must thing about what makes Git useful and explain that.

It doesn't matter that Git is important for large distributed projects. Most people aren't a part of large distributed projects.

No tutorial that I can remember does this. Not a single one.

> Why is there a staging area in the first place?

Because you don't always want to commit every change you've made or every new file you've added.

> If a commit doesn't push my changes to a remote repository, why do I care?

If I have my code in a working state, I'd like to save that "version" somewhere, so I can make a whole bunch of changes without worrying about whether or not I can get back to a working state. This is true even if no one else in the world has to read my code. This is the entire rationale of version control in the first place! But if I can do it just on my own individual changes, that means I can go back to a closer savepoint and not have to play the whole level over again if I screw up ;)

> Well, if a commit allows me to have a local history of changes that I may not want to have in the remote repository, why do I need to stage my changes? Why don't I just commit them and be done with that? Isn't the files themselves a stagind area? Isn't this all redundant?

No, because you still don't always want to commit every change you've made or every new file you've added!

Maybe you want to commit while you have Vim open but you don't want to add a bunch of garbage .swp files to your repo. Maybe you did two or three different things that aren't related, so you want them to show up as two or three different commits in the history.

From the perspective of a Subversion or Perforce user, it's not something you really think about because it's not even an option that you have. You effectively don't even have version control on your own machine. Your company has version control, but you don't. And in my personal experience as a Subversion or Perforce user, I frequently feel lost at sea in that environment because it's virtually impossible for me to reliably do things like:

1. Get back to a working state newer than the one I checked out of the repository after making lots of changes everywhere.

2. Make completely unrelated code changes at the same time without mixing the changes together. Maybe one change is blocking on a code review. Maybe I found an unrelated bug and want to fix it separately from whatever other changes I'm making. Maybe I'm second-guessing a certain feature addition and want to put it on ice while I do other things. Maybe someone reported a bug and I want to fix it separately from what I happen to be working on at the time. Whatever the reason, it can live in its own branch and I can come back to it later. I don't have to create duplicate workspaces in my file system, Git just manages it for me.

3. Turn a large, complicated code change into a series of smaller changes, each with its own diff and description which I can review more easily.

These are things I do every day. I would do them if I shared my code with a small team or with the entire world. I would do them if I shared my code with no one at all. Git isn't just for large distributed projects. It's for decoupling version control from version sharing or version verification.

In practice, the purpose of something like Subversion or Perforce isn't to help you as a programmer, it's to help the canonical owner of the code you're working on to do certain things, like rollback to past versions or make policies that your code has to pass code review or something before you can "check it in". Git handles all that too--some of it more effectively--and it has the added feature that even you the programmer can get the benefits of version control, too.

> No tutorial that I can remember does this. Not a single one.

The purpose of a tutorial is to help someone learn how to use Git. If you're not interested in learning how to use Git, why are you reading tutorials? It would be much easier to just start a flame war on Hacker News and wait for someone knowledgable to respond. I guess you figured that out yourself.

What disturbs me about that workflow is that your commits have literally never been tested because the staging area contents aren't accessible as a working copy. I for one am adamant about not littering my history with all my crap that didn't run, so I much prefer to commit the mixed work and then rewrite history to tease out and regress the independent changes. I pretty much always test and commit my workspace as-is, treating the staging area as an unfortunately visible implementation detail. It'd be easier if I could stash some but not all of my changes to get them out of my workspace temporarily, but this hasn't bugged me enough to figure out how to implement that.
> It'd be easier if I could stash some but not all of my changes to get them out of my workspace temporarily, but this hasn't bugged me enough to figure out how to implement that.

Here, let me help you, from the examples section of `git help stash`:

"Testing partial commits You can use git stash save --keep-index when you want to make two or more commits out of the changes in the work tree, and you want to test each change before committing:

               # ... hack hack hack ...
               $ git add --patch foo            # add just first part to the index
               $ git stash save --keep-index    # save all other changes to the stash
               $ edit/build/test first part
               $ git commit -m 'First part'     # commit fully tested change"
A nice thing about Git's Swiss army knife nature: someone else has likely run into most problems you encounter, and have added the solution to Git porcelain.
Thanks for the very genteel RTFM. I think you've pointed that out before, I just mischaracterized the process as quarantining the changes I don't want yet rather than rescuing the changes I do and forgot the mechanics.
> It'd be easier if I could stash some but not all of my changes to get them out of my workspace temporarily

It's literally called "git stash".

Aside from that, you can squash commits together after-the-fact. If it makes it any easier, you can squash a whole branch together all at once before pushing it out to other people. No one need be the wiser. The intermediate commits can just be temporary savepoints for your personal convenience.

The point isn't about me reading tutorials to learn Git.

The point is about convincing people to use Git by pointing them to tutorials and have them come back with blank stares and "why do I need this exactly?" questions.

I use Git for just my own projects, and it's just me. I barely use branches either, and I come from SVN.

I use TortoiseSVN, I'm not sure if you do. But when I want to commit in SVN, I bring up the commit tool, select the files I want to commit, write a message in the box, and click commit. But I have to do it all in one go. I can't close the commit window if I forget something, otherwise I have to make sure I copy out the message to paste in again, select all the files.

With Git, the staging area is the same as this commit box. It's just a bit more stretched out. Instead of selecting files to commit, and doing it then, you add files to the staging, and commit the staging area. It's a different way of doing it, but I've found it much better for myself. Instead of doing it all in one go, I can add to staging and keep working. Usually I keep open all the files that have changed so I remember which ones to add.

Regarding the remote repository, you still can have it remote. Simply instead of "commit" being the last action you do to push it to the remote repo, make sure "git push" is. I use bitbucket for this, so I know it's "safe" in case of computer death or something.

I have one more project using SVN and I want to move it to Git, for just me, I don't work in a team or anything like that. I like the staging area, it feels "lighter" and that commits are much less drastic, and diffs/logs are MUCH faster since it's all on your computer. Also, `git add -p` to craft your own commits.

There's a good reason that developers love git, it helps to organise code for _themselves_. Centralised VCSs are there to help you share your code with _other_ people.

Here's some problems I encounter everyday that git solves and SVN for instance doesn't.

1) I've been working on a feature since this morning but now there's a bug in production. I need to drop what I'm doing and come back to it when the bug is fixed.

2) I've implemented a feature but before I share it I want do some refactoring to clean it up. If I break something during the refactoring I want to be able to get back to the version that was working.

3) I'm working on integrating an old web API (SOAP hell) and I want to make a note of the workaround which is spread across several files. My tests aren't passing yet though so I don't want to share any code yet.

These are some examples of scenarios where git fits with _your_ workflow. This is where git really shines, not in the sharing of code (where it does also improve on SVN), but the ways in which it allows you to organise the pieces of code you're working on throughout your day.

Unfortunately you fell right into the trap he said everyone trying to explain Git does. The first paragraph is complete nonsense unless you already understand it.

You first call it a staging area and then you clarify with an "index," but you never clarify what an index is?! The second paragraph doesn't improve the situation much.

Ultimately I think there is a language breakdown here. People who explain Git seem to be unable to do so without using Git-language, and it is very difficult to understand the Git-language without understanding how it is used.

So therefore it is a chicken/egg problem. You somehow need to know the language to understand Git, but to understand the Git you need to understand the language.

PS - I know you're trying to help; it is just one of those things where I am not even sure it can be explained in that way.

I'm not saying it's an "index" to clarify what "staging area" means, I'm saying "index" is a synonym for "staging area" so if he runs into the word "index" somewhere, he knows it's just a different word for the same concept. For Christ's sake, there's nothing magic about the words, they're just names for something. If you didn't know what a dog was, and I said "a dog (aka a canine) is a domesticated animal related to a wolf", I'm not expecting the word "canine" to add anything to the explanation, I'm just throwing it in there in case you run into someone else who says "canine" instead of "dog", just so you know that in both cases they're referring to the same type of thing.

In any case, a staging area only makes sense in the context of trying to create a commit, and I think I did usefully define what a commit is. Maybe that part should have come first.

I suppose you have to know the general idea of a Version Control System (VCS) first before you can understand how Git does version control. I'll try my hand at it.

A Version Control System is a software system that uses files to save different versions of your source code (really, it can save any file, but it works best with source code). The system also lets you revert back to an old version of your code, so you can try something radical out on your code knowing that you have a safe version tucked away in your version control system.

A 'commit' is when you tell the VCS to take a "snapshot" of your files and then save that in its system. Git implements 'commits' with three-location system: the working index (the files on your computer), the staging index (Git's log of what files you want to change), and then the actual commit index (where all the versions are saved). When you stage a file, you tell Git to add the name of that file to it's internal log, telling Git that you want that file to be saved in a version. After you have told Git what files to save (by "staging" them), you can commit (with 'git commit') to save that snapshot of your staged files. Later on, you can revert to the snapshot through git commands.

Hope this helps!

See if the git parable helps:

Git is a simple, but extremely powerful system. Most people try to teach Git by demonstrating a few dozen commands and then yelling “tadaaaaa.” I believe this method is flawed. Such a treatment may leave you with the ability to use Git to perform simple tasks, but the Git commands will still feel like magical incantations. Doing anything out of the ordinary will be terrifying. Until you understand the concepts upon which Git is built, you’ll feel like a stranger in a foreign land.

The following parable will take you on a journey through the creation of a Git-like system from the ground up. Understanding the concepts presented here will be the most valuable thing you can do to prepare yourself to harness the full power of Git. The concepts themselves are quite simple, but allow for an amazing wealth of functionality to spring into existence. Read this parable all the way through and you should have very little trouble mastering the various Git commands and wielding the awesome power that Git makes available to you.

http://tom.preston-werner.com/2009/05/19/the-git-parable.htm...

I'm about half way through the Git Immersion tutorials [1], and so far it's been pretty good - clear explanations of what you're doing and why you should care.

[1] http://gitimmersion.com

+1 for this. Of all the tutorials I've tried, this was the one that sunk in the most.
The Pro Git book is relatively good. Ignore Chapter 1.

http://git-scm.com/book/en/Git-Basics

This is probably one of the easier tutorials out there.
Of all the basic version control intros/books, for me nothing beats Version Control by Example[1] book. It first explains the core concepts/commands behind version control such as create, commit, etc and them it goes on to illustrate how these commands actually implemented and used in practice using different version control systems.

The explanation is given for both centralized version control systems, using SVN, as well as for distributed version control systems, using Mercurial and Git (and Veracity).

Give it a try. The digital editions (PDF/EPUB/MOBI) are free for download I think.

[1] http://www.ericsink.com/vcbe/

Off-topic from the theme of your post, if you really want to learn about git, you could take the path that I did, which was to go by way of Mercurial (otherwise known as hg).

Hg is simpler than git in many ways. There's no "staging" for changes, so "commit" is just taking a snapshot of your files as they are right now. Simple.

And, since it's so simple, that means that you can write a really good tutorial for it, which Joel Spolsky did: http://hginit.com/01.html

Hg is plenty useful in its own right, and it doesn't really deserve to be training wheels for git as I've presented it here. But moving from hg to git is really easy; it makes git just seem like hg with a bunch more features.

Rather than these n00b tutorials, I recommend reading "Pro Git" by Scott Chacon, available for free here: http://git-scm.com/book

If you prefer a video, try "Getting Git" by Scott Chacon: http://vimeo.com/14629850

Coming from a Subversion & Perforce background, I was initially very confused by Git. There were two things that finally switched-on the old lightbulb for me:

a) Scott's book

b) Actively using Git for all of my personal projects (e.g. small school assignments and code experiments), without using a remote repository. If you defer learning about remote repositories for now, I'm sure the light will switch-on for you as well :)

b) glosses over what I've found to be one of the biggest brain-twisters in git - working with remotes.
Exactly: don't tackle remotes until you've learned the fundamentals of git, otherwise you'll be stuck with a big brain twister. If you start dealing with remotes right off the bat, like I initially did, you'll find git very frustrating and weird to work with. I kept treating git like it was svn, and just didn't get it. If you learn git without remotes first, the way git handles remotes will make way more sense to you once you finally explore that functionality.
> Maybe that's the problem, Git isn't something you can just pick up quickly

It is the problem, I think. Git isn't easy to use. It's a powerful tool designed by a very smart person (Linus) to manage a very complex project (the kernel). It's not a toy, and it's not designed for beginners. On top of that, the interface actually isn't that well designed, and is a pretty leaky abstraction layer that in many cases requires you to have some understanding of its internals [1]. But we're programmers, our work isn't always easy and the benefits of using Git or using any distributed version control system outweigh the alternatives (note that I'm not talking about Git vs Mercurial vs Darcs but rather about the previous generation of supposedly easier tools like SVN and CVS). So I really think it's worth struggling to master it and treat it like a first-class tool, that you're going to invest in because it's important, rather than try to find an easy way out.

I'm projecting on to you a little bit, and I apologize for that, but every time a Git tutorial hits the front page of HN, there are people expressing frustration or complaining that Git is too hard or too complex. Yeah, it's not perfect, but honestly, it's a damned good tool, and I think it's absolutely worth investing in. Most things worth learning are hard, and while that's not an excuse for poor tutorials (no comment on this one as I haven't tried it), I don't think programmers who take their profession seriously have much to excuse what seems like our almost constant desire for things to be easy.

Maybe the next generation of version control will be easier to use and have a more beautiful user interface, but Git is here now and there's an ecosystem around it supported by the network effects of its popularity, and I think that does end up outweighing the difficulty.

[1] That said, I think the inner core of its internals, ie representing revision history as a DAG of commits, is actually relatively simple, despite the poor interface. See this for what I think is one of the best intros to Git: http://ftp.newartisans.com/pub/git.from.bottom.up.pdf

Sounds like a false dilemma. Mercurial is here now, is powerful enough for a majority of users, is easy to use, and has an introductory book as well. After reading it and Spolsky's site, I picked it up in a few hours.

I think git is a good fit for people who find version control theory interesting, a endeavor in itself, or have complex workflows. For the rest of us, who simply need to work together (sometimes offline) with multiple synced backups, the complexity of git is too much.

Hg, for its flaws, keeps the simple things simple. I think the constant push from above to use git is a disservice, and I wonder if there will be a backlash at some point.

I specifically wasn't comparing Git to Mercurial, and noted so in my comment, mostly because I don't have any real experience with it. It certainly might be easier to use than Git, I don't actually know. I also don't know how many people who bemoan Git's complexity and learning curve have tried Mercurial, or even used any version control, and how many are migrating from SVN or CVS.
I use them both and I can say that Mercurial is way easier to learn and use than Git. Obviously, Mercurial has less features but, is there currently any DVCS system that has more features than Git?

The funny thing about Mercurial and Git is that they build on top of the same core concepts:

http://mercurial.selenic.com/wiki/GitConcepts

hg is leaps and bounds simpler than git. I came from a long svn background and picked up hg in about a day.

hg to git took several weeks, and I'm still learning.

I prefer git's handling of branches; hg never deletes a branch, just "closes" it, so you're left with a lot of mess if you do a great deal of branching. Other than that, I prefer hg.

the best way to learn Git is simply to be forced to use it. and even then you only learn subset you actually need to get the job done but at least it's something to get you started.

I'm not going to post link to yet another git tutorial. I would rather recommend to start with something like Heroku, Appharbor or similar.

I find by far the best way to learn git is actually walking through it with someone who knows, and asking absolutely every question that comes to your mind--force them to break it down. Email me at mrjordangoldstein@gmail.com if you want to set up a Skype chat/screenshare sometime, I'd love to teach you. It wasn't that much long ago I was in your shoes!

P.S. And the only way to get better with it after you learn is to use it everywhere. Which is a good idea anyway, because version control is incredibly useful.

I know how you feel. I was working on a very basic project and since i had some hand-holding i used git to publish the code to github, but now the hand-holding has stopped (my mentor doesnt have time to help me) and i'm no longer pushing to Github (dont want to make all my code open source).

It was too much of a learning curve to figure out how to deal with this change where Git was concerned, so i went back to mercurial which has a windows client and is easy enough to get my head round.

I do think that Git is probably more powerful as i see it in much more use in production out there, and at a guess i imagine that for version control it's probably more dependable and reliable than Mercurial - im not really qualified to say - but right now, i'm sticking to mercurial because at least i can wrap my head around it, and that's what matters, for now.

You're right. I'm halfway from git noob to power user. My problem with git is that everything is named badly. index, staging, head, ref, reset, rebase, pull, fetch, merge, all of it could have been named better. The commands could have better arguments. And you're right about most tutorials. They only make sense if you already know git.

These are pretty good. It's when I saw these that I realized everything in git is named poorly:

http://marklodato.github.com/visual-git-guide/index-en.html http://ndpsoftware.com/git-cheatsheet.html

> Anyway, for some reason, everyone who tries to describe Git already has such a strong understanding of it and it's oddities, that they are, for some reason, unable to lay it out properly for a noob IMO

I for one had a really hard time grasping Git, until I wiped my VC-mindset slate clean, it was primarily my upbringing in a development environment where Centralized Version Control was the king. I read up on Eric Sink's Version Control By Example. It's a great book to lay-out the fundamentals of Git. If you wrap yourself around the concept and not the tool, the use of tools (Git commandlines, Git GUI's) will come naturally.

I can empathize, been in a similar situation myself. Most of the git tutorials out there have a problem that they don't explain much of the 'why' and just tell about the 'how'. They are telling mostly about commands and not about the concepts behind it.

Some guy at Harvard wrote a great tutorial[1] on understanding git conceptually. It has been on of the best git tutorials I have read myself.

[1] Understand Git Conceptually - http://www.eecs.harvard.edu/~cduan/technical/git/

There is also "Think Like a Git" (http://think-like-a-git.net/), "The Git Cheatsheet" (http://ndpsoftware.com/git-cheatsheet.html) and "Git, the simple guide" (http://rogerdudler.github.com/git-guide/). This might just be piling on to your 'yet another tutorial' list but maybe one of these will help it click for you.
I liked http://gitref.org when I started with git. I find it's a good quick reference to common git commands so you can quickly get up and running with git. The rest of learning git is really just practice and searching for how to do stuff when you need to.

The section on commit explains what the '-m' option is:http://gitref.org/basic/#commit

It's pretty clear that this tutorial expects you to already have some experience with concepts in revision control. However, the problem is that if you're already experienced in revision control, you would probably find this tutorial a little simplistic and condescending.

Basically, git has a steep learning curve and people haven't found a good way to flatten it out a bit.

The svn book, (and I believe the hg) spends a number of chapters explaining how version control works. It will also give you some background on how things were, and where they're going. If the git docs don't do a good enough job, I suggest you read/skim the introductory chapters of these two free books.
This is the best intro I've read to get the concepts of distributed version control: http://hginit.com/

It's specific to Mercurial, but git is very similar. If it's the overall concepts that are giving you trouble, that should be effective in removing those blocks.

It sounds like the problem isn't git itself, but the concept of source control in general, which is pretty abstract until you actually dig into a source-controlled project that has other people committing - after that, the understanding comes pretty naturally.
The tutorial definitely glosses over some information that you would need to research later on.

For a more in-depth guide, check out the Pro Git book @ http://git-scm.com/book. You can read it online for free.

Yeah, it should certainly start with some intro explaining the idea of VC and defining words like commit or repo.
Perhaps what's missing in Git is a good metaphor.