programing

Git 인덱스에는 정확히 무엇이 포함되어 있습니까?

batch 2023. 7. 5. 20:33
반응형

Git 인덱스에는 정확히 무엇이 포함되어 있습니까?

Git 인덱스에는 정확히 무엇이 포함되어 있으며 인덱스의 내용을 보려면 어떤 명령을 사용할 수 있습니까?


모든 답변 감사합니다.인덱스가 준비 영역 역할을 하고, 커밋된 것은 작업 트리가 아닌 인덱스에 있다는 것을 알고 있습니다.나는 단지 인덱스 객체가 무엇으로 구성되어 있는지 궁금합니다.아마 파일 이름/디렉토리 이름, SHA-1 쌍, 일종의 가상 트리의 목록일 것입니다.

Git 용어로 인덱스의 내용을 나열하는 데 사용할 수 있는 배관 명령이 있습니까?

Git book에는 인덱스에 포함된 내용에 대한 기사가 포함되어 있습니다.

파일으로 인스는일이다니파일입보진됨관덱로으반적일▁in▁((▁the)입니다..git/index이름의 하며, 을 포함합니다. ) 경로의렬며포하함체개및의각, 각권한름된 SHA1.git ls-files인덱스의 내용을 표시할 수 있습니다.

$ git ls-files --stage
100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0   .gitignore
100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0   .mailmap

Racygit 문제는 그 구조에 대한 몇 가지 세부 사항을 제공합니다.

지수는 git에서 가장 중요한 데이터 구조 중 하나입니다.
경로 목록과 해당 개체 이름을 기록하여 가상 작업 트리 상태를 나타내며 커밋할 다음 트리 개체를 쓰기 위한 준비 영역 역할을 합니다.
상태는 작업 트리의 파일과 일치할 필요가 없으며 종종 일치하지 않는다는 점에서 "가상"입니다.


2021년 11월: 데릭 Stolee(마이크로소프트/GitHub)의 "Git's sparse index로 모노레포를 작게 느껴보세요"도 참조하십시오.

https://github.blog/wp-content/uploads/2021/11/Fig-1-working-directory-index-commit-history.png

Git 인덱스는 Git에서 중요한 데이터 구조입니다.파일 시스템에 있는 파일과 커밋 기록 사이의 "스테이지 영역" 역할을 합니다.

  • 을 할 때git add작업 디렉토리의 파일은 해시되고 인덱스의 개체로 저장되므로 "심각한 변경사항"이 됩니다.
  • 을 할 때git commit인덱스에 저장된 단계별 변경사항은 해당 새 커밋을 만드는 데 사용됩니다.
  • 을 할 때git checkoutGit는 커밋에서 데이터를 가져와 작업 디렉토리와 인덱스에 씁니다.

인덱스는 준비된 변경사항을 저장할 뿐만 아니라 작업 디렉토리에 대한 파일 시스템 정보도 저장합니다.
이렇게 하면 Git가 변경된 파일을 더 빨리 보고할 수 있습니다.


더 보기, cf."git/git/blob/master/Documentation/gitformat-index.txt":

Git 인덱스 파일의 형식은 다음과 같습니다.

모든 이진 숫자는 네트워크 바이트 순서입니다.
버전 2는 달리 명시되지 않은 한 여기에 설명되어 있습니다.

  • 다음으로 구성된 12바이트 헤더:
  • 4바이트 서명:
    서명은 {'입니다.D', 'I', 'R', 'C}(""의 약자)dircache
  • 4바이트 버전 번호:
    현재 지원되는 버전은 2, 3 및 4입니다.
  • 32비트 인덱스 항목 수입니다.
  • 정렬된 인덱스 항목 수입니다.
  • 확장:
    확장은 서명으로 식별됩니다.
    Git가 확장을 이해하지 못하는 경우 선택적 확장을 무시할 수 있습니다.
    Git는 현재 캐시된 트리를 지원하고 실행 취소 확장을 해결합니다.
  • 4바이트 확장자 서명. 번째 ' 번째바인가트 '인 A'..'Z확장은 선택 사항이며 무시할 수 있습니다.
  • 확장의 32비트 크기
  • 확장 데이터
  • 이 체크섬 이전의 인덱스 파일 내용에 160비트 SHA-1.

mljrg 주석:

지수가 다음 커밋을 준비하는 곳이라면, 왜"git ls-files -s커밋 후 아무것도 반환하지 않습니까?

인덱스는 추적되는 내용을 나타내며 커밋 직후에 추적되는 내용은 마지막 커밋(git diff --cached아무것도 반환하지 않음).

그렇게git ls-files -s추적된 모든 파일(출력의 개체 이름, 모드 비트 및 단계 번호)을 나열합니다.

해당 목록(추적된 요소)은 커밋 내용으로 초기화됩니다.
분기를 전환하면 인덱스 내용이 전환한 분기에서 참조하는 커밋으로 재설정됩니다.


Git 2.20(2018년 4분기)은 인덱스 엔트리 오프셋 테이블(IEOT)을 추가했습니다.

커밋 77ff112, 커밋 3255089, 커밋 abb4bb8, 커밋 c780b9c, 커밋 3b1d9e0, 커밋 371ed0d(2018년 10월 10일)를 Ben Peart()에서 참조하십시오.benpeart
252d079 (2018년 9월 26일)를 Nguyễn Thai Ngọc Duy pclouds()의 커밋을 참조하십시오.
(주니오 C 하마노에 의해 합병 -- -- 2018년 10월 19일 위원회 27bfaa에서)

iot: IEOT(인덱스 항목 오프셋 테이블) 확장 추가

이 패치를 사용하면 캐시 항목의 로드 및 변환을 효율적으로 멀티 스레드화할 수 있는 추가 데이터를 인덱스에 추가하여 인덱스를 로드하는 CPU 비용을 해결할 수 있습니다.

인덱스 파일의 캐시 항목 블록에 오프셋 테이블인 (선택 사항) 인덱스 확장을 추가하여 이 작업을 수행합니다.

V4 인덱스에서 이 작업을 수행하려면 캐시 항목을 쓸 때 이전 항목의 경로 이름이 완전히 다른 것처럼 현재 항목을 인코딩하여 주기적으로 접두사 압축을 "재설정"하고 해당 항목의 오프셋을 IOT에 저장합니다.
기본적으로 V4 인덱스를 사용하면 접두사로 압축된 항목 블록으로 오프셋을 생성합니다.

index.threads 구성 설정을 사용하면 인덱스 로드 속도가 빨라집니다.


결과적으로 (IEOT 사용의) 7bd9631 정리를 커밋합니다.read-cache.c load_cache_entries_threaded()Git 2.23(2019년 3분기)에 대한 함수입니다.

커밋 peff8373037, 커밋 713e88, 커밋 92349d, 커밋 113c29a, 커밋 c95fc72, 커밋 7a2a721, 커밋 c016579, 커밋 beb7, 커밋 13a1781, 커밋 7bd9631, 커밋 3c1dce8, 커밋 cf7a901, 커밋 dbc0(2019년 5월 9일)을 참조하십시오.
(주니오 C 하마노에 의해 합병되었습니다 -- -- commit c0e78f7, 2019년 6월 13일)

읽기 캐시: 스레드 로드에서 사용되지 않는 매개 변수 삭제

load_cache_entries_threaded()은 함를사니다를 합니다.src_offset사용하지 않는 매개 변수입니다.이것은 77ff112에 시작된 이래로 존재해 왔습니다.read-cache작업자 스레드에 캐시 항목 로드, 2018-10-10, Git v2.20.0-rc0).

메일링 목록을 살펴보면, 해당 매개 변수는 시리즈의 초기 반복의 일부였지만 코드가 IOT 확장자를 사용하는 것으로 전환되었을 때 필요하지 않게 되었습니다.


Git 2.29 (2020년 4분기)를 사용하여 형식 설명은 최근 SHA-256 작업에 맞게 조정됩니다.

마틴 오그렌()의 커밋 8afa50a, 커밋 0756e61, 커밋 123712b, 커밋 5b6422a(2020년 8월 15일)none 참조.
(주니오 C 하마노에 의해 합병 -- 74a395c, 2020년 8월 19일 커밋)

index-format.txt문서 SHA-256 인덱스 형식

사인 오프 바이: 마틴 오그렌

SHA-1 저장소에서는 SHA-1을 사용하고 SHA-256 저장소에서는 SHA-256을 사용한다는 점을 문서화한 다음 "SHA-1"의 다른 모든 용도를 보다 중립적인 것으로 대체합니다.
"160비트" 해시 값을 참조하지 않도록 합니다.

technical/index-format이제 관리 페이지에 다음 항목이 포함됩니다.

모든 이진 숫자는 네트워크 바이트 순서입니다.
기존 SHA-1을 사용하는 저장소에서는 아래에 언급된 체크섬과 개체 ID(개체 이름)가 모두 SHA-1을 사용하여 계산됩니다.
마찬가지로 SHA-256 저장소에서는 이러한 값이 SHA-256을 사용하여 계산됩니다.

버전 2는 달리 명시되지 않은 한 여기에 설명되어 있습니다.

비트 단위 분석

저는 형식을 더 잘 이해하고 일부 분야를 더 자세히 연구하기 위해 약간의 테스트를 하기로 결정했습니다.

아래의 결과는 Git 버전에 대해서도 동일합니다.1.8.5.2그리고.2.3.

는 제가 잘 못한 을 나는확실점표다시로 했습니다.TODO그 점들을 자유롭게 보완해 주시기 바랍니다.

다른 사람들이 언급했듯이, 인덱스는 다음과 같이 저장됩니다..git/index표준 트리 객체가 아니며, 그 형식은 바이너리이며 다음 사이트에 문서화되어 있습니다. https://github.com/git/git/blob/master/Documentation/technical/index-format.txt

인덱스가 커밋을 생성하기 위한 캐시이기 때문에 인덱스를 정의하는 주요 구조체는 cache.h에 있습니다.

세우다

다음을 사용하여 테스트 저장소를 시작하는 경우:

git init
echo a > b
git add b
tree --charset=ascii

.git디렉터리 모양은 다음과 같습니다.

.git/objects/
|-- 78
|   `-- 981922613b2afb6025042ff6bd878ac1994e85
|-- info
`-- pack

그리고 우리가 유일한 대상의 내용을 얻는다면,

git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85

는 리는우를 받습니다.a이는 다음을 의미합니다.

  • 그자리의 index내용을 . 내용을 가리킵니다.git add b했습니다.
  • BLOB라는 단일 개체만 있었기 때문에 트리 개체가 아닌 인덱스 파일에 메타데이터를 저장합니다(일반 Git 개체에서는 BLOB 메타데이터가 트리에 저장됨).

HD 분석

이제 인덱스 자체를 살펴보겠습니다.

hd .git/index

제공:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 09 76 e6  |DIRC.... ....T.v.|
00000010  1d 81 6f c6 54 09 76 e6  1d 81 6f c6 00 00 08 05  |..o.T.v. ..o.....|
00000020  00 e4 2e 76 00 00 81 a4  00 00 03 e8 00 00 03 e8  |...v.... ........|
00000030  00 00 00 02 78 98 19 22  61 3b 2a fb 60 25 04 2f  |....x.." a;*.`%./|
00000040  f6 bd 87 8a c1 99 4e 85  00 01 62 00 ee 33 c0 3a  |......N. ..b..3.:|
00000050  be 41 4b 1f d7 1d 33 a9  da d4 93 9a 09 ab 49 94  |.AK...3. ......I.|
00000060

다음은 다음과 같이 결론을 내릴 것입니다.

  | 0           | 4            | 8           | C              |
  |-------------|--------------|-------------|----------------|
0 | DIRC        | Version      | File count  | ctime       ...| 0
  | ...         | mtime                      | device         |
2 | inode       | mode         | UID         | GID            | 2
  | File size   | Entry SHA-1                              ...|
4 | ...                        | Flags       | Index SHA-1 ...| 4
  | ...                                                       |

먼저 다음 위치에 정의된 헤더가 나옵니다. struct cache_header:

  • 44 49 52 43:DIRCTODO: 왜 이것이 필요합니까?

  • 00 00 00 02형식 버전: 2.인덱스 형식은 시간이 지남에 따라 발전했습니다.현재 버전은 4까지 존재합니다.GitHub에서 서로 다른 컴퓨터 간에 협업할 때 인덱스의 형식은 문제가 되지 않습니다. 맨 리포지토리는 인덱스를 저장하지 않기 때문입니다. 인덱스는 복제 시 생성됩니다.

  • 00 00 00 01 단 하나, 스에있파일수는하나인: 단덱하,,b.

다음은 struct cache_entry로 정의된 인덱스 항목 목록을 시작합니다. 여기에는 하나만 있습니다.포함되는 항목:

  • 메타데이터 : 음바이터묶: 8이트파일ctime8바이트mtime4바이트: 장치, 아이노드, 모드, UID 및 GID.

    참고 방법:

    • ctime그리고.mtime (동일(일54 09 76 e6 1d 81 6f c6입니다.

      첫 번째 바이트는 EPOH 이후의 초(16진수)입니다.

      date --date="@$(printf "%x" "540976e6")"
      

      제공:

      Fri Sep  5 10:40:06 CEST 2014
      

      그 때 제가 이 예를 만들었습니다.

      두 번째 4바이트는 나노초입니다.

    • 및 는 UID 는 GID 와00 00 03 e81000 in 16진수: 단일 사용자 설정에 대한 공통 값.

    대부분 트리 개체에 존재하지 않는 이 모든 메타데이터를 통해 Git는 전체 내용을 비교하지 않고 파일이 빠르게 변경되었는지 확인할 수 있습니다.

  • 줄의맨행의 에.30:00 00 00 02 크기:파일 이름: 2바이트 (a그리고.\necho)

  • 78 98 19 22 ... c1 99 4e 85항목의 이전 내용에 대한 20바이트 SHA-1.유효 플래그를 가정한 제 실험에 따르면, 그 뒤에 오는 플래그는 이 SHA-1에서 고려되지 않습니다.

  • 플래그: 2바이트 플래그:00 01

    • 1비트: 유효한 플래그로 가정합니다.제가 조사한 바로는 이 이름이 잘못된 깃발이git update-index --assume-unchanged상태 저장: https://stackoverflow.com/a/28657085/895245

    • 1비트 확장 플래그입니다.확장된 플래그가 있는지 여부를 결정합니다. .0확장 플래그가 없는 버전 2.

    • 병합하는 동안 사용된 2비트 단계 플래그입니다.는 계는다음설있다습니어명에 기록되어 .man git-merge:

      • 0파일입니다.
      • 1기저의
      • 2우리의
      • 3의 집

      충돌 되어 병합충의 1-3모든과 같은 을 수행할 수 .git checkout --ours.

      네가 만약git add그런 다음 0단계가 경로에 대한 인덱스에 추가되고 Git는 충돌이 해결된 것으로 표시되었음을 알게 됩니다.TODO: 이것을 확인합니다.

    • 오는 길이: " " " " " "0 01경로가 다음과 같았기 때문에 1바이트만b

  • 2바이트 확장 플래그입니다.기본 플래그에 "확장 플래그"가 설정된 경우에만 의미가 있습니다.하기 위해서.

  • 62ASCII(ASCII)b length path . :: 의 길이입니다., 이전플그에결바길이정된, 여는서트 1이래서,b.

나서 그고나서a가 .00경로가 null-termination되고 인덱스가 8바이트의 배수로 끝나도록 1-8바이트의 제로 패딩.이것은 인덱스 버전 4 이전에만 발생합니다.

사용된 확장자가 없습니다.Git는 파일에 체크섬을 위한 공간이 충분하지 않기 때문에 이를 알고 있습니다.

마지막으로 20바이트 체크섬이 있습니다.ee 33 c0 3a .. 09 ab 49 94인덱스의 내용을 초과합니다.

Git 색인은 작업 디렉토리와 리포지토리 사이의 준비 영역입니다.인덱스를 사용하여 함께 커밋할 변경사항 집합을 작성할 수 있습니다.커밋을 만들 때 커밋되는 것은 작업 디렉토리에 있는 것이 아니라 현재 인덱스에 있는 것입니다.

인덱스 내부의 내용을 확인하려면 다음 명령을 실행합니다.

git status

Git 상태를 실행하면 현재 인덱스에 준비되어 있는 파일, 수정되었지만 아직 준비되지 않은 파일 및 추적되지 않은 파일을 볼 수 있습니다.

읽을 수 있어요.구글 검색은 많은 링크를 표시하는데, 이는 상당히 충분할 것입니다.

파일입니다(으로 Git 인일이다니파덱일입진보됨관스는로으반적일▁g▁in(▁(▁g▁is▁file다▁agener▁binary됨보덱관니인)입니다..git/index) 이름의 하며, 을 포함합니다경로이름의며포하함체개및의각, 각권한렬된을 SHA1.

git ls-files인덱스의 내용을 표시할 수 있습니다.그 단어들을 주의하세요.index,stage,그리고.cacheGit에서도 같은 것입니다. 상호 교환적으로 사용됩니다.

enter image description here

Git 인덱스 또는 Git 캐시에는 세 가지 중요한 속성이 있습니다.

  1. 인덱스에는 단일(고유하게 결정된) 트리 개체를 생성하는 데 필요한 모든 정보가 포함됩니다.
  2. 인덱스를 사용하면 정의한 트리 개체와 작업 트리를 빠르게 비교할 수 있습니다.
  3. 서로 다른 트리 개체 간의 병합 충돌에 대한 정보를 효율적으로 나타낼 수 있으므로 각 경로 이름을 관련 트리에 대한 충분한 정보와 연결하여 트리 간에 3방향 병합을 만들 수 있습니다.

출처:

  1. https://mincong.io/2018/04/28/git-index/
  2. https://medium.com/hackernoon/understanding-git-index-4821a0765cf

@ciro-santilli-%e9%83%9d%e6%b7%e4%b8%b8%9c%e5%86%e7%b6%e7%e7%97%85%e5%ad%e5%e5%e4%b8%e4%b4%b4%b6%b3%e8%e8%의 세부적인 A8%의 출력을 공유하기 위해 AM8%에 대해 살펴봅니다.

"git를 추가하면 0단계가 경로에 대한 인덱스에 추가되고, Git는 충돌이 해결된 것으로 표시되었음을 알게 됩니다.TODO: 이것을 확인합니다."

그리고, 좀 더 구체적으로, 다른 병합 단계.

  • 0: 병합 충돌이 아닌 일반 파일
  • 1: 베이스
  • 2: 우리 것
  • 3: 그들의

다양한 단계(이 경우 충돌이 있는 파일)의 수치 표현에 대한 세부 정보입니다.

$ git ls-files -s
100644 f72d68f0d10f6efdb8adc8553a1df9c0444a0bec 0       vars/buildComponent.groovy

$ git stash list
stash@{0}: WIP on master: c40172e turn off notifications, temporarily

$ git stash apply
Auto-merging vars/commonUtils.groovy
Auto-merging vars/buildComponent.groovy
CONFLICT (content): Merge conflict in vars/buildComponent.groovy

$ git ls-files -s
100644 bc48727339d36f5d54e14081f8357a0168f4c665 1       vars/buildComponent.groovy
100644 f72d68f0d10f6efdb8adc8553a1df9c0444a0bec 2       vars/buildComponent.groovy
100644 24dd5be1783633bbb049b35fc01e8e88facb20e2 3       vars/buildComponent.groovy

정확히 필요한 것은 다음과 같습니다. 이 명령을 사용하십시오.

$ binwalk index

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1717          0x6B5           Unix path: /company/user/user/delete.php
1813          0x715           Unix path: /company/user/user/get.php
1909          0x775           Unix path: /company/user/user/post.php
2005          0x7D5           Unix path: /company/user/user/put.php
3373          0xD2D           Unix path: /urban-airship/channel/channel/post.php
3789          0xECD           Unix path: /urban-airship/named-user/named-user/post.php
3901          0xF3D           Unix path: /user/categories/categories/delete.php
4005          0xFA5           Unix path: /user/categories/categories/get.php
4109          0x100D          Unix path: /user/categories/categories/put.php
4309          0x10D5          Unix path: /user/favorites/favorites/delete.php

그냥 링에 깃 나무를 넣고 싶었어요.

지수는 git에서 가장 중요한 데이터 구조 중 하나입니다.
경로 목록과 해당 개체 이름을 기록하여 가상 작업 트리 상태를 나타내며 커밋할 다음 트리 개체를 쓰기 위한 준비 영역 역할을 합니다.
상태는 작업 트리의 파일과 일치할 필요가 없으며 종종 일치하지 않는다는 점에서 "가상"입니다.

특별한 커밋을 체크아웃한 경우 gits-tree가 어떤 작업 파일/객체가 있어야 하는지 정확히 알려준다고 하는 것이 사실입니까?ls-tree의 맥락에서 우리는 어떤 종류의 나무에 대해 이야기합니까?

git ls-tree -r -l HEAD
git ls-tree -r -l commit-hash

BTW: ls-tree는 체크아웃(-n) 없이 복제된 리포지토리에서도 작동합니다. 여기서 ls-files는 아무것도 반환하지 않습니다.

https://stackoverflow.com/a/56242906/2623045

https://stackoverflow.com/a/67567058/2623045

언급URL : https://stackoverflow.com/questions/4084921/what-does-the-git-index-contain-exactly

반응형