Nếu tôi hiểu họ một cách chính xác (và tôi cách xa một chuyên gia về từng người) thì về cơ bản, mỗi người có một triết lý khác nhau. Lần đầu tiên tôi sử dụng thủy ngân trong 9 tháng. Bây giờ tôi đã sử dụng git cho 6.
hg là phần mềm kiểm soát phiên bản. Mục tiêu chính của nó là theo dõi các phiên bản của một phần mềm.
git là một hệ thống tập tin dựa trên thời gian. Mục tiêu của nó là thêm một chiều khác cho một hệ thống tệp. Hầu hết có tập tin và thư mục, git thêm thời gian. Rằng nó hoạt động tuyệt vời vì một VCS là sản phẩm phụ của thiết kế.
Trong hg, có một lịch sử của toàn bộ dự án mà nó luôn cố gắng duy trì. Theo mặc định, tôi tin rằng hg muốn tất cả các thay đổi cho tất cả các đối tượng bởi tất cả người dùng khi đẩy và kéo.
Trong git chỉ có một nhóm các đối tượng và các tệp theo dõi này (các nhánh / đầu) xác định tập hợp các đối tượng đó đại diện cho cây các tệp ở trạng thái cụ thể. Khi đẩy hoặc kéo git chỉ gửi các đối tượng cần thiết cho các nhánh cụ thể mà bạn đang đẩy hoặc kéo, đó là một tập hợp nhỏ của tất cả các đối tượng.
Theo như git có liên quan thì không có "1 dự án". Bạn có thể có 50 dự án trong cùng một repo và git sẽ không quan tâm. Mỗi người có thể được quản lý riêng trong cùng một repo và sống tốt.
Khái niệm chi nhánh của Hg là các chi nhánh ngoài dự án chính hoặc các chi nhánh ngoài chi nhánh, vv Git không có khái niệm đó. Một nhánh trong git chỉ là một trạng thái của cây, mọi thứ đều là một nhánh trong git. Chi nhánh nào là chính thức, hiện tại hoặc mới nhất không có ý nghĩa gì trong git.
Tôi không biết điều đó có ý nghĩa gì không. Nếu tôi có thể vẽ hình ảnh hg có thể trông như thế này trong đó mỗi cam kết là mộto
o---o---o
/
o---o---o---o---o---o---o---o
\ /
o---o---o
Một cái cây với một gốc và các nhánh mọc ra từ nó. Trong khi git có thể làm điều đó và mọi người thường sử dụng nó theo cách đó không được thi hành. Một hình ảnh git, nếu có một điều như vậy, có thể dễ dàng trông như thế này
o---o---o---o---o
o---o---o---o
\
o---o
o---o---o---o
Trong thực tế, theo một số cách, nó thậm chí không có ý nghĩa để hiển thị các nhánh trong git.
Một điều rất khó hiểu cho các cuộc thảo luận, cả git và đồng bóng đều có một thứ gọi là "nhánh" nhưng chúng không phải là những thứ giống nhau. Một nhánh trong đồng bóng xuất hiện khi có xung đột giữa các repos khác nhau. Một nhánh trong git rõ ràng tương tự như một bản sao trong hg. Nhưng một bản sao, trong khi nó có thể cho hành vi tương tự chắc chắn là không giống nhau. Hãy xem xét tôi thử những thứ này trong git vs hg bằng cách sử dụng repo crom khá lớn.
$ time git checkout -b some-new-branch
Switched to new branch 'some-new-branch'
real 0m1.759s
user 0m1.596s
sys 0m0.144s
Và bây giờ trong hg sử dụng bản sao
$ time hg clone project/ some-clone/
updating to branch default
29387 files updated, 0 files merged, 0 files removed, 0 files unresolved.
real 0m58.196s
user 0m19.901s
sys 0m8.957
Cả hai đều là chạy nóng. Tức là tôi đã chạy chúng hai lần và đây là lần chạy thứ hai. hg clone thực sự giống như git-new-workdir. Cả hai đều tạo ra một thư mục làm việc hoàn toàn mới gần như thể bạn đã gõ cp -r project project-clone
. Điều đó không giống như tạo ra một nhánh mới trong git. Đó là trọng lượng nặng hơn nhiều. Nếu có sự tương đương thực sự của phân nhánh git trong hg tôi không biết nó là gì.
Tôi hiểu ở một số cấp độ hg và git có thể có thể làm những điều tương tự. Nếu vậy thì vẫn có một sự khác biệt rất lớn trong quy trình làm việc mà họ dẫn bạn đến. Trong git, quy trình làm việc điển hình là tạo một nhánh cho mọi tính năng.
git checkout master
git checkout -b add-2nd-joypad-support
git checkout master
git checkout -b fix-game-save-bug
git checkout master
git checkout -b add-a-star-support
Điều đó chỉ tạo ra 3 nhánh, mỗi nhánh dựa trên một nhánh gọi là master. (Tôi chắc chắn rằng có một số cách trong git để tạo 1 dòng đó mỗi dòng thay vì 2)
Bây giờ để làm việc trên một tôi chỉ cần làm
git checkout fix-game-save-bug
và bắt đầu làm việc. Cam kết mọi thứ, vv Chuyển đổi giữa các chi nhánh ngay cả trong một dự án lớn như chrome là gần như ngay lập tức. Tôi thực sự không biết làm thế nào để làm điều đó trong hg. Nó không phải là một phần của bất kỳ hướng dẫn nào tôi đã đọc.
Một sự khác biệt lớn khác. Sân khấu của Git.
Git có ý tưởng về một sân khấu. Bạn có thể nghĩ về nó như một thư mục ẩn. Khi bạn cam kết, bạn chỉ cam kết những gì trên sân khấu, không phải là những thay đổi trong cây làm việc của bạn. Nghe có vẻ lạ. Nếu bạn muốn thực hiện tất cả các thay đổi trong cây làm việc của mình, bạn sẽ git commit -a
thêm tất cả các tệp đã sửa đổi vào giai đoạn và sau đó cam kết chúng.
Điểm của sân khấu là gì? Bạn có thể dễ dàng tách các cam kết của bạn. Hãy tưởng tượng bạn đã chỉnh sửa joypad.cpp và gamesave.cpp và bạn muốn cam kết chúng một cách riêng biệt
git add joypad.cpp // copies to stage
git commit -m "added 2nd joypad support"
git add gamesave.cpp // copies to stage
git commit -m "fixed game save bug"
Git thậm chí còn có các lệnh để quyết định các dòng cụ thể trong cùng một tệp mà bạn muốn sao chép vào giai đoạn để bạn cũng có thể tách riêng các cam kết đó. Tại sao bạn muốn làm điều đó? Bởi vì như những cam kết riêng biệt, những người khác chỉ có thể lấy những thứ họ muốn hoặc nếu có vấn đề, họ có thể hoàn nguyên chỉ những cam kết có vấn đề.