jj, giao diện dòng lệnh của Jujutsu, là một công cụ dựa trên hệ thống quản lý phiên bản phân tán (DVCS)
- Cung cấp các tính năng đơn giản, trực quan hơn
git nhưng vẫn mạnh mẽ hơn
- Kết hợp ưu điểm của
git và Mercurial để giảm số lượng công cụ cốt lõi và tăng cường sự liên kết hữu cơ giữa chúng
- Sử dụng backend tương thích
git để có thể thử nghiệm độc lập mà vẫn giữ nguyên môi trường cộng tác hiện có
- Với người dùng nâng cao, điểm quan trọng là có thể tận dụng các tính năng quản lý phiên bản bổ sung vốn khó thực hiện bằng
git
Giới thiệu và đặc điểm của jj
-
jj là CLI (giao diện dòng lệnh) của Jujutsu, và Jujutsu là hệ thống quản lý phiên bản phân tán (DVCS)
- Người dùng có thể đã quen với các DVCS khác như
git, và hướng dẫn này được viết với giả định từ góc nhìn của người dùng git
jj được thiết kế là công cụ đơn giản, dễ dùng hơn git nhưng vẫn mạnh mẽ
- Thông thường, “mạnh mẽ” và “phức tạp” là hai yếu tố đối nghịch, nhưng
jj đưa ra một cách cân bằng mới
jj kết hợp ưu điểm của git và Mercurial(hg) để tạo nên một dạng DVCS mới
- Giảm số lượng công cụ cốt lõi và cung cấp môi trường làm việc hiệu quả thông qua sự liên kết hữu cơ giữa từng công cụ
- Người dùng nâng cao có thể tận dụng các tính năng quản lý phiên bản bổ sung vốn khó thực hiện với
git
jj sử dụng backend tương thích git để có thể thử nghiệm độc lập mà không cần thay đổi môi trường cộng tác
- Vẫn duy trì khả năng tương thích với kho lưu trữ
git hiện có, và khi cần cũng có thể dễ dàng quay lại git
- Hướng dẫn này báo trước quá trình trực tiếp cho thấy vì sao
jj là một công cụ đáng chú ý thông qua những đặc tính đó
1 bình luận
Ý kiến Hacker News
Nhiều thảo luận tập trung vào sự khác biệt giữa git và jj, nhưng tôi nghĩ tốt hơn là cứ quên git đi và tập trung vào workflow cơ bản của jj
Khi ở một repository sạch, chỉ cần chạy
jjlà có thể kiểm tra trạng thái, sau đó sửa đổi xong thì commit bằngjj commit -m "made changes"Nếu lỡ làm sai, sửa lại rồi dùng
jj squashđể gộp vào commit cuối cùngChỉ khi muốn làm việc từ một revision cụ thể như tạo branch mới thì mới cần dùng
jj new -r lmnopCó thể xem lịch sử git bằng
git log, còn cơ chế hoạt động nội bộ của jj thì không hiện raalias.save="!git add -A; git commit -m"và dùng kiểu$ git save "made changes"Tôi có cảm giác JJ bắt tôi phải nghĩ ngược lại
Trong git, bạn sửa xong rồi mới viết message commit, còn jj thì giống như tạo commit mới trước rồi mới gắn mô tả
Tôi quen với việc ở trong một trạng thái lộn xộn có nhiều tính năng trộn lẫn rồi chọn ra đúng phần thay đổi cần thiết để commit, nhưng chỉ xem tutorial của jj thì tôi chưa chắc điều đó có làm được không
jj newlà một khái niệm giống vùng staging trống của gitTrong jj luôn có một commit tồn tại, và commit đó có changeid ổn định là giá trị được tính từ nội dung thư mục
Nếu muốn tách nhiều thay đổi thành các commit riêng thì dùng
jj splitjj newvà để trống messageKhi đã sẵn sàng, tôi squash nhiều commit lại thành một và thêm message sau
Cách này hoạt động như một loại lịch sử undo, nên việc thử nghiệm thoải mái hơn nhiều
jj newchỉ đơn giản là “tạo một commit mới ở phía trên”, nên không cần phải viết mô tả ngayBan đầu tôi cũng cố tạo thói quen đó, nhưng hóa ra lại kém hiệu quả hơn
Git cũng đã khuyến nghị workflow tương tự từ lâu, và nếu xem Squash Workflow thì có thể tạo ra luồng làm việc gần giống index của Git
Vì thế tôi dùng nhiều workspace và thường xuyên dùng tính năng shelve (IntelliJ)
Đôi khi tôi còn tạm lưu diff bằng git patch
Tôi cố giấu quy trình hỗn loạn này với đồng nghiệp để trông chuyên nghiệp hơn một chút
Điều tôi không thích khi dùng jj là việc sửa file sẽ tự động được commit
Nếu checkout để duyệt một commit cũ rồi sửa file, commit đó sẽ bị thay đổi và toàn bộ lịch sử phía sau sẽ được rebase lại
Vì thế tôi phải phòng thủ bằng cách tạo một commit rỗng mới
Với git thì repository không thay đổi cho đến khi tôi commit một cách tường minh, nên thấy thoải mái hơn
jj evologthì suy nghĩ đã thay đổijj đã có sẵn một lời giải tốt hơn staging
Việc quá quen với git CLI lại trở thành rào cản khi học jj
Điều thú vị là dùng jj lại giúp hiểu rõ hơn về cấu trúc storage engine của git
editthay vìjj newthì có thể theo dõi thay đổi gọn gàng hơnTôi thấy còn tốt hơn nhiều so với việc phải juggling với stash của git
jj editlà cái bẫy lớn nhất của jjThay vào đó hãy dùng
jj new, và nếu lỡ sai thì có thể khôi phục bằngjj undojj coi commit là các snapshot rẻ, nên hợp lý hơn khi tập trung vào “thay đổi” thay vì commit
Việc auto rebase sẽ được cố định bất biến sau khi push nên vẫn an toàn
Chỉ cần kết hợp
jj newvàjj squashđể quản lý như branch head của gitjj khiến việc làm việc trong trạng thái detached head trở nên dễ dàng
jj editNếu đổi sang
jj newthì vấn đề sẽ được giải quyếtĐoạn cuối của jj mới là điểm mấu chốt
Nó dùng backend tương thích hoàn toàn với git, nên bạn có thể tự dùng thử mà không cần cả nhóm cùng chuyển đổi
Nếu không thích thì lúc nào cũng có thể quay về git
Các thao tác git sẽ không được ghi vào log của jj nên phải import thủ công
Trong một dự án, tốt nhất chỉ nên dùng một interface
Tính năng tôi thích nhất là
jj absorbNó tự động chuyển các thay đổi của revision hiện tại sang những commit trước đó có liên quan
Rất hữu ích khi quên sửa file config hoặc
.gitignoreChỉ cần
jj new, sửa đổi rồi chạyjj absorbTuyệt nhất là không phải xử lý merge conflict
jj absorbáp dụng sai thì có thể hoàn tác bằngjj undoNhờ tính năng này mà cả rebase phức tạp cũng không còn đáng sợ
git absorbTôi đã không cập nhật tutorial trong một thời gian dài, nhưng vẫn dùng jj hằng ngày
Tôi bận ở startup ersc.io nên chưa thể làm việc upstream
Nếu có câu hỏi thì lúc nào cũng hoan nghênh
jj dùng stable change ID, còn git dùng immutable commit ID
Vì thế trong jj, undo hay rebase có cảm giác linh hoạt hơn nhiều
Đôi khi tôi muốn xem nhiều thay đổi hơn, không biết có tùy chọn nào để hiện tất cả một lần không
jj khác git đủ nhiều để đáng thử
Chỉ riêng việc trải nghiệm một cách tiếp cận khác cũng đã giúp mở rộng góc nhìn kỹ thuật
Không cần phải thử mọi thứ, nhưng hiểu được trade-off của các workflow khác nhau là điều quan trọng
Mối quan hệ giữa git và jj khiến tôi liên tưởng đến quan hệ giữa C và Python
git giống như truy vết pháp chứng, còn jj giống như các chương của một câu chuyện
Đôi khi phải viết lại chương đầu thì phần sau mới trở nên tự nhiên hơn
jj được thiết kế theo triết lý “working tree tự thân là commit” và “xung đột cũng có thể được commit”
Tôi cảm thấy tuyên bố “mạnh hơn và dễ hơn” cần có ví dụ cụ thể
Nếu không có nhu cầu này thì có thể bạn sẽ không cảm thấy giá trị của jj
Phải tự dùng thì mới hiểu được
jj undothôi cũng đã đủ đáng giáTrong git rất dễ rơi vào trạng thái không thể khôi phục, còn trong jj thì chỉ cần undo vài lần là giải quyết được
Nhờ jj mà tôi tự tin hơn khi tận dụng DAG phi tuyến tính
Tôi thoải mái xử lý các thay đổi có nhiều parent hoặc child
Trước đây tôi thường ép thứ tự một cách không cần thiết, nhưng giờ có thể biểu đạt quan hệ phụ thuộc rõ ràng
Quá trình review và submit cũng hiệu quả hơn nhiều