16

Is it possible to start tracking files in git without adding them to the index?

I have new files which I'd like to survive a git clean, but will likely change before the next commit. Do I simply add them to the index now, and then add them again later just before the commit?

ajwood
  • 18,227
  • 15
  • 61
  • 104

3 Answers3

22

Seems like you're looking for git add --intent-to-add (or git add -N). From the official git add documentation:

-N
--intent-to-add

Record only the fact that the path will be added later. An entry for the path is placed in the index with no content. This is useful for, among other things, showing the unstaged content of such files with git diff and committing them with git commit -a.

See the What does git add --intent-to-add or -N do and when should it be used? question for more information.

Wiktor Czajkowski
  • 1,623
  • 1
  • 14
  • 20
  • Just as a quick remark: while this solution might work in many situations, don't use it to include the new files in a stash (I just tried, won't work currently). See also: https://stackoverflow.com/questions/72931533/git-stash-seems-not-to-work-when-new-files-have-been-added – kaba May 16 '23 at 20:07
  • To add new files to stash it's best to use `git stash save -u`, also see https://stackoverflow.com/questions/835501/how-do-you-stash-an-untracked-file – Wiktor Czajkowski Jun 26 '23 at 15:28
4

You can stage the files using git add, then git reset them prior to the commit.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
0

The problem with add -N (i-t-a, "intent to add", in order to "start tracking a file in Git without adding to to the index") is that:

Due to the implementation detail of intent-to-add entries,

  • the current "git diff" (i.e. no treeish or --cached argument) would show the changes in the i-t-a file, but it does not mark the file as new,
  • while "diff --cached" would mark the file as new while showing its content as empty.

Git 2.19 (Q3 2018) changes that; since "git diff" compares the index and the working tree.
For paths added with intent-to-add bit, the command shows the full contents of them as added, but the paths themselves were not marked as new files.
They are now shown as new by default.

See commit cff5dc0, commit 8fc8f05, commit 0231ae7, commit ba4e356 (26 May 2018) by Nguyễn Thái Ngọc Duy (pclouds).
(Merged by Junio C Hamano -- gitster -- in commit ac997db, 25 Jun 2018)

Before Git 2.19:

$ git diff                      | $ diff --cached
--------------------------------|-------------------------------
 diff --git a/new b/new         | diff --git a/new b/new
 index e69de29..5ad28e2 100644  | new file mode 100644
 --- a/new                      | index 0000000..e69de29
 +++ b/new                      |
 @@ -0,0 +1 @@                  |
 +haha                          |

One evidence of the current output being wrong is that, the output from "git diff" (with ita entries) cannot be applied because it assumes empty files exist before applying.

Turning on --ita-invisible-in-index (commit 425a28e, commit b42b451 Oct. 2016, Git 2.11.0) would fix this. The result is "new file" line moving from "git diff --cached" to "git diff".

$ git diff                      | $ diff --cached
--------------------------------|-------------------------------
 diff --git a/new b/new         |
 new file mode 100644           |
 index 0000000..5ad28e2         |
 --- /dev/null                  |
 +++ b/new                      |
 @@ -0,0 +1 @@                  |
 +haha                          |

This option is on by default in git-status but we need more fixup in rename detection code (commit bc3dca0, Jan. 2018, Git 2.17.0). Luckily we don't need to do anything else for the rename detection code in diff.c (wt-status.c uses a customized one).


With Git 2.28 (Q3 2020), "git diff-files" has been taught to say paths that are marked as intent-to-add are new files, not modified from an empty blob.

See commit feea694 (20 Jun 2020) by Srinidhi Kaushik (clickyotomy).
(Merged by Junio C Hamano -- gitster -- in commit 298d704, 29 Jun 2020)

diff-files: treat "i-t-a" files as "not-in-index"

Signed-off-by: Srinidhi Kaushik

The diff-files' command and related commands which call the function cmd_diff_files()', consider the "intent-to-add" files as a part of the index when comparing the work-tree against it.
This was previously addressed in commits 0231ae71d3 (diff: turn --ita-invisible-in-index on by default, 2018-05-26) and 425a28e0a4 (diff-lib: allow ita entries treated as "not yet exist in index", 2016-10-24) by turning the option --ita-invisible-in-index (introduced in b42b451919 ("diff: add --ita-[in]visible-in-index", 2016-10-24, Git v2.11.0-rc0 -- merge) on by default.

For diff-files (and add -p as a consequence) to show the i-t-a files as as new, ita_invisible_in_index will be enabled by default here as well.


Warning: if you are using exclusion (lowercase) and inclusion (uppercase) in a git diff-filter, use Git 2.36 (Q2 2022).

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250