기술백서 - git add--intent-to-add 또는 N은 무엇을 하고 언제 사용해야 합니까?



eos 백서 v2 (3)

git add -h 에서 다음 옵션을 볼 수 있습니다 :

-N, --intent-to-add   record only the fact that the path will be added later

그러나이 옵션을 언제 사용해야하는지 이해하지 못합니다. 이 옵션은 실제로 무엇을하며 어떻게 사용해야합니까?

https://src-bin.com


Answer #1

추적 할 수없는 파일의 diffing 사용

Blue112의 대답 은 부분적으로 정확합니다. git add --intent-to-add 는 작업 카피의 지정된 각 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

파일을 diff 한 후에는 일반 git add 를 사용하여 비어 있지 않은 버전을 준비 영역 / 인덱스에 git add .

$ git add foo.txt

추적 할 수없는 파일의 git commit -a 사용

마찬가지로, --intent-to-add--intent-to-add 파일을 스테이지의 / 인덱스에 빈 버전의 파일을 추가하여 Git에 "알려진"것으로 만들기 때문에 git commit --all 또는 git commit -a 를 사용하여 커밋 할 수 있습니다 그 파일들은 당신이 알고있는 수정 된 파일과 함께 당신이 달리 할 수없는 것입니다.

git commit 에 대한 공식 리눅스 커널 문서 에서 설명했듯이 :

commit 명령과 함께 -a [또는 --all ] 스위치를 사용하면 알려진 모든 파일 (즉, 이미 색인에 나열된 모든 파일)의 변경 사항을 자동으로 "추가"합니다 ... 그리고 실제 커밋을 수행합니다

선적 서류 비치

공식 리눅스 커널 git add 문서를 git add :

-N
--intent-to-add

경로가 나중에 추가된다는 사실 만 기록하십시오. 경로 항목은 내용이없는 색인에 위치합니다. 이것은 다른 것들 사이에서 git diff 로 이러한 파일의 무대화 된 내용을 보여주고 git commit -a 커밋하는 데 유용합니다.


Answer #2

git 2.10 (2016 년 3 분기) 이전에 git add -N 은 언젠가 일부 항목을 건너 뛸 수 있습니다.

Nguyễn Thái Ngọc Duy ( pclouds )의 커밋 6d6a782 , 커밋 c041d54 , 커밋 378932d , 커밋 f9e7d9f (2016 년 7 월 16 일)를 참조하십시오 .
( Junio ​​C gitster - gitster 병합 - 커밋 3cc75c1 , 2016 년 7 월 25 일)

당신이 가지고 있다면:

a-file
subdir/file1
subdir/file2
subdir/file3
the-last-file

그리고 add -N 모두 add -N 하면 ... subdir 파일은 항목을 추가하려는 의도로 기록 되지 않습니다 .

cache-tree.c : 때때로 디렉토리 업데이트를 건너 뛰는 항목 수정

3cf773e 커밋 ( cache-tree : CE_REMOVE 가있을 때 캐시 트리 작성 - 2012-12-16 - Git v1.8.1.1)은 인덱스에서 트리 객체를 작성할 때 항목을 건너 뜁니다. 불행히도 너무 많이 건너 뛸 수 있습니다.

subdir/file1 이 ita 인 경우,이 코드에서 깨진 조건으로 인해 " subdir "은 ita 파일이고 " subdir "을 쓰지 않고 last-file로 점프한다고 생각합니다.
이제 결과 트리에는 a- a-filethe-last-file 두 항목 만 있습니다.
subdir 도 거기에 있어야합니다 (2 개의 하위 항목, file2file3 만 기록하더라도).

Git 2.17 (Q2 2018, later 4 년) : 작업 트리에서 경로를 이동 한 다음 (따라서 "제거"로 표시) -N 옵션을 추가 한 후 Git 2.17 (Q2 2018, laters) ), git status 그것을 이름 바꾸기로 감지했지만 이전 경로와 새 경로명을 정확하게보고하지 않았습니다.

커밋 176ea74 보기, 커밋 5134ccd , 커밋 ea56f97 , 커밋 98bc94e , 커밋 06dba2b , 커밋 6de5aaf (2017 년 12 월 27 일) Nguyễn Thái Ngọc Duy ( pclouds ) .
도움 말 : Igor Djordjevic ( boogisha ) .
( Junio ​​C gitster - gitstergitster - 커밋 12accdc , 2018 년 2 월 27 일) .

주의 사항 : ita 또는 ita 는 " ita -to-add"를 의미하며 -N 은 무엇을 의미합니다.

wt-status.c : 작업 트리 이름 바꾸기 처리

425a28e ( diff-lib : ita 항목이 "색인에 아직 존재하지 않음"- 2016-10-24, Git 2.11.0-rc0)을 처리하기 전에 색인에 "새 파일"이 없으므로 기본적으로 이름 바꾸기 감지 기능을 사용할 수 없기 때문에 새로운 파일이 diff 쌍에 나타날 때만 이름 변경을 감지합니다.

그 커밋 후, ita 엔트리는 " git diff-files "에 새로운 파일로 나타날 수있다. 그러나 wt-status.c 의 diff 콜백 함수는이 경우를 처리하지 못하고 잘못된 상태 출력을 생성합니다.


Answer #3

user456814의 대답 은 git add -N 이 유용하다는 것을 잘 설명합니다. 백그라운드에서 진행되는 작업에 대해보다 자세한 설명을 드리고자합니다.

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

# 1에서 초록색으로, 그리고

modified:   abc.txt

동시에 # 2에서 빨간색으로 표시됩니다. 파일을 # 1로 올린 다음 나중에 파일을 변경하면이 문제가 발생할 수 있습니다. # 1의 엔트리는 파일을 승격하기 전에 만든 델타를 참조합니다. 아마도 새로운 코드 행을 추가 할 것입니다. # 2의 엔트리는 내가 만든 델타를 참조합니다. 맨 위에 주석을 추가 할 수 있습니다. 좀 더 체계적으로 작성했다면이 상황을 피하기 위해 파일을 # 1로 승격하기 전에 모든 변경 작업을 수행했을 것입니다.)

# 3 : 비 추적 파일

이 델타는 git status 있을 때 마지막에 나타납니다. 쉘이 색상을 지원하면 빨간색이됩니다.

이것들은 # 1에서가 아니라 가장 최근의 커밋이 아닌 모든 파일입니다. 엄밀히 말하면 델타는 커밋을 변경하면 커밋이 변경 될 수 있다는 의미에서 파일은 항상 거기에 있었을 수 있으며 사람들은 단지 그 것에 대한 정보를 기록하지 않기를 바랍니다. (이 경우 .gitignore에 파일을 추가해야하며 git status 표시되지 않습니다.)

새로운 파일을 만들면이 파일이이 범주에 나타납니다.

그래서이 모든 것들을 git add -N 해야합니까? git add -N ?

git add -N 은 3 델타로 작업하기가 더 쉽다. 위의 대답에서 언급했듯이 git diff 사용하면 실제로 작성한 델타를 볼 수 있습니다. Here 은 git diff 와 함께 작동하는 좋은 명령 집합입니다.

git diff 는 # 1과 # 2의 git diff 만을 보여줍니다 (즉, # 2의 델타).

git diff --staged 는 # 1의 델타 만 보여줍니다.

git diff HEAD 는 # 1과 # 2의 델타 만 표시합니다.

이 명령들 중 어느 것도 # 3을 보지 않습니다. 그러나 git add -N 을 실행하면 기본적으로 다음을 수행합니다.

  • 새 파일을 두 개의 델타로 나눕니다. 파일 만들기 만하고 텍스트 / 내용으로 파일 채우기
  • git add 은 # 1에 "파일 생성"델타를 git add 합니다.

이것은 # 2에서 두 번째 델타를 표시하는 효과가 있습니다. 이제 새 파일은 3 번에서 완전히 벗어 났고 git diff 명령을 사용할 수 있습니다.

git commit -a 는 기본적으로 다음과 같습니다.

  • git add # 2 git add 모든 것을 git add 하여 # 1의 모든 항목과 함께 준비되도록합니다.
  • git commit (방금 추가 된 내용을 포함하여 # 1의 모든 것을 취하고 그로부터 실제 커밋을 만듭니다)

git add -N 하지 않으면이 명령은 # 3에서 새 파일을 git add -N . 그러나 git add -N 을 실행 git add -N 새로운 파일이 # 1과 # 2에 퍼지고 커밋에 포함될 것입니다.

글쎄, 내가 설명하고 싶은 모든 것을 설명했다. 이해를 확인하려면 아래 예를 따라 할 수 있습니다.

  1. 나는 새로운 git repo를 만든다.

    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/
    
  2. git status 는이 repo가 ​​비어 있음을 나타냅니다.

    sh-4.1$ git status
    On branch master
    
    Initial commit
    
    nothing to commit (create/copy files and use "git add" to track)
    
  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
    
  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)
    
  5. git diff 는 # 3에서 작동하지 않기 때문에 아무 것도하지 않습니다.

    sh-4.1$ git diff
    
  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
    
  7. 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
    
  8. git diff 를 실행하면 # 2에 나열된 모든 델타를 표시 할 수 있습니다. 나타나는 델타는 ghi.txt 줄을 추가 한 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
    
  9. git diff --staged 를 실행하면 # 1에 나열된 모든 델타를 표시 할 수 있습니다. 그것들 중 세개가 나타납니다 : 새로운 파일 def.txt , def.txt 에 줄을 추가하고, 새로운 파일 ghi.txt . def.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
    




git