Sự khác biệt giữa CHÍNH, cây làm việc và chỉ mục, trong Git là gì?


488

Ai đó có thể cho tôi biết sự khác biệt giữa CHÍNH, cây làm việc và chỉ mục, trong Git không?

Từ những gì tôi hiểu, tất cả chúng đều là tên của các ngành khác nhau. Là giả định của tôi đúng?


Biên tập

tôi đã tìm thấy cái này

Một kho lưu trữ git duy nhất có thể theo dõi số lượng nhánh tùy ý, nhưng cây làm việc của bạn được liên kết với chỉ một trong số chúng (nhánh "hiện tại" hoặc "đã kiểm tra") và ĐẦU trỏ tới nhánh đó.

Điều này có nghĩa là TRỤ và cây làm việc luôn giống nhau phải không?


26
Đối với chỉnh sửa của bạn: hoàn toàn không. HEADlà cam kết ở đầu chi nhánh hiện tại. Nếu bạn vừa kiểm tra chi nhánh, tức là không có tệp sửa đổi, thì nội dung của nó phù hợp với cây làm việc. Ngay khi bạn sửa đổi bất cứ điều gì, nó không còn phù hợp.
Cascabel

6
Tôi nghĩ bạn phải đọc cái này: think-like-a-git.net
Andrzej Duś

5
Tôi cũng sẽ thêm một Staging Areadanh sách đó. Là gì HEAD, Working Tree, Indexvà mộtStaging Area
Xanh

2
Câu cuối cùng của @ Jefromi's sẽ rõ ràng hơn là:> Ngay sau khi bạn sửa đổi bất cứ điều gì, cây làm việc không còn phù hợp với cam kết CHÍNH
starscream_disco_party

3
Đối với bất kỳ việc đọc nào trong tương lai, cách tốt nhất để thực sự hiểu một số câu trả lời này là xem và cảm nhận và khái niệm trực quan những gì đang diễn ra: đây là công cụ tốt nhất để học git bao giờ: onlywei.github.io/explain-git-with -d3 / # fetchrebase
BKSpurgeon

Câu trả lời:


579

Một vài tài liệu tham khảo tốt khác về các chủ đề đó:

văn bản thay thế

Tôi sử dụng chỉ số như một điểm kiểm tra .

Khi tôi chuẩn bị thực hiện một thay đổi có thể trở nên tồi tệ - khi tôi muốn khám phá một số hướng mà tôi không chắc mình có thể làm theo hay thậm chí đó có phải là một ý tưởng hay không, chẳng hạn như tái cấu trúc theo yêu cầu về mặt khái niệm hoặc thay đổi loại đại diện - Tôi kiểm tra công việc của tôi vào chỉ mục. Nếu đây là thay đổi đầu tiên tôi thực hiện kể từ lần cam kết cuối cùng, thì tôi có thể sử dụng kho lưu trữ cục bộ làm điểm kiểm tra, nhưng thường thì tôi có một thay đổi về mặt khái niệm mà tôi đang thực hiện như một bộ các bước nhỏ. Tôi muốn kiểm tra điểm sau mỗi bước, nhưng lưu lại cam kết cho đến khi tôi quay lại làm việc, kiểm tra mã.

Ghi chú:

  1. các không gian làm việc là cây thư mục của (nguồn) các tập tin mà bạn nhìn thấy và chỉnh sửa.

  2. Các chỉ số là một duy nhất, lớn, tập tin nhị phân trong <baseOfRepo>/.git/index, trong đó liệt kê tất cả các file trong ngành hiện tại, họ sha1 checksums, tem thời gian và tên tập tin - nó không phải là một thư mục với một bản sao của tập tin trong nó.

  3. Các kho lưu trữ địa phương là một thư mục ẩn ( .git) bao gồm một objectsthư mục chứa tất cả các phiên bản của tất cả các tập tin trong repo (chi nhánh và bản sao của chi nhánh từ xa địa phương) như là một tập tin "blob" nén.

Đừng nghĩ bốn 'đĩa' được thể hiện trong hình trên là các bản sao riêng biệt của các tệp repo.

văn bản thay thế

Chúng cơ bản được đặt tên tham chiếu cho các cam kết Git. Có hai loại refs chính: tags và head.

  • Thẻ là các tham chiếu cố định đánh dấu một điểm cụ thể trong lịch sử, ví dụ v2.6,29.
  • Ngược lại, người đứng đầu luôn được di chuyển để phản ánh vị trí hiện tại của phát triển dự án.

văn bản thay thế

(lưu ý: như nhận xét của Timo Huovinen , những mũi tên đó không phải là thứ mà cam kết chỉ ra, đó là thứ tự quy trình công việc , về cơ bản hiển thị mũi tên là 1 -> 2 -> 3 -> 4nơi 1cam kết đầu tiên và 4là lần cuối cùng)

Bây giờ chúng tôi biết những gì đang xảy ra trong dự án.
Nhưng để biết những gì đang xảy ra ngay tại đây, ngay bây giờ có một tài liệu tham khảo đặc biệt gọi là CHÍNH. Nó phục vụ hai mục đích chính:

  • nó cho Git biết cam kết lấy tệp từ khi bạn thanh toán và
  • nó cho Git biết nơi đặt cam kết mới khi bạn cam kết.

Khi bạn chạy, git checkout refnó trỏ HEADđến ref bạn đã chỉ định và trích xuất các tệp từ nó. Khi bạn chạy git commitnó sẽ tạo ra một đối tượng cam kết mới, trở thành một đứa con của hiện tại HEAD. Thông thường HEADchỉ vào một trong những cái đầu, vì vậy mọi thứ hoạt động tốt.

văn bản thay thế


20
Sau khi đọc về git rất nhiều lần, tôi chưa bao giờ hiểu nó hoàn toàn. Tôi thực sự thất vọng n Tôi muốn sử dụng từ f; Nhưng tôi đang ở trong cộng đồng! Bạn đã đề cập đến những cái đầu nhưng trong các hình ảnh ở trên luôn có một cái đầu duy nhất trong đó những cái đầu còn lại? "Thông thường ĐẦU chỉ vào một trong những cái đầu, vì vậy mọi thứ đều ổn." Tôi cầu xin bạn giải thích điều này, Ur tuyên bố.
Necktwi

12
@neckTwi HEAD là cam kết hiện tại bạn đang làm việc ( stackoverflow.com/a/964927/6309 ). Nó thường là một trong những "đầu chi nhánh" (một trong những cam kết được tham chiếu bởi các nhánh, đại diện cho đỉnh của các nhánh nói trên). Nhưng bạn có thể kiểm tra (và làm việc trên) bất kỳ cam kết nào. Nếu bạn kiểm tra một cam kết không phải là một trong những người đứng đầu (chi nhánh), bạn đang ở chế độ "tách rời": stackoverflow.com/a/3965714/6309
VonC

1
@Imray Tôi đồng ý, nhưng đó là cách tôi tìm thấy những bức ảnh đó 5 năm trước ( hades.name/blog/2010/01/11/iêu )
VonC

11
Về chỉ số, tôi nghĩ điều hữu ích nhất có thể nói là "Chỉ số này chỉ là một tên gọi khác của khu vực tổ chức", như @ ashraf-alam nói. Tôi cảm thấy như hầu hết thời gian trong cuộc thảo luận, nó được gọi là khu vực tổ chức, đó là lý do tại sao tôi không tự động thực hiện kết nối rằng đó là điều tương tự như chỉ mục.
Pete

1
@Pete Tôi đồng ý. Để biết thêm về sự khác biệt giữa bộ đệm và chỉ mục, hãy xem câu trả lời khác của tôi stackoverflow.com/a/6718135/6309
VonC

137

Sự khác biệt giữa HEAD (nhánh hiện tại hoặc trạng thái cam kết cuối cùng trên nhánh hiện tại), chỉ mục (còn gọi là khu vực tổ chức) và cây làm việc (trạng thái của các tệp trong thanh toán) được mô tả trong phần "Ba trạng thái" của "Cơ bản 1.3 Git " chương của cuốn sách Pro Git của Scott Chacon (Creative Commons được cấp phép).

Đây là hình ảnh minh họa nó từ chương này:

Hoạt động cục bộ - thư mục làm việc so với khu vực tổ chức (chỉ mục) so với kho git (HEAD)

Trong hình trên, "thư mục làm việc" giống như "cây làm việc", "khu vực tổ chức" là một tên thay thế cho git "index" và HEAD trỏ đến chi nhánh hiện đang được kiểm tra, điểm này chỉ ra cam kết cuối cùng trong " thư mục git (kho lưu trữ) "

Lưu ý rằng git commit -asẽ thay đổi giai đoạn và cam kết trong một bước.


1
"Một bưc tranh đang gia ngan lơi noi". Cảm ơn Jakub .. Và cảm ơn vì liên kết.
Joyce Babu

5
Lưu ý: working treedường như được ưa thích cho đến working directoryngày nay. Xem github.com/git/git/commit/ Mạnh
VonC

3
Bức ảnh này không chính xác vì Khu vực tổ chức được chứa trong một tệp có tên là "index" - và tệp chỉ mục đó nằm trong thư mục gốc của thư mục .git. Vì vậy, nếu bạn xác định repo là thư mục .git, khu vực tổ chức là về mặt kỹ thuật bên trong repo. Cột thứ ba sẽ được gắn nhãn tốt hơn "Đối tượng cây gốc của HEAD" để chỉ ra rằng các tệp đã kiểm tra đang đến từ một đối tượng cam kết và cam kết ghi một cây mới vào một đối tượng cam kết - cả hai đối tượng cam kết đều được chỉ ra bởi HEAD.
Jazimov

@Jazimov Có lẽ bạn đúng, nhưng khi anh ấy viết, anh ấy đã lấy bức ảnh đó từ cuốn sách Pro Git nổi tiếng, và anh ấy đã cung cấp một liên kết. Do đó, nếu bức tranh có thể được cải thiện hoặc thậm chí sai, ai đó nên nói với các tác giả của cuốn sách đó ... Nói chung, tôi sẽ sẵn sàng làm điều đó, nhưng thành thật mà nói, tôi vẫn là một người mới bắt đầu và chưa hiểu những gì bạn nói, vì vậy tôi chắc chắn là người sai trong trường hợp đó.
Binarus

@Binarus: Điều nguy hiểm trong việc tái tạo hình ảnh bán buôn như thế này là nó dùng để tuyên truyền một "sự xuyên tạc" được thực hiện bởi một tác giả / cuốn sách. Tôi nghĩ rằng đây là một trường hợp diễn giải theo nghĩa đen và chức năng ở đây: Theo nghĩa đen, thực tế chỉ mục được chứa trong repo nếu bạn định nghĩa repo là mọi thứ trong thư mục .git. Tuy nhiên, trong ý nghĩa chức năng, chỉ số giúp Git duy trì DAG trong repo và có thể được coi là bên ngoài đối với nó.
Jazimov

64

Cây làm việc của bạn là những gì thực sự có trong các tệp mà bạn hiện đang làm việc.

HEADlà một con trỏ tới nhánh hoặc cam kết mà bạn đã kiểm tra lần cuối và nó sẽ là cha mẹ của một cam kết mới nếu bạn thực hiện nó. Chẳng hạn, nếu bạn ở masterchi nhánh, sau đó HEADsẽ trỏ đến mastervà khi bạn cam kết, cam kết mới đó sẽ là hậu duệ của bản sửa đổi được masterchỉ ra và mastersẽ được cập nhật để trỏ đến cam kết mới.

Các chỉ số là một khu vực dàn nơi mới cam kết sẵn sàng. Về cơ bản, nội dung của chỉ mục là những gì sẽ đi vào cam kết mới (mặc dù nếu bạn thực hiện git commit -a, điều này sẽ tự động thêm tất cả các thay đổi vào các tệp mà Git biết về chỉ mục trước khi cam kết, vì vậy nó sẽ cam kết nội dung hiện tại của cây làm việc của bạn ). git addsẽ thêm hoặc cập nhật các tệp từ cây làm việc vào chỉ mục của bạn.


Cảm ơn rất nhiều vì lời giải thích Brian. Vì vậy, cây làm việc chứa tất cả các thay đổi không được cam kết. Nếu tôi cam kết thay đổi của mình với git commit -a, thì tại thời điểm cụ thể đó, Cây làm việc và Chỉ mục của tôi sẽ giống nhau. Khi tôi đẩy đến repo trung tâm của mình, cả ba sẽ giống nhau. Tôi có đúng không?
Joyce Babu

3
@Vinod Khá nhiều. Bạn có thể có các tệp trong cây làm việc mà Git không biết và chúng không được cam kết git commit -a(bạn cần thêm chúng git add), vì vậy cây làm việc của bạn có thể có thêm các tệp mà chỉ mục, repo cục bộ của bạn hoặc repo từ xa của bạn không có.
Brian Campbell

2
@Vinod: Cây làm việc và chỉ mục có thể trở nên giống nhau mà không cần cam kết (git add cập nhật chỉ mục từ cây làm việc và kiểm tra git <path> cập nhật cây làm việc từ chỉ mục). HEADđề cập đến cam kết gần đây nhất, vì vậy khi bạn cam kết, bạn đang cập nhật HEADlên cam kết mới, phù hợp với chỉ mục. Đẩy không liên quan nhiều đến nó - nó tạo ra các nhánh trong các nhánh khớp từ xa trong repo cục bộ của bạn.
Cascabel

45

Cây làm việc

Cây làm việc của bạn là các tệp mà bạn hiện đang làm việc.

Chỉ số Git

  • "Chỉ mục" git là nơi bạn đặt các tệp bạn muốn cam kết vào kho git.

  • Chỉ số này cũng được gọi là bộ nhớ cache , bộ nhớ cache thư mục , bộ nhớ cache thư mục hiện hành , khu vực dàn dựng , file dàn dựng .

  • Trước khi bạn "cam kết" (kiểm tra) các tệp vào kho git, trước tiên bạn cần đặt các tệp vào "chỉ mục" git.

  • Chỉ mục không phải là thư mục làm việc: bạn có thể nhập một lệnh như git status, và git sẽ cho bạn biết những tệp nào trong thư mục làm việc của bạn đã được thêm vào chỉ mục git (ví dụ: bằng cách sử dụng git add filenamelệnh).

  • Chỉ mục không phải là kho git: các tệp trong chỉ mục git là các tệp mà git sẽ cam kết với kho git nếu bạn sử dụng lệnh git commit.


1
Lưu ý rằng Git 2.5 sẽ mang lại nhiều cây làm việc ( stackoverflow.com/a/30185564/6309 ). +1
VonC

3
Tôi không chắc chắn rằng "Chỉ mục không phải là thư mục làm việc" là chính xác 100%. Nó phải là "Chỉ mục không phải là Thư mục làm việc, nhưng nó bao gồm toàn bộ thư mục làm việc + những thay đổi bạn muốn được cam kết tiếp theo". Bằng chứng? đi đến kho git, reset --hard HEADđể đảm bảo rằng chỉ mục của bạn == cây làm việc của bạn. an then: mkdir history && git checkout-index --prefix history/ -aKết quả là một bản sao của toàn bộ cây làm việc trong history/thư mục của bạn . Ergo git index> = git thư mục làm việc
Adam Kurkiewicz 21/07/2015

3
Index không phải là thư mục làm việc và không phải bao gồm thư mục làm việc. Index chỉ là một tệp trong kho git lưu trữ thông tin những gì bạn muốn cam kết.
Boon

3
"" Chỉ mục "giữ một ảnh chụp nhanh nội dung của cây làm việc và đó là ảnh chụp nhanh này được lấy làm nội dung của cam kết tiếp theo. Do đó, sau khi thực hiện bất kỳ thay đổi nào đối với thư mục làm việc và trước khi chạy lệnh commit, bạn phải sử dụng lệnh add để thêm bất kỳ tệp mới hoặc sửa đổi nào vào chỉ mục "( git-scm.com/docs/git-add )
anth

3
@AdamKurkiewicz: bằng chứng thất bại nếu bạn trước echo untracked-data > untracked-file, trước hoặc sau git reset --HARDgit checkout-indexcác bước. Bạn sẽ thấy rằng untracked tập tin là không trong historythư mục. Bạn cũng có thể sửa đổi độc lập cả chỉ mục và cây công việc, mặc dù sửa đổi chỉ mục mà không chạm vào cây công việc trước là khó (yêu cầu sử dụng git update-index --index-info).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.