Mẹo và thủ thuật Git
(blog.gitbutler.com)- Ngay cả những người đã dùng Git lâu năm cũng dễ bỏ lỡ nhiều tính năng ít được biết đến, làm lung lay giả định rằng kiến thức dòng lệnh nâng cao đã trở nên phổ biến
- Không giống thế hệ chuyển sang từ SVN, CVS, những lập trình viên chỉ dùng Git từ đầu có ít cơ hội học một số cách dùng nâng cao
- Theo thời gian, Git liên tục bổ sung các tính năng nhỏ nhưng hữu ích, và những thay đổi này có thể mang giá trị thực tiễn trong những tình huống nhất định
- Dành cho người dùng từ trung cấp đến nâng cao, các chủ đề về tính năng cũ nhưng hữu ích, tính năng mới được thêm gần đây, và kho mã lớn·monorepo được chia thành loạt 3 bài ngắn
- Nếu xem lại những tính năng không dễ nhận ra chỉ với thói quen dùng Git quen thuộc, bạn có thể xử lý công việc hằng ngày với kho mã hiệu quả hơn
Vì sao nên nhìn lại Git
- Khi gần đây thuyết trình về Git và GitButler, tác giả nhận ra rằng rất nhiều lập trình viên vẫn có những phần chưa biết về Git
- Trước đây từng có các buổi nói chuyện về Git nâng cao, nhưng khoảng 10 năm qua, mọi người thường được cho là đã biết sẵn các tính năng dòng lệnh nâng cao
- Thế hệ lập trình viên chỉ dùng Git không có dịp chuyển từ các công cụ như SVN, CVS sang Git hoặc học lại các khái niệm trước đó
- Bản thân Git cũng đã học thêm các tính năng mới theo thời gian; phần lớn là những thay đổi tinh tế hoặc nhắm đến mục đích cụ thể, nhưng vẫn có thể giúp ích cho công việc thực tế
- Loạt bài blog được xây dựng dựa trên bài trình bày FOSDEM 2024 little known Git stuff
Loạt mẹo Git gồm 3 phần
- Đối tượng là người dùng Git từ trung cấp đến nâng cao, và bài viết đề cập đến những tính năng mà ngay cả người dùng lâu năm cũng có thể đã bỏ lỡ
- Thay vì gói gọn mọi thứ trong một bài, nội dung được chia thành 3 bài ngắn theo từng nhóm chủ đề
- Các chủ đề gồm có:
- Oldies but Goodies: các tính năng Git cũ nhưng vẫn hữu ích
- Some Subtle New Things: những thay đổi tinh tế được thêm vào Git gần đây
- Really Large Repositories and Monorepos: nội dung liên quan đến kho mã rất lớn và monorepo
- Bài đầu tiên tiếp nối tại Oldies but Goodies
1 bình luận
Ý kiến trên Hacker News
Tôi cũng đã có những cuộc trò chuyện thú vị với phía Mercurial, và gần đây họ nói rằng khi viết lại một phần nội bộ của Hg bằng Rust, họ đã đạt được mức cải thiện tốc độ đáng kinh ngạc
Tôi cũng đang nghĩ đến Pro Git bản 3, nên nếu có điều gì bạn đã học được khi chật vật với Git, hoặc điều gì bạn muốn biết, hãy cho tôi biết
difftasticthay cho diff của Git rất hay: https://difftastic.wilfred.me.uk/Các bí danh
gitconfigtôi hay dùng làfza,gone,root.git fzamở các tệp đã sửa/tệp mới trong cửa sổfzfrồi chuyển tệp đã chọn sanggit add: https://github.com/junegunn/fzfgit gonexóa các nhánh cục bộ không còn trên remote, còngit rootin ra thư mục gốc của repo để tiện quay về từ các thư mục sâu. Gần đây tôi dùngzoxidenên ít cần hơn: https://github.com/ajeetdsouza/zoxidegit blamekhông bị hỏnghttps://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt
Ví dụ, tôi đã không hiểu vì sao chỉ xóa một commit trong lúc rebase mà mọi commit sau đó cũng đều thay đổi. Chỉ đến khi nhận ra rằng việc lưu trữ là dựa trên snapshot nhưng thao tác là dựa trên khác biệt, tôi mới hiểu rebase, và nếu nhấn mạnh phần này hơn khi dạy thì sẽ rất hữu ích
Tôi tôn trọng những người thích Git, nhưng với tôi nó chỉ là một công cụ buộc phải dùng
checkout/commit/push, chỉ cần biết thêm một vài thứ, đặc biệt là viết lại lịch sử, thì chất lượng lịch sử commit sẽ tốt hơn rất nhiều và các kỹ sư khác trong dự án cũng dễ hiểu luồng hơnGit có vẻ gần như là một hằng số lâu dài trong ngành, và là một trong những công cụ bạn đụng tới nhiều nhất mỗi ngày khi phát triển, nên đáng để tìm hiểu thêm một chút
Vì thế tôi thấy việc Git có một mức độ phức tạp nhất định là chấp nhận được
core.fsmonitor. Ở góc độ mono-repo lớn, tôi ướcgit clonecó tùy chọn tiếp tục tải dởHồi những năm 2000 tôi từng gặp đúng vấn đề này khi cố clone repo kernel qua kết nối băng thông thấp, và chỉ sau khi hỏi trên mailing list thì mới có người đăng toàn bộ repo dưới dạng tar nén lên trang cá nhân để tôi tải được
Đến giờ thỉnh thoảng tôi vẫn gặp vấn đề tương tự khi VPN công ty chập chờn trong lúc clone các repo lớn. Cứ tưởng tượng bạn đã tải được 95% kho mã Windows 300GB rồi mà Wi‑Fi ngắt trong chốc lát
Thật lạ khi Git và Docker, hai công cụ ngốn băng thông hàng đầu trong stack phát triển hiện đại, lại không hỗ trợ tốt việc tiếp tục tải xuống
https://git-scm.com/docs/git-bundle
Cũng giống như việc muốn một ngôn ngữ bậc thấp mà lại che giấu được độ phức tạp của hệ thống, hai điều này về cơ bản loại trừ lẫn nhau. Git đủ ổn và không quá khó học, nên một phần là bạn cứ phải học Git thôi
Nó xóa đi cảm giác hộp đen mà nhiều lập trình viên thấy ở terminal, đưa đồ thị lên vị trí trung tâm, và khiến các thao tác rebase trở nên trực quan, tự nhiên đến mức Git trở nên thú vị
Kỹ năng dùng CLI vẫn rất có giá trị, nhưng thật bực khi thấy các lập trình viên đã 10 năm kinh nghiệm vẫn loay hoay với những vấn đề cơ bản hoặc phá hỏng lịch sử dự án vì bầu không khí kiểu “nếu là kỹ sư thực thụ thì phải chỉ dùng Git CLI”
Giờ đây ngay cả khi dùng CLI, tôi vẫn khuyên mọi người cứ mở đồ thị ở một cửa sổ khác cả ngày. VS Code, JetBrains, thậm chí cả CLI cũng làm được điều đó miễn phí
Khi đồng đội merge PR thì tôi xem ngay và rebase nhánh của mình, nên nhánh luôn được cập nhật mới nhất dựa trên
main, nhờ đó tránh được địa ngục merge hoặc để lại những commit “fix conflicts” kinh khủngTrong lúc tìm 10 file được sửa nhiều nhất kể từ khi tạo hôm qua, tôi phát hiện ra https://github.com/tj/git-extras/blob/main/Commands.md
Có khá nhiều lệnh Git bổ sung đáng dùng
git-extraskhá tốt. Một công cụ khác cũng ổn là git absorb: https://github.com/tummychow/git-absorbTôi không thực sự hiểu vì sao đa số lập trình viên lại cố chấp dùng Git CLI khi các client UI hiện đại như GitKraken đã đủ hữu dụng và hữu ích: https://www.gitkraken.com/
Không phải là tôi hoàn toàn phản đối GUI, nhưng hiện tại CLI hiệu quả hơn và tôi không muốn tốn thời gian tìm một GUI đáp ứng các điều kiện sau
đẹp mắt, là ứng dụng native chứ không phải kiểu nhét một trình duyệt web cổ lỗ vào bên trong, không có telemetry hoặc mặc định bị tắt, hoàn toàn mã nguồn mở, và có thể kỳ vọng là 5 năm nữa vẫn không biến mất
Ngoài ra nó cũng không được làm mọi thứ rối hơn. Ở công ty cũ tôi từng phải dùng Visual Studio, và có một nút ghi đầy điềm gở là “Accept merge”, trong khi thực chất nó có nghĩa là “đánh dấu là đã giải quyết xung đột”
Không nên gây nhầm lẫn cho những người đã quen gán một ý nghĩa nhất định cho một số từ, và cũng khó mà tin tưởng các hành vi kiểu nút “Commit changes” lại tiện tay push luôn lên remote
Nếu chỉ để tạo một commit mà phải chuyển sang chương trình khác thì động lực commit thường xuyên sẽ giảm đi
push,pull,checkout, nên dùng GUI có cảm giác hơi quá mức cần thiếtNgay cả khi dùng Git trong CLI thì phần lớn cũng không có gì đặc biệt, chỉ là vài lệnh; các mẹo hay thủ thuật ít dùng thì tôi ghi vào một file văn bản
Tôi biết
-committerdate, nhưng không biết có thể đặt nó làm thứ tự sắp xếp mặc định, và điều đó rất hữu ích. Có vài ghi chúgit columnskhá khó theo dõi nếu không hiển thị hết trên màn hình và phải cuộn, nên sẽ tốt hơn nếu có đánh sốgit maintenancecó vẻ hay, nhưng tôi rebase nhiều nên hơi lo. Tôi tự hỏi liệu nó có làm mất loose object nhanh hơngckhông. Tôi có thấygcbị tắt, nhưng vẫn không rõ ràngLiên quan đến
git blame, có một script ít người biết nhưng hữu ích là https://github.com/gnddev/git-blameall. Nó ít được biết đến mức tôi phải tự port sang Python 3, dù tôi cũng không phải là lập trình viên Pythongcbị vô hiệu hóa. Khi chạymaintenance runmột cách tường minh thì nó được bật như một tác vụNó không thu gom loose object nhanh hơn
gc. Xét cho cùng thì nó chỉ đơn giản là chạy gcgit-blamealltrông khá ổn, tôi sẽ thử dùng xem saoTôi đã đơn giản hóa đáng kể luồng Git bằng vài alias chạy được trong nhiều môi trường
git syncedđồng bộ nhánh hiện tại bằng rebase theo upstream nếu có, còn không thì theo origin. Nó dùngmasterhoặcmain, ưu tiênmaingit pubpublish thay đổi lên remote origin và dùng force push with leasegit prmở đúng URL PR trên GitHub mà không cần client GH. Nếu có định nghĩa upstream thì nó sẽ gửi PR sang đógit hubmở trang GitHub của repositoryhttps://softwaredoug.com/blog/2022/11/09/idiot-proof-git-aliases.html
Tôi đã thôi giả vờ như mình biết mình đang làm gì và dùng các công cụ Git trực quan. Chẳng hạn như SmartGit hay công cụ đi kèm IntelliJ. Tôi thấy các “anh hùng dòng lệnh” của Git phần nhiều chỉ để thể hiện
Lớp lệnh dành cho người dùng có thể khó chịu đến mức gây rối. Ví dụ,
YoursvàTheirscó thể mang ý nghĩa hoàn toàn trái ngược tùy theo ngữ cảnhKhông có phong cách hay chủ đề chung xuyên suốt toàn bộ giao diện người dùng, nên cần một lớp trực quan mới nếu không muốn làm người ta phát điên
Tôi chỉ biết về ứng dụng và Git ở mức đủ để phục vụ công việc, còn hiếm khi cần nhiều hơn thì tra cứu là được. Trong nhiều năm dùng như vậy, chuyện đó chỉ xảy ra một hai lần
Ngay cả với các tác vụ phức tạp để sửa lỗi của người khác hoặc của chính tôi, trước tiên tôi cũng xem history, commit, reflog và diff bằng công cụ trực quan để hiểu xem thứ gì đã bị rối và có gì còn cứu được không
Nếu chỉ cần quay về một commit thì tôi dùng
reset --hard, còn nếu phải ghép thứ gì đó từ nhiều commit thì thường tôi sẽ dùng dòng lệnhHai thứ này không loại trừ lẫn nhau. Với những việc như xem khác biệt hay xử lý xung đột thì tôi chỉ dùng công cụ trực quan, nhưng tôi cũng học được rất nhiều khi tìm hiểu về đối tượng commit, reflog, những gì rebase làm ở phía sau, rebase tương tác, hard/soft reset, v.v.