Но я не понимаю, когда следует использовать эту опцию. Что делает этот вариант действительно и как его использовать?
Ответ 1
Включить различение неиспользуемых файлов
Ответ Blue112 является частично правильным. git add --intent-to-add
действительно добавляет пустой пул в промежуточную область/индекс для каждого указанного невоспроизводимого файла в вашей рабочей копии, , но одна из основных целей этого заключается в том, чтобы вы могли использовать git diff
с файлами, которые еще не добавлены в репозиторий Git, отличая ваш необработанный файл от его пустой версии в промежуточной области:
$ echo foo > foo.txt
$ git diff foo.txt
$ git add --intent-to-add foo.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: foo.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: foo.txt
$ git diff --staged foo.txt
diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..e69de29
$ git diff foo.txt
diff --git a/foo.txt b/foo.txt
index e69de29..257cc56 100644
--- a/foo.txt
+++ b/foo.txt
@@ -0,0 +1 @@
+foo
После того, как вы изменили файл, вы можете добавить непустую версию в промежуточную область/индекс, просто выполнив обычный git add
:
$ git add foo.txt
Включить git commit -a
отпечатанных файлов
Аналогично, поскольку --intent-to-add
делает незатребованные файлы "известными" Git, добавляя пустые версии этих файлов в промежуточную область/индекс, он также позволяет использовать git commit --all
или git commit -a
для фиксации этих файлов наряду с вашими известными измененными файлами, что вы не сможете сделать иначе.
Как описано в официальной документации ядра Linux для git commit
:
с помощью переключателя -a
[или --all
] с командой commit [будет] автоматически "добавлять" изменения из всех известных файлов (то есть всех файлов, которые уже указаны в индексе)... и затем выполнить фактическая фиксация
Документация
Из официальная документация Linux Kernel git add
:
-N
--intent-to-add
Запишите только тот факт, что путь будет добавлен позже. Запись для пути помещается в индекс без содержимого. Это полезно, помимо прочего, показывать неустановленное содержимое таких файлов с помощью git diff
и совершать их с помощью git commit -a
.
Ответ 2
user456814 answer очень хорошо объясняет, что полезно для git add -N
. Я просто хочу дать более подробное объяснение того, что происходит в фоновом режиме.
Вы можете думать о git как о сохранении истории изменений файла, таких как творения, модификации и удаления (пусть их называют deltas). Дельты довольно понятны до самой последней фиксации, но все усложняется, когда вы работаете в своем проекте, чтобы подготовить новую фиксацию, чтобы идти вверх. В этой ситуации существуют три разные типы дельт.
(Боковое примечание: большинство людей при первом знакомстве с git учат чему-то вроде: "совершение в git выполняет два шага: сначала вы делаете git add
, а затем можете делать git commit
". это правда, оно только привлекает внимание к изменениям типа дельта. Для понимания git add -N
требуется понимание других типов дельт.)
# 1: Изменения, которые необходимо совершить
Обычно называемые "поэтапные изменения", эти дельта появляются вверху при запуске git status
, если таковые имеются. Если ваша оболочка поддерживает цвет, они будут зелеными.
Когда вы git add
файл, он получает повышение в эту категорию. Это те изменения, которые будут включены, если вы запустите git commit
без каких-либо флагов.
# 2: изменения не поставлены для фиксации
Эти дельта появляются второй при запуске git status
, если таковые имеются. Если ваша оболочка поддерживает цвет, они будут красными.
Это изменения, внесенные вами в файлы в репозитории git , которые еще не были выполнены, и не были перенесены на # 1. Когда вы редактируете файл и затем сохраняете его, он по умолчанию появляется в этой категории.
Для файла, который будет отображаться в этой категории, он должен иметь уже существующий в последней фиксации, OR , если необходимо внести изменения в # 1. strong > . В противном случае он появится в категории № 3.
(Примечание: поскольку вы выбираете, когда "продвигать" файл в категорию №1, возможно, что тот же файл отображается как в # 1, так и в # 2. Например, я мог видеть
modified: abc.txt
зеленым цветом в # 1 и
modified: abc.txt
красным цветом в # 2 одновременно. Это может произойти, если я продвигаю файл на # 1, а затем сделаю еще несколько изменений. Запись в # 1 ссылается на дельта, которую я сделал, прежде чем продвигать файл, возможно, добавив новую строку кода, а запись в # 2 ссылается на дельта, которую я сделал впоследствии, возможно, добавив комментарий вверху. Если бы я был более организован, я бы сделал все изменения, прежде чем продвигать файл на # 1, чтобы вообще избежать этой ситуации.)
# 3: файлы без отслеживания
Эти дельта появляются last при запуске git status
, если таковые имеются. Если ваша оболочка поддерживает цвет, они будут красными.
Это все файлы, которые не находятся в последней фиксации, а не в # 1. В то время как технически дельта в том смысле, что добавление этого изменило бы фиксацию, возможно, что файл всегда был там, и люди просто не хотят, чтобы git записывал любую информацию об этом. (В этом случае вы должны добавить файл в .gitignore, и он перестанет отображаться в git status
.)
Когда вы создаете совершенно новый файл, он отображается в этой категории.
Итак, что все это имеет отношение к git add -N
?
git add -N
- все это упрощает работу с дельтами 3. Как указано в принятом ответе выше, git diff
позволяет вам увидеть, какие дельта вы действительно подготовили. Здесь - хороший набор команд, которые работают с git diff
.
git diff
показывает только различия между # 1 и # 2 (т.е. дельтами в # 2).
git diff --staged
показывает только дельта в # 1.
git diff HEAD
показывает только дельта в # 1 и # 2.
Обратите внимание, что ни одна из этих команд даже не смотрит на # 3. Однако, запустив git add -N
, вы в основном выполните следующее:
- Разделить новый файл на две дельта: просто создать файл и заполнить файл текстом/контентом
-
git add
Дельта "создание файла" в # 1
Это приводит к появлению второй дельты в # 2. Теперь новый файл полностью вышел из # 3, и вы можете использовать с ним команды git diff
.
Что касается git commit -a
, то, по существу, он делает следующее:
-
git add
все в # 2, чтобы он также был поставлен со всем в # 1
-
git commit
(который принимает все в # 1, включая только что добавленный материал, и создает из него фактическое сообщение)
Без git add -N
эта команда пропускает ваш новый файл в # 3; однако вы можете видеть, что после запуска git add -N
ваш новый файл распространяется на # 1 и # 2 и будет включен в commit.
Хорошо, я объяснил все, что хочу объяснить. Если вы хотите проверить свое понимание, вы можете следовать примеру ниже:
-
Я создаю новый репо git.
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
показывает, что это репо пусто.
sh-4.1$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
-
Я делаю несколько новых файлов.
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
показывает, что все новые файлы в настоящее время относятся к категории № 3.
sh-4.1$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." 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
ничего не делает, поскольку он не работает на # 3.
sh-4.1$ git diff
-
Я фиксирую один файл, добавляю еще один и add -N
третий.
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
-
В git status
, abc.txt
больше не появляется, поскольку он уже был зафиксирован. def.txt
отображается только в категории # 1, так как весь файл был добавлен. ghi.txt
отображается в категориях # 1 и # 2.
sh-4.1$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: def.txt
new file: ghi.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: ghi.txt
-
Запустив git diff
, я могу показать все дельта, перечисленные в # 2. Единственная дельта, которая появляется, это то, что я добавил строку в 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
-
Запустив git diff --staged
, я могу показать все дельта, перечисленные в # 1. Появятся три из них: создание нового файла def.txt
, добавление строки в def.txt
и создание нового файла ghi.txt
. Несмотря на то, что для def.txt
есть 2 дельта, само имя файла выводится только один раз в примере 7 выше, чтобы избежать беспорядка.
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