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 I don't understand when should this option be used. What does this option really do, and how it should be used?
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 I don't understand when should this option be used. What does this option really do, and how it should be used?
Enable diffing of untracked files
Blue112's answer is partially correct.
git add --intent-to-add
does indeed add an empty file to the staging area/index for each specified untracked file in your working copy, but one of the main purposes of this is to enable you to usegit diff
with files that haven't been added to the Git repository yet by diffing your untracked file against its empty version in the staging area:Once you've diffed the file, you can add the non-empty version to the staging area/index by simply doing a normal
git add
:Enable
git commit -a
of untracked filesLikewise, since
--intent-to-add
makes untracked files "known" to Git by adding empty versions of those files to the staging area/index, it also allows you to usegit commit --all
orgit commit -a
to commit those files along with your known modified files, which is something that you wouldn't be able to do otherwise.As explained in the official Linux Kernel documentation for
git commit
:Documentation
From the official Linux Kernel
git add
documentation:It is mainly used to add an empty file for your commits.
More informations at Git with intent to add!.
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 dogit commit
". While this is true, it only brings attention to the Changes to be committed type of delta. Understandinggit add -N
requires understanding the other types of deltas as well.)#1: Changes to be committed
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 rungit commit
without any flags.#2: Changes not staged for commit
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
in green in #1, and
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.)
#3: Untracked files
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.
So what does all this have to do with
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 withgit 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 runninggit 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.
git status
shows me this repo is empty.I make some new files.
git status
shows me all the new files are currently in category #3.git diff
does nothing, since it doesn't operate on #3.I commit one file, add another one, and
add -N
the third one.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.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 toghi.txt
.By running
git diff --staged
, I can show all the deltas listed in #1. Three of them show up: creating a new filedef.txt
, adding a line indef.txt
, and creating a new fileghi.txt
. Even though there are 2 deltas fordef.txt
, the file name itself is only output one time in example 7 above, to avoid clutter.Note that before git 2.10 (Q3 2016),
git add -N
can sometime skips some entries.See commit 6d6a782, commit c041d54, commit 378932d, commit f9e7d9f (16 Jul 2016) by Nguyễn Thái Ngọc Duy (
pclouds
).(Merged by Junio C Hamano --
gitster
-- in commit 3cc75c1, 25 Jul 2016)If you have:
And you
add -N
everything... thensubdir
files are not recorded as i-t-a ("intended to add") entries.git status
has improved, with Git 2.17 (Q2 2018, four years laters): after moving a path in the working tree (hence making it appear "removed") and then adding with the-N
option (hence making that appear "added"),git status
detected it as a rename, but did not report the old and new pathnames correctly.See commit 176ea74, commit 5134ccd, commit ea56f97, commit 98bc94e, commit 06dba2b, commit 6de5aaf (27 Dec 2017) by Nguyễn Thái Ngọc Duy (
pclouds
).Helped-by: Igor Djordjevic (
boogisha
).(Merged by Junio C Hamano --
gitster
-- in commit 12accdc, 27 Feb 2018).Reminder:
ita
ori-t-a
stands for "intended-to-add", what-N
does.