Re: What is the diff between a --soft and a blank reset
- From
Chris Torek <chris.torek@gmail.com>
- Date
- Nov 17, 2024, 02:57 UTC
- Message-ID
- <CAPx1GvfT1iNnpJ0Jv0vhdHrwD-pDOK81MnUW2-Fk_zcJkW9PUQ@mail.gmail.com>
- In-Reply-To
- <myxdTw4K7jcrlKX-HC0edNKB3mgkjGJPAejkxWTcab03uT9uROZlO28zjhmnogOvGCJkag5q_Zvbok0VUyVjlkw5Goz3Gwe3l636lCYnGic=@proton.me>
On Sat, Nov 16, 2024 at 6:08 PM A bughunter <A_bughunter@proton.me> wrote:
> The difference here is touching the index but what does that mean in pragma ...
Understanding "the index" is _crucial_ to using Git, yet it's not often explained very well.
(Note: _emphasis_ means italics emphasis, while ALL CAPS means bold emphasis, below.)
I think it helps to start with a simple fact about _every_ source management system: such a system, by definition, _must_ have TWO COPIES OF EVERY FILE available at all times. This follows from the fact that you can get back the version you started with -- and to do that, the system must retain each original, unedited version -- and yet you must also be able to edit files, which means the system must retain the edited files as well. So those are the two _required_ copies: original, and edited. If the two are the same, it's at least theoretically possible to share them, but that's not important here. The actively-being-edited files are the _working tree_, while the frozen-for-all-time original files are saved (forever) in a Git commit, in the case of Git.
What's unusual about Git is that it keeps a THIRD copy of every file. As noted above, if any given pair of copies match, it's at least theoretically possible to share them -- and Git sometimes does -- but that's not important here.
What Git's index is all about is that it HOLDS THE THIRD COPY. The reason this is crucial to know is that running:
git commit
tells Git to make a *new* commit FROM THIS THIRD COPY.
There are tricks you can use to attempt to hide or ignore this third copy, but using them is, in my opinion, a bad idea, because eventually one of these tricks fails and you're exposed to the fact that there _is_ a third copy. You might as well just get used to the idea.
Once you _are_ used to the idea, much of the rest of Git begins to make sense:
* `git add` mainly copies files _into_ the index, preparing them for a future commit.
* `git commit` takes whatever is in the index _right then_ and uses that to make the new (permanently-frozen) copy of all those files.
Now, logically, `git reset` might be the one that undoes `git add`. And it _does_ do that. The problem is that it does a lot more as well. It has, in fact, _three_ primary jobs:
* It can move `HEAD`. (Understanding precisly what `HEAD` means, in Git, is another crucial item, but this message won't cover that.)
* It can copy some or all files from a commit into the index.
* Last, it can _also_ copy those files from the commit, into the index, and then on into the working tree.
(Even more unfortunately, `git reset` has several auxiliary jobs as well as these three primary ones. I won't cover these.)
The three options -- `--soft`, `--mixed`, and `--hard` -- tell `git reset` which of these three jobs to do:
* With `--soft`, `git reset` _only_ adjusts `HEAD`. The
default adjustment is to leave it unchanged, so running
`git reset --soft` with no additional arguments does
nothing at all. That is, it does only job #1, then
stops.* With `--mixed`, `git reset` adjusts `HEAD` as before -- it's usually wisest to not have it adjust anything for this case, in my opinion -- and then goes on to copy the files from the `HEAD` commit into the index. That is, it does jobs #1 and #2, and then stops.
* With `--hard`, `git reset` adjusts `HEAD`, copies the files from the adjusted `HEAD` to the index, and then copies the files from the index to the working tree. That is, it does all three of jobs #1, #2, and #3.
And that's it: that's all you need to know. Well, _almost_ all: there are all kinds of finicky corner cases around files that are in the working tree but _not_ in the index and/or commit. There's also one other problem, in a new, totally-empty repository in which there are no commits yet. But those edge cases need a lot of explanation and should be left until later.
Chris