Search code examples
gitmercurialtortoisehgstaging

What is git staging and why does Hg *ostensibly* not support it?


The Hg docs state that hg doesn't support an equivalent to git's index out of the box and suggests using extensions (record or mq) for similar behaviour.

First, I have very little field experience with git, so let me state my understanding of the concept of staging in git:

  • There's the working copy, containing a number of changed files, each having a number of changed chunks.
  • The user then (maybe repeatedly) uses git add to select which files will be committed.
  • Alternatively, use git add -p to select only some of the chunks in a file to later be committed.
  • Do a git commit to add the previously selected changes to the repository.

So the whole staging area, to me, is a pompous name for a selection of which of the changes in the working copy will make it in the next commit.

If I'm not completely off on that, then, why does everyone, including the official documentation, state that Mercurial does not support this?

I'm asking, because the exact workflow above is trivial in TortoiseHg:

enter image description here

  • in the left pane - select whole files to include in the commit
  • in the right bottom pane - select single chunks to include
  • hit 'Commit'.

I don't know what hg commands TortoiseHg uses, but then again, I never needed to care. (It doesn't make use of any extension for this AFAICT)

Is there more to the git concept of staging that I'm missing?


Solution

  • The staging area (index) records change snapshots, not just a selection of files. For instance, you can modify file A to add foo, stage file A, then modify file A again to add bar. If you don't re-stage file A, then when you commit, only foo will be committed, because the index has the snapshot of A when it was staged.

    You can also revert a file back to the state of the last index snapshot (via git checkout). Essentially, the index acts like a "temporary commit" that is easy to modify before actually being promoted to a full commit.

    Since the index is persistent, if you get halfway through staging things, then decide you need to make another change, no problem - just go make the change, then stage the new version. No need to re-stage all of the other things you've already staged.

    Accidentally delete a file before committing? If you already staged it, no worries - just check out the staged version.