On git add -h I can see the following option:
-N, --intent-to-add record only the fact that the path will be added later
But
user456814's answer explains very well what git add -N is useful for. I just want to give a more detailed explanation of what's going on in the background.
You can think of git as maintaining a history of file changes like creations, modifications, and deletions (let's call them deltas). The deltas are pretty self-explanatory up until the most recent commit, but things get more complicated when you're working in your project to prepare a new commit to go on top. There are three different types of deltas when you're in this situation.
(Side note: most people, when first introduced to git, are taught something like "committing in git takes two steps; first you do git add and then you can do git commit". While this is true, it only brings attention to the Changes to be committed type of delta. Understanding git add -N requires understanding the other types of deltas as well.)
Commonly called "staged changes", these deltas appear at the top when you run git status, if there are any. If your shell supports color, they will be green.
When you git add a file, it gets promoted into this category. These are the changes that will actually be included if you run git commit without any flags.
These deltas appear second when you run git status, if there are any. If your shell supports color, they will be red.
These are changes that you have made to files in the git repository that have not yet been committed AND have not been moved to #1. When you edit a file and then save, it appears in this category by default.
For a file to show up in this category, it has to EITHER already exist in the most recent commit, OR be added if the changes in #1 were to be committed. Otherwise, it will show up in category #3.
(Note: because you choose when to "promote" a file into category #1, it's possible to have the same file show up in both #1 and #2. For example, I could see
modified: abc.txt
in green in #1, and
modified: abc.txt
in red in #2 at the same time. This can happen if I promote a file to #1, then later make some more changes to it. The entry in #1 references the delta that I made before promoting the file, maybe adding a new line of code, and the entry in #2 references the delta that I made afterwards, maybe adding a comment at the top. If I were more organized, I would have made all the changes before promoting the file to #1, in order to avoid this situation altogether.)
These deltas appear last when you run git status, if there are any. If your shell supports color, they will be red.
These are all the files that are not in the most recent commit AND not in #1. While technically a delta in the sense that adding it would change the commit, it's possible that the file has just always been there and people just don't want git to record any information about it. (In this case, you should add the file to .gitignore, and it will stop showing up in git status.)
When you create a brand-new file, it shows up in this category.
git add -N?git add -N is all about making it easier to work with #3 deltas. As referenced in the accepted answer above, git diff lets you see what deltas you have actually prepared. Here is a good set of commands that work with git diff.
git diff only shows the differences between #1 and #2 (i.e. the deltas in #2).
git diff --staged only shows the deltas in #1.
git diff HEAD only shows the deltas in #1 and #2, put together.
Notice that none of these commands even look at #3. However, by running git add -N, you basically do the following:
git add the "file creation" delta into #1This has the effect of making the second delta appear in #2. Now the new file is completely out of #3, and you can use git diff commands with it.
As for git commit -a, essentially what it does is:
git add everything in #2 so that it is also staged with everything in #1git commit (which takes everything in #1, including the stuff that was just added, and creates an actual commit from it)Without git add -N, this command misses your new file in #3; however, you can see that after running git add -N, your new file is spread across #1 and #2, and will get included in the commit.
Well, I've explained everything I want to explain. If you want to check your understanding, you can follow along with the example below:
I make a new git repo.
sh-4.1$ cd ~/Desktop
sh-4.1$ mkdir git-demo
sh-4.1$ cd git-demo
sh-4.1$ git init
Initialized empty Git repository in /local/home/Michael/Desktop/git-demo/.git/
git status shows me this repo is empty.
sh-4.1$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
I make some new files.
sh-4.1$ echo "this is the abc file" > abc.txt
sh-4.1$ echo "this is the def file" > def.txt
sh-4.1$ echo "this is the ghi file" > ghi.txt
git status shows me all the new files are currently in category #3.
sh-4.1$ git status
On branch master
Initial commit
Untracked files:
(use "git add ..." to include in what will be committed)
abc.txt
def.txt
ghi.txt
nothing added to commit but untracked files present (use "git add" to track)
git diff does nothing, since it doesn't operate on #3.
sh-4.1$ git diff
I commit one file, add another one, and add -N the third one.
sh-4.1$ git add abc.txt && git commit -m "some commit message"
[master (root-commit) 442c173] some commit message
1 file changed, 1 insertion(+)
create mode 100644 abc.txt
sh-4.1$ git add def.txt
sh-4.1$ git add -N ghi.txt
In git status, abc.txt no longer shows up, since it has already been committed. def.txt only shows up in category #1 since the whole file has been added. ghi.txt shows up in categories #1 and #2.
sh-4.1$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: def.txt
new file: ghi.txt
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: ghi.txt
By running git diff, I can show all the deltas listed in #2. The only delta that shows up is that I added a line to ghi.txt.
sh-4.1$ git diff
diff --git a/ghi.txt b/ghi.txt
index e69de29..8a8dee2 100644
--- a/ghi.txt
+++ b/ghi.txt
@@ -0,0 +1 @@
+this is the ghi file
By running git diff --staged, I can show all the deltas listed in #1. Three of them show up: creating a new file def.txt, adding a line in def.txt, and creating a new file ghi.txt. Even though there are 2 deltas for def.txt, the file name itself is only output one time in example 7 above, to avoid clutter.
sh-4.1$ git diff --staged
diff --git a/def.txt b/def.txt
new file mode 100644
index 0000000..48baf27
--- /dev/null
+++ b/def.txt
@@ -0,0 +1 @@
+this is the def file
diff --git a/ghi.txt b/ghi.txt
new file mode 100644
index 0000000..e69de29