On Sat, Nov 16, 2024 at 6:08 PM A bughunter <A_bughunter@xxxxxxxxx> 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