The Git index is the killer feature of git. Now obviously Git has many other things going for it, but I was searching for the real differences between Git and Mercurial and this appears to be the trump card of Git.
You may know that I am a fan of Mercurial, and have fought against the tides of Git. I had an excuse for every feature that people brought up as a "killer feature". I thought that git stash was a crappy version of a full on Quilt, like Mercurial Queues (hg q*). I thought that git rebase -i was a less featured hg transplant. Then Xentac brought up that git add -i was his favorite command. And so ensued a discussion on what a git index actually is, and how it affects your development. I shall now summarize what a git's index is, and how it makes you a happier developer.
Git has 3 places you can store changes: the working copy, the index, and the object database. The working copy is the files being tracked by your repository as they are in your filesystem. The object database is the place where tree objects (diffs/deltas/what have you) are stored when you type in git commit. The index is the middle ground. It is the "cache" or a temporary staging environment for the tree object of which you are about to commit.
What does this give you? It gives you completely non-linear development. A good example is that you are working on some new feature, and half way through you realize that you should refactor some completely unrelated function into two functions, for whatever reason. You could edit them now, but you're afraid both the feature and the refactor changes will appear in the patch you are going to send off. They are highly unrelated and you'd like them to be in two seperate commits. With git, this non-linear development is supported ( can we call it polynomial development? I'd like that. ). You can edit your index so that way the refactor is commited, and then edit again so the feature you were initially working on is in a seperate commit.
Nifty! But how do you actually do that index edit? git add -i to the rescue. Make your edits, then run git add -i. You will be prompted interactively to edit and change the index. When you are done, run git commit and be done! You have just prepared, and commited a tree object manually.
I will be migrating stuff over to git. Out of both popularity and features! The only thing I'm going to miss is plugins, but I'll live.. it's not like I wrote mercurial plugins all day.

2 months, 1 week ago
Couldn't you do justs the same with "hg commit <whatever-files>".
Don't see how you could make multiple patches to the very same file with git and commit then separated...
2 months, 1 week ago
Funny... sounds like branching. Why'd they have to go and make things so complicated?
The paragraph where you explain how to actually do this isn't specific enough that I would know how to do it; what are the "edits"? The refactoring or the new feature?
2 months, 1 week ago
Last time I checked, you could do exactly that with `hg record`, which is a mercurialization of `darcs record`: an interactive commit.
It does pretty much the same thing as `git add -i` followed by `git commit`, but in a single command.
2 months, 1 week ago
Meta-comment: the commands are practically unreadable in black-on-dark-grey.
2 months, 1 week ago
Tom: "They" didn't make it so complicated. You can ignore this feature if it freaks you out; in fact, it's not something generally advertised and most people would need to seek it out.
But if you need it... and if you're a serious developer, you could very well need it without realizing it... it's there.
Complicated needs sometimes required complicated tools. git-rebase -i is pretty complicated too, but when you need it, it is way less complicated than any alternative. And git's pretty good about having a solid, simple core that you can use if that's all you need. (One nice thing about command-line interfaces is that they tend to give you that feature for free; if anything, the advanced features are typically too well hidden.)
2 months, 1 week ago
I was just today trying to find a way to separate changes in mercurial in a similar manner to how I used changesets in perforce. I saw I could call hg commit <file_names> but what a pain to have to type in each and every file I want to check in.
A fix for this (IMO) would be to allow me to remove lines from the hg commit edit message that appears prior to the commit ... i.e. it would only check in those files listed beginning with HG: and would ignore files referenced by lines I removed.
Best case would allow me to package commits as atomic units in changesets just like perforce.
2 months, 1 week ago
me: no you can't.
> Don't see how you could make multiple patches to the very same file with git and commit then separated...
That's *exactly* what git add -a does. Make multiple patches to the very same file and make separate commits out of them.
2 months, 1 week ago
@James:
Being able to comment files out in the commit-file is a great idea :)
Maybe a bug should be filed for that.
2 months, 1 week ago
Sounds like the index is pretty much the same thing as Mercurial's mq.
2 months, 1 week ago
I never noticed git add -i before. Thanks. This will certainly eliminate some frustration.
2 months, 1 week ago
The killer feature for git is one that simulates branching, but in a way that makes it impossible for you to test that the branch you commit first works on its own. That's okay, though, because it's a command-line switch that you never have to use...
2 months, 1 week ago
I changed the code text to A _much_ lighter color... sorry about that. If you can't tell, I'm really not one for artful blog design.
As for hg record and darcs record... They have the same function as git add -i, but they don't give you fun stuff like git rebase -i, and the other index-fun tools of git. (unless I'm wrong.. again. Very possible.)
The killer feature as I see it is the index itself. The tools the are written with it are merely the product of having the index.
And hello reddit.
2 months, 1 week ago
I think 'git add -i' (and stash) are strict subsets of hg queues. They are two incongruous ways to control the atomicity of changesets.
Mercurial queues do both of those with one mechanism, and more. They also let you go back in time and add (amend) and remove, change the order of commits, etc.
Ideally you'd have the foresight to 'qnew' with the right atomicity to start with, but if not, there's a new 'qrecord' command, which does them same for patches in the queue as 'record' (mentioned above) does for commits to the repo.
Mercurial 1.0 next week!
2 months, 1 week ago
This sounds kind of like fast in-place branching, and it's something I've (mildly) wished for on other VC systems before.
But all the code I write is backed up with a ton of unit tests. If I tell git to commit only one change to a file, doesn't that mean I never actually had a complete working copy representing what I'm committing, and thus, I couldn't have run my unit tests?
If so, it sounds neat in theory, but something I'd never want to use on a production system.
2 months, 1 week ago
I think the built-in module "shelve" gives you something quite similar to this, doesn't it?
http://www.selenic.com/mercurial/wiki/in...
2 months, 1 week ago
too complicated.
2 months ago
Git UI is complicated by default, for no good reason.
Until commit -a (and related) are default, I prefer mercurial (and even SVN).
2 months ago
If you haven't tried "git gui" you might do so, it makes it very easy to pick and choose which files will be included in a particular commit. It doesn't allow you to change any file content, but you can alway edit the files outside of git gui then RESCAN.
If I understand correctly "Staged Changes" section is the current state of the index.
Comments are enabled
Comments must be approved by the administrator before they will be shown. Please be curteous, and write carefully, you have a whole preview page just to check up on it.
Post a comment