Вкл git add -h
Я вижу следующий параметр:
-N, --intent-to-add record only the fact that the path will be added later
Но я не понимаю, когда следует использовать эту опцию. Что делает этот вариант действительно и как его использовать?
Вкл git add -h
Я вижу следующий параметр:
-N, --intent-to-add record only the fact that the path will be added later
Но я не понимаю, когда следует использовать эту опцию. Что делает этот вариант действительно и как его использовать?
Ответ 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
.
user456814 answer очень хорошо объясняет, что полезно для git add -N
. Я просто хочу дать более подробное объяснение того, что происходит в фоновом режиме.
Вы можете думать о git как о сохранении истории изменений файла, таких как творения, модификации и удаления (пусть их называют deltas). Дельты довольно понятны до самой последней фиксации, но все усложняется, когда вы работаете в своем проекте, чтобы подготовить новую фиксацию, чтобы идти вверх. В этой ситуации существуют три разные типы дельт.
(Боковое примечание: большинство людей при первом знакомстве с git учат чему-то вроде: "совершение в git выполняет два шага: сначала вы делаете git add
, а затем можете делать git commit
". это правда, оно только привлекает внимание к изменениям типа дельта. Для понимания git add -N
требуется понимание других типов дельт.)
Обычно называемые "поэтапные изменения", эти дельта появляются вверху при запуске git status
, если таковые имеются. Если ваша оболочка поддерживает цвет, они будут зелеными.
Когда вы git add
файл, он получает повышение в эту категорию. Это те изменения, которые будут включены, если вы запустите git commit
без каких-либо флагов.
Эти дельта появляются второй при запуске git status
, если таковые имеются. Если ваша оболочка поддерживает цвет, они будут красными.
Это изменения, внесенные вами в файлы в репозитории git , которые еще не были выполнены, и не были перенесены на # 1. Когда вы редактируете файл и затем сохраняете его, он по умолчанию появляется в этой категории.
Для файла, который будет отображаться в этой категории, он должен иметь уже существующий в последней фиксации, OR , если необходимо внести изменения в # 1. strong > . В противном случае он появится в категории № 3.
(Примечание: поскольку вы выбираете, когда "продвигать" файл в категорию №1, возможно, что тот же файл отображается как в # 1, так и в # 2. Например, я мог видеть
modified: abc.txt
зеленым цветом в # 1 и
modified: abc.txt
красным цветом в # 2 одновременно. Это может произойти, если я продвигаю файл на # 1, а затем сделаю еще несколько изменений. Запись в # 1 ссылается на дельта, которую я сделал, прежде чем продвигать файл, возможно, добавив новую строку кода, а запись в # 2 ссылается на дельта, которую я сделал впоследствии, возможно, добавив комментарий вверху. Если бы я был более организован, я бы сделал все изменения, прежде чем продвигать файл на # 1, чтобы вообще избежать этой ситуации.)
Эти дельта появляются 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, чтобы он также был поставлен со всем в # 1git 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
В основном используется для добавления пустого файла для ваших коммитов.
Дополнительная информация Git с намерением добавить!.
Обратите внимание, что до git 2.10 (Q3 2016) git add -N
может пропускать некоторые записи.
См. commit 6d6a782, commit c041d54, commit 378932d, зафиксировать f9e7d9f (16 июля 2016 г.) Nguyễn Thái Ngọc Duy (pclouds
).
(слияние Junio C Hamano - gitster
- в commit 3cc75c1, 25 июля 2016 г.
Если у вас есть:
a-file
subdir/file1
subdir/file2
subdir/file3
the-last-file
И вы add -N
все... тогда subdir
файлы не записываются как записи i-t-a ( "предназначенные для добавления" ).
cache-tree.c
: исправить i-t-запись иногда пропускает обновления каталогаCommit 3cf773e (
cache-tree
: исправить запись кеша приCE_REMOVE
присутствует - 2012-12-16 - git v1.8.1.1) пропускает его при построении объектов деревьев из индекса. К сожалению, он может пропустить слишком много.Если
subdir/file1
является ita, из-за сломанного условия в этом коде, мы по-прежнему считаем, что "subdir
" является ita файлом и не записывает "subdir
" вниз и переходит в последний файл.
Дерево результатов теперь имеет только два элемента:a-file
иthe-last-file
.subdir
должен быть там (даже если он записывает только две подзаголовки,file2
иfile3
).