git添加了什么 - 添加 - 或添加 - 或者什么时候应该使用它?

fot*_*nus 25 git

git add -h我可以看到下面的选项:

-N, --intent-to-add   record only the fact that the path will be added later
Run Code Online (Sandbox Code Playgroud)

但我不明白何时应该使用此选项.这个选项真正做了什么,以及如何使用它?

小智 25

启用未跟踪文件的差异化

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
Run Code Online (Sandbox Code Playgroud)

一旦您对文件进行了差异化,就可以通过简单地执行正常操作将非空版本添加到临时区域/索引git add:

$ git add foo.txt
Run Code Online (Sandbox Code Playgroud)

启用git commit -a未跟踪的文件

同样,由于--intent-to-add通过将这些文件的空白版本添加到临时区域/索引来使未跟踪文件"已知"给Git,它还允许您使用git commit --allgit commit -a提交这些文件以及您已知的已修改文件,这是您不会的事情.能否做到.

正如官方Linux内核文档中所述git commit:

使用-a[或--all]开关和commit命令[将]自动"添加"来自所有已知文件的更改(即已在索引中列出的所有文件)...然后执行实际提交

文档

官方Linux内核git add文档:

-N
--intent-to-add
Run Code Online (Sandbox Code Playgroud)

仅记录稍后将添加路径的事实.路径的条目放在索引中,没有内容.除其他外,这对于显示此类文件的未分级内容git diff并使用它们进行提交非常有用git commit -a.

  • 我经常以迭代模式进行修补,如果没有-N,则不可能修补新添加的文件。 (5认同)
  • 您的答案是正确且有道理的,所以+1。然而“--intent-to-add”对我来说似乎没什么用。假设我有一个新文件 foo.txt,其中包含 100 行代码。当我 `git add -N foo.txt` 并运行 `git diff foo.txt` 时,我看到添加了 100 行代码。(看起来这相当于剪切所有文件的内容,添加文件,然后将其粘贴回文件中。)现在,当我进行更改(例如添加一行)并再次 git diff 时,我现在看到添加了 101 行代码。因此,向舞台添加空文件路径对于查看差异没有帮助。 (2认同)
  • @chharvey 这取决于你的工作流程。您只需暂存文件并忽略这个新选项即可获得您想要的行为。我喜欢在输入“git diff”时看到我编写的所有代码,这样我就可以在提交和打开 PR 之前在一个地方自我审查所有内容。 (2认同)

Mic*_*ael 5

user456814的答案很好地说明了什么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的文件所做的更改。当您编辑文件然后保存时,默认情况下它将显示在此类别中。

对于要显示在此类别中的文件,它必须在最近的提交中已经存在,或者如果要提交#1的更改,则添加该文件。否则,它将显示在类别3中。

(注意:由于您选择何时将文件“升级”到类别1中,因此有可能在#1和#2中都显示相同的文件。例如,我可以看到

modified:   abc.txt
Run Code Online (Sandbox Code Playgroud)

#1中为绿色,并且

modified:   abc.txt
Run Code Online (Sandbox Code Playgroud)

在#2中同时显示为红色。如果我将文件提升为#1,然后再对其进行更多更改,则会发生这种情况。#1中的条目引用了我在升级文件之前所做的增量,也许添加了新的代码行,而#2中的条目引用了我之后进行的增量,也许在顶部添加了注释。如果我更有条理,那么在将文件升级到#1之前,我会进行所有更改,以便完全避免这种情况。)

#3:未跟踪的文件

如果运行,这些增量将在您运行时最后显示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中,并将包含在提交中。


好了,我已经解释了我想解释的所有内容。如果要检查您的理解,可以按照以下示例进行操作:

  1. 我做了一个新的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/
    
    Run Code Online (Sandbox Code Playgroud)
  2. git status 告诉我这个仓库是空的。

    sh-4.1$ git status
    On branch master
    
    Initial commit
    
    nothing to commit (create/copy files and use "git add" to track)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我制作了一些新文件。

    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
    
    Run Code Online (Sandbox Code Playgroud)
  4. 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)
    
    Run Code Online (Sandbox Code Playgroud)
  5. git diff 什么也不做,因为它无法在#3上运行。

    sh-4.1$ git diff
    
    Run Code Online (Sandbox Code Playgroud)
  6. 我提交一个文件,添加另一个文件,然后添加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
    
    Run Code Online (Sandbox Code Playgroud)
  7. 在中git statusabc.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
    
    Run Code Online (Sandbox Code Playgroud)
  8. 通过运行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
    
    Run Code Online (Sandbox Code Playgroud)
  9. 通过运行git diff --staged,我可以显示#1中列出的所有增量。其中显示三个:创建一个新文件def.txt,在其中添加一行def.txt,以及创建一个新文件ghi.txt。即使有2个增量def.txt,在上面的示例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
    
    Run Code Online (Sandbox Code Playgroud)