I'm addind my change to a commit with git add -p
, now I'd like to use the manual hunk edit mode.
I simply have this hunk:
# Manual hunk edit mode -- see bottom for a quick guide
@@ -46,6 +46,7 @@ function signIn(email, password) {
}
})
.catch((error) => {
+ console.log(error);
ToastAndroid.show(translations.translations.error_occurred, ToastAndroid.SHORT);
that.setState({isLoading: false});
});
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
If I delete completely the line added (with console.log
) then save and quit the editor, I get this error:
error: corrupt patch at line 12
I have totally no idea of what I'm doing wrong.
[note: comments turned into answer - the top section is all you need, the rest is just explication]
The only change the patch hunk makes is to add that one line. If you take out the added line, the patch becomes a directive to change the file by making no change to the file, which is not very sensible. The error message here is kind of silly, but the action you need is simply "skip this one".
Note that there are, at all times while you're working on your next commit to make, three of what I call active copies of each file. Well, more precisely, there are up to three such copies. The first one is whatever you committed previously, or had inside the commit that you got when you ran git checkout
. This copy, being stored inside a commit, is fundamentally read-only: you cannot change it, as it's part of that particular commit. But you can access it whenever you like. For instance, given a README.txt
file you can run:
git show HEAD:README.txt
to view it. Internally, this file is stored in a special Git-only format (zlib-deflated and perhaps even further compressed)—non-Git programs in general cannot read this copy of the file.
There's also a copy of that same file in your work-tree, where you can work on it. This copy is stored in its ordinary computer format, so that you can read it. Your editor—atom or emacs or sublime or vim or whatever it is you use—can read and write the file. Your compiler, if you compile programs, can read and write it, and so on. You need not do anything special with the file, as it's just like any other file. Oddly, Git almost doesn't care about this copy of README.txt
—Git has to be kind of hands-off, since anything can change it!
But there's a third copy of README.txt
too, and that's the one that is in what Git calls, variously, the index, or the staging area, or the cache. (Which name Git uses depends on which Git documentation you're looking at.) This third copy, which you can see with git show :README.txt
, is in the special Git-only format, but unlike the copy in a commit, you can overwrite this one. The usual way that you overwrite this one is with git add
, which simply copies the work-tree file into the index.
Hence, the index :README.txt
starts out matching the HEAD:README.txt
file. If you change the work-tree copy, the HEAD and index versions still match. If you then git add README.txt
, that overwrites the index copy from the work-tree copy, and now HEAD:README.txt
and README.txt
no longer match, but :README.txt
does match README.txt
.
This is where git add -p
comes in: if the index copy and the work-tree copy of some file are different, you can have Git come up with a patch—a set of hunks, each of which says to add and/or remove some line or lines—that, if applied, would change the index version to match the work-tree version. If Git were to follow all the instructions in the patch, that would change the index copy of the file to match the work-tree copy, just like git add
would do.
But now Git has you go through that patch, one patch-hunk at a time, and:
When you choose to apply a particular patch-hunk (perhaps after editing it), Git extracts the index version of the file, applies that set of instructions, and goes on to look at the next one. If you skip it, Git just goes on to the next one.
Note that there is a companion to git add -p
: running git reset -p README.txt
tells Git that it should compare HEAD:README.txt
and :README.txt
(HEAD and index versions), and prepare a patch that would, if followed to the letter, change the index copy so that it matches the HEAD
copy again. Then Git goes through the same process as for git add -p
.
Last, let's take a quick look at git status
. This does a lot of useful things, but the one where it tells you about changes staged for commit and changes not staged for commit consists of running, in essence, two git diff
commands. The first one is:
HEAD
vs the index?For every file that is exactly the same here, Git is just silent about that. But if HEAD:README.txt
and :README.txt
are different, Git tells you that there is something staged for commit in README.txt
.
Having listed all of those files, Git runs a second diff, this time to find out:
Here, any file that's different, Git tells you that there is something not staged for commit. That's because you could run git add
on that file, to copy it into the index.
If you were to run git commit
right now, Git would make the new commit from whatever is in the index right now, so HEAD
-vs-index tells you: these files would be different, in this new commit, from what's in the current commit. Meanwhile index-vs-work-tree tells you: these files could be different, but won't be unless you git add
them.
This second diff is also the step that discovers any untracked files. An untracked file is, quite simply, a file that's in the work-tree, but not in the index. If such a file is ignored, Git shuts up about it. If the untracked file is not ignored, Git tells you that it is untracked. Note that a file that is in the index is by definition tracked, so Git never even checks for an ignore directive.
This fact—about new / untracked files—is why there are up to three copies of each file. If you create a new file, it's not in the HEAD
commit at all. It's also untracked until you git add
the file to copy it into the index. So you start out with one copy, in the work-tree only; then you have two, in the index and work-tree. Then you make a new commit, which becomes the current (HEAD
) commit, and only then are there three copies of that new file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With