Lưu ý: một trong những khác biệt lớn nhất giữa Git và Mercurial là sự hiện diện rõ ràng của chỉ mục hoặc khu vực tổ chức .
Từ Mercurial dành cho Người dùng Git :
Git là DistributedSCM duy nhất đưa ra khái niệm về chỉ mục hoặc vùng tổ chức. Những người khác có thể thực hiện và ẩn nó, nhưng không có trường hợp nào khác, người dùng không biết cũng như không phải xử lý nó.
Tương đương thô của Mercurial là DirState
kiểm soát thông tin trạng thái bản sao đang hoạt động để xác định các tệp được đưa vào cam kết tiếp theo. Nhưng trong mọi trường hợp, tệp này được xử lý tự động.
Ngoài ra, có thể lựa chọn nhiều hơn tại thời điểm cam kết bằng cách chỉ định các tệp bạn muốn cam kết trên dòng lệnh hoặc bằng cách sử dụng RecordExtension
.
Nếu bạn cảm thấy không thoải mái khi xử lý chỉ mục, bạn đang chuyển đổi để tốt hơn ;-)
Bí quyết là, bạn thực sự cần hiểu chỉ mục để khai thác đầy đủ Git. Như bài báo này từ tháng 5 năm 2006 nhắc nhở chúng ta sau đó (và nó vẫn đúng đến bây giờ):
"Nếu bạn từ chối Chỉ mục, bạn thực sự phủ nhận chính git."
Bây giờ, bài viết đó chứa nhiều lệnh mà bây giờ đơn giản hơn để sử dụng (vì vậy đừng dựa vào nội dung của nó quá nhiều;)), nhưng ý tưởng chung vẫn là:
Bạn đang làm việc trên một tính năng mới và bắt đầu thực hiện các sửa đổi nhỏ trên một tệp.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
Tại thời điểm này, cam kết tiếp theo của bạn sẽ thực hiện 2 sửa đổi nhỏ trong nhánh hiện tại
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
Chỉ ghi lại những thay đổi được thêm vào vùng tổ chức (chỉ mục) tại thời điểm này, chứ không phải những thay đổi lớn hiện có trong thư mục làm việc của bạn.
$ git branch newFeature_Branch
$ git add myFile
Cam kết tiếp theo sẽ ghi lại tất cả các thay đổi lớn khác trong nhánh mới 'newFntic_Branch'.
Giờ đây, thêm tương tác hoặc thậm chí tách cam kết là các tính năng có sẵn với Mercurial, thông qua hg record
lệnh '' hoặc các tiện ích mở rộng khác: bạn sẽ cần cài đặt RecordExtension
, hoặc CrecordExtension
.
Nhưng đây không phải là một phần của quy trình làm việc bình thường của Mercurial.
Git xem một cam kết là một loạt " thay đổi nội dung tệp " và cho phép bạn thêm những thay đổi đó cùng một lúc.
Bạn nên nghiên cứu tính năng đó và hậu quả của nó: Hầu hết sức mạnh Git (như khả năng dễ dàng hoàn nguyên một hợp nhất (hoặc chia nhỏ vấn đề, hoặc hoàn nguyên một cam kết) , trái ngược với Mercurial ) đến từ mô hình "nội dung tệp" đó.
tonfa (trong hồ sơ: "Hg dev, pythonist": figure ...) đã tham gia, trong phần nhận xét:
Về cơ bản, không có gì "git-ish" trong chỉ mục, hg có thể sử dụng một chỉ mục nếu nó được coi là có giá trị, trên thực tế mq
hoặc shelve
đã thực hiện một phần của việc đó.
Oh Boy. Lại đây.
Đầu tiên, tôi không ở đây để làm cho một công cụ này trông đẹp hơn một công cụ khác. Tôi thấy Hg tuyệt vời, rất trực quan, với sự hỗ trợ tốt (đặc biệt là trên Windows, nền tảng chính của tôi, mặc dù tôi cũng làm việc trên Linux và Solaris8 hoặc 10).
Chỉ mục này thực sự ở phía trước và trung tâm theo cách Linus Torvalds hoạt động với VCS :
Git đã sử dụng các bản cập nhật chỉ mục rõ ràng từ ngày 1, ngay cả trước khi nó thực hiện lần hợp nhất đầu tiên. Đó chỉ đơn giản là cách tôi luôn làm việc. Tôi có xu hướng có cây bẩn, với một số bản vá ngẫu nhiên trong cây của tôi mà tôi không muốn cam kết, vì nó chỉ là bản cập nhật Makefile cho phiên bản tiếp theo
Giờ đây, sự kết hợp của chỉ mục (không phải là khái niệm chỉ thấy trong Git) và mô hình "content is king" làm cho nó trở nên khá độc đáo và "git-ish" :
git là một trình theo dõi nội dung và tên tệp không có ý nghĩa trừ khi được liên kết với nội dung của nó. Do đó, hành vi tốt nhất cho git add filename là thêm nội dung của tệp cũng như tên của nó vào chỉ mục.
Lưu ý: "nội dung", ở đây, được định nghĩa như sau :
Chỉ mục của Git về cơ bản được định nghĩa rất nhiều là
- đủ để chứa toàn bộ " nội dung " của cây (và điều này bao gồm tất cả siêu dữ liệu: tên tệp, chế độ và nội dung tệp là tất cả các phần của "nội dung" và tất cả chúng đều vô nghĩa! )
- thông tin "thống kê" bổ sung để cho phép tối ưu hóa so sánh hệ thống tệp rõ ràng và nhỏ (nhưng cực kỳ quan trọng!).
Vì vậy, bạn thực sự nên xem các chỉ số như là nội dung .
Nội dung không phải là "tên tệp" hoặc "nội dung tệp" là các phần riêng biệt. Bạn thực sự không thể tách rời hai người .
Bản thân tên tệp không có nghĩa lý gì (chúng cũng phải có nội dung tệp) và nội dung tệp riêng của nó cũng vô nghĩa tương tự (bạn phải biết cách tiếp cận nó).
Điều tôi muốn nói là về cơ bản git không cho phép bạn xem tên tệp mà không có nội dung của nó. Toàn bộ khái niệm là điên rồ và không có giá trị. Nó không liên quan đến "thực tế".
Từ Câu hỏi thường gặp , những lợi thế chính là:
- cam kết với độ chi tiết tốt
- giúp bạn giữ một sửa đổi không giới hạn trong cây của mình trong một thời gian dài hợp lý
- thực hiện một số bước nhỏ cho một cam kết, kiểm tra những gì bạn đã làm với
git diff
và xác thực từng bước nhỏ với git add
hoặc git add -u
.
- cho phép quản lý xuất sắc của các cuộc xung đột hợp nhất:
git diff --base
, git diff --ours
, git diff --theirs
.
- chỉ cho phép
git commit --amend
sửa đổi thông báo nhật ký nếu chỉ mục chưa được sửa đổi trong thời gian chờ đợi
Cá nhân tôi nghĩ hành vi này không nên là mặc định, bạn muốn mọi người cam kết một cái gì đó đã được kiểm tra hoặc ít nhất là được biên dịch
Mặc dù bạn nói chung là đúng (về phần "đã được kiểm tra hoặc biên dịch"), cách Git cho phép bạn phân nhánh và hợp nhất (hái quả anh đào hoặc phục hồi) cho phép bạn cam kết thường xuyên như bạn muốn trong một nhánh riêng tạm thời (chỉ được đẩy vào kho lưu trữ "sao lưu" từ xa), trong khi thực hiện lại những "cam kết xấu xí" đó trên một nhánh công cộng, với tất cả các thử nghiệm phù hợp.