Kapybara
Published on

10 Lệnh Git Mới Mà Bạn Nên Biết

Authors
  • avatar
    Name
    Khoa (kapybara)
    Occupation
    Full-stack developer

Nếu bạn đã làm việc với Git đủ lâu, bạn có thể đã gặp phải một số khó khăn phổ biến như tốc độ hoạt động chậm lại khi kho lưu trữ phát triển, vô tình ghi đè lên các thay đổi khi chuyển đổi nhánh hoặc gặp khó khăn với các monorepo khổng lồ.

May mắn thay, giống như mọi công cụ khác, Git không ngừng phát triển và bổ sung các tính năng mới để giúp cuộc sống của chúng ta dễ dàng hơn. Mặc dù một số lệnh này không phải là mới nhất, nhưng chúng vẫn là những viên ngọc ẩn chứa tiềm năng cải thiện đáng kể quy trình làm việc của bạn. Nếu bạn đã quen thuộc với một số mẹo và thủ thuật cốt lõi (như những mẹo được đề cập trong 15 mẹo dòng lệnh Git mà mọi nhà phát triển nên biết), bài viết này sẽ giới thiệu cho bạn mười lệnh bổ sung có thể nâng cao kỹ năng Git của bạn lên một tầm cao mới.

1. git switch - Cách an toàn hơn để chuyển đổi nhánh

Trước Git 2.23, git checkout là lệnh chính để chuyển đổi nhánh, nhưng nó thực hiện nhiều hơn thế. Bạn có thể sử dụng nó để khôi phục tệp, tạo nhánh hoặc kiểm tra các commit cụ thể. Điều này khiến nó trở nên mạnh mẽ nhưng có khả năng gây nhầm lẫn, đặc biệt khi bạn chỉ muốn chuyển đổi nhánh mà không chạm vào các tệp của mình.

Đó là lý do tại sao Git 2.23 giới thiệu git switch như một giải pháp thay thế tập trung hơn cho các hoạt động của nhánh. Với git switch, bạn có thể chỉ tập trung vào quản lý nhánh:

Bash

# Chuyển đến một nhánh khác
git switch feature-branch

# Tạo và chuyển đổi sang một nhánh mới
git switch -c new-branch

Sự rõ ràng này làm giảm nguy cơ ghi đè lên tệp hoặc thực hiện thay đổi không mong muốn một cách tình cờ. Nếu bạn từng do dự sử dụng git checkout vì sợ làm sai điều gì đó, git switch sẽ đơn giản hóa quá trình.

2. git restore - Hoàn tác thay đổi một cách an toàn

Hoàn tác thay đổi thường liên quan đến việc sử dụng git checkout để hoàn nguyên tệp hoặc git reset để di chuyển HEAD của nhánh. Tuy nhiên, cả hai lệnh đều có khả năng thay đổi trạng thái nhánh của bạn nếu sử dụng không chính xác: git reset có thể di chuyển HEAD nhánh của bạn, trong khi git checkout có thể chuyển đổi nhánh hoặc kiểm tra một commit khác, làm gián đoạn nhánh hiện tại.

Git 2.23 giới thiệu git restore để chỉ tập trung vào việc hoàn tác thay đổi đối với tệp. Nó cung cấp một cách an toàn và trực tiếp hơn để hoàn nguyên các thay đổi trong thư mục làm việc hoặc khu vực tạm chờ, tách biệt rõ ràng các hoạt động tệp với các tác vụ quản lý nhánh:

Bash

# Bỏ qua các thay đổi của thư mục làm việc
git restore main.js

# Bỏ xếp hàng các thay đổi khỏi chỉ mục
git restore --staged main.js

Điều này đặc biệt hữu ích cho người mới bắt đầu hoặc trong các tình huống quan trọng khi độ chính xác là yếu tố quan trọng. Bạn có thể hoàn tác các thay đổi mà không lo lắng về việc vô tình chuyển đổi nhánh hoặc đặt lại commit.

3. git maintenance - Automate repository health

Khi kho lưu trữ phát triển, hiệu suất có thể giảm. Các hoạt động như git fetch, git status hoặc git log có thể chậm lại và dữ liệu không sử dụng có thể làm lộn xộn kho lưu trữ của bạn. Trước Git 2.29, bạn phải chạy thủ công các lệnh như git gc (thu gom rác) hoặc git repack để giữ cho kho lưu trữ của bạn được tối ưu hóa.

Git 2.29 giới thiệu git maintenance, tự động hóa các tác vụ này cho bạn:

Bash

# Bật bảo trì tự động
git maintenance start

# Chạy ngay các tác vụ dọn dẹp
git maintenance run

Điều gì đang xảy ra đằng sau hậu trường?

  • Thu gom rác: Loại bỏ các đối tượng không thể truy cập được, chẳng hạn như các commit bị loại bỏ trong quá trình rebase hoặc xóa nhánh.
  • Đóng gói lại: Hợp nhất các tệp gói bị phân mảnh để tăng hiệu quả lưu trữ.
  • Cập nhật biểu đồ commit: Tối ưu hóa việc duyệt lịch sử commit, tăng tốc các lệnh như git loggit blame.

Sử dụng git maintenance sẽ giúp bạn giữ cho kho lưu trữ của mình luôn khỏe mạnh mà không cần nỗ lực thủ công.

4. git sparse-checkout - Xử lý hiệu quả các kho lưu trữ lớn

Monorepo rất tuyệt vời để quản lý nhiều dự án, nhưng việc clone toàn bộ kho lưu trữ khi bạn chỉ cần một thư mục cụ thể có thể không hiệu quả. Git 2.25 giới thiệu git sparse-checkout để giải quyết vấn đề này.

Bash

# Bật chế độ sparse-checkout
git sparse-checkout init

# Chỉ lấy các thư mục cụ thể
# Bạn có thể chỉ định nhiều thư mục cách nhau bởi dấu cách
git sparse-checkout set services/ docs/

Với git sparse-checkout, bạn chỉ có thể bao gồm các thư mục hoặc tệp bạn cần trong thư mục làm việc của mình, bỏ qua phần còn lại. Điều này hữu ích cho các nhóm lớn làm việc trên các phần riêng biệt của một monorepo và sẽ giúp bạn tiết kiệm thời gian và dung lượng đĩa.

5. git log --remerge-diff: Hiểu rõ hơn về việc hợp nhất

Các commit hợp nhất thường cho thấy các nhánh nào đã được hợp nhất, nhưng chúng không luôn giải thích các thay đổi cụ thể được giới thiệu, đặc biệt là khi xung đột đã được giải quyết trong quá trình hợp nhất.

Bắt đầu với Git 2.35, bạn có thể sử dụng:

Bash

git log --remerge-diff

Tùy chọn này tái tạo commit hợp nhất bằng cách phát lại chiến lược hợp nhất được ghi lại và hiển thị các thay đổi chính xác mà nó đã giới thiệu. Nó hữu ích cho việc gỡ lỗi xung đột hợp nhất hoặc xem xét lịch sử hợp nhất phức tạp.

6. git blame --ignore-rev - Bỏ qua các commit "ồn ào"

Khi nhóm của bạn thực hiện thay đổi định dạng hàng loạt, git blame có thể mất đi tính hữu dụng, vì mọi dòng đều kết thúc bằng việc trỏ đến commit định dạng thay vì tác giả ban đầu.

Được giới thiệu trong Git 2.23, tùy chọn --ignore-rev cho phép bạn loại trừ các commit như vậy:

Bash

git blame --ignore-rev commit-hash

Để duy trì việc loại trừ này, bạn có thể thiết lập một tệp ignore-revs:

Bash

# Thêm commit hash vào tệp ignore-revs
echo commit-hash >> .git-blame-ignore-revs

# Yêu cầu Git sử dụng tệp
git config blame.ignoreRevsFile .git-blame-ignore-revs

Điều này giúp bạn tập trung vào tác giả có ý nghĩa và có thể hữu ích trong các cơ sở mã có cập nhật kiểu thường xuyên.

7. git range-diff - So sánh và theo dõi các thay đổi giữa các phạm vi commit

Viết lại lịch sử, cho dù thông qua rebase, cherry-picking hay chỉnh sửa tương tác, có thể rất khó khăn. Sau khi rebase, bạn có thể tự hỏi làm thế nào các commit được viết lại khác với bản gốc. git range-diff giúp bằng cách so sánh hai phạm vi commit, hiển thị cách một phạm vi phát triển thành phạm vi khác và làm nổi bật các thay đổi đối với từng commit:

Bash

git range-diff

Lệnh này có thể được sử dụng để hiểu sự phát triển của một tính năng hoặc bản sửa lỗi trên các nhánh khác nhau.

8. git worktree - Làm việc trên nhiều nhánh cùng một lúc

Chuyển đổi nhánh trong một thư mục làm việc duy nhất có thể làm gián đoạn quy trình làm việc của bạn, đặc biệt khi bạn cần làm việc trên nhiều nhánh. Với git worktree, bạn có thể tạo thêm các thư mục làm việc được liên kết với cùng một kho lưu trữ.

# Thêm một worktree mới cho một nhánh cụ thể
git worktree add ../feature-branch feature-branch

# Xóa một worktree khi bạn hoàn thành
git worktree remove ../feature-branch

git worktree cho phép bạn làm việc trên các nhánh khác nhau mà không cần chuyển đổi hoặc lưu trữ. Bạn cũng có thể tạo các worktree dùng một lần với HEAD tách rời để thử nghiệm hoặc cách ly các bản dựng và triển khai trong các thư mục làm việc riêng

9. git rebase --update-refs - Giữ các tham chiếu đồng bộ

Khi rebase (viết lại lịch sử), các nhánhtag cũ có thể bị hỏng vì lịch sử đã thay đổi. Git 2.38 bổ sung tùy chọn --update-refs để tự động cập nhật các nhánh và tag này cho phù hợp với lịch sử mới.

git rebase --update-refs

Lệnh này giúp Git tự động cập nhật các nhánh và tag liên quan đến các commit đã được rebase, đảm bảo lịch sử luôn nhất quán.

Bạn có thể tùy chỉnh để Git tự động cập nhật các nhánh và tag cụ thể bằng cách thiết lập:

Bash

git config rebase.updateRefs true

Điều này rất hữu ích khi làm việc nhóm hoặc quản lý nhiều nhánh/tag liên quan.

10. git commit --fixup và git rebase --autosquash - Sửa chữa commit

Mặc dù đã có từ lâu (Git 1.7.4), lệnh git commit --fixup thường bị bỏ qua, trong khi nó rất hữu ích để giữ lịch sử commit gọn gàng.

Khi làm việc, bạn có thể phát hiện cần sửa hoặc cải thiện một commit trước đó. Thay đổi lịch sử commit thủ công dễ gây lỗi.

Git cung cấp git commit --fixupgit rebase --autosquash để tự động hóa quá trình này:

Bash

# Tạo commit sửa lỗi cho một commit cụ thể
git commit --fixup=<commit-hash>

# Sau đó, trong quá trình rebase tương tác, tự động gộp các commit sửa lỗi
git rebase -i --autosquash <base-branch> 

Lệnh --fixup tạo một commit đặc biệt, sẽ được tự động gộp vào commit đích trong quá trình rebase tương tác. Điều này giúp dọn dẹp lịch sử commit trước khi hợp nhất dễ dàng hơn và đảm bảo các thay đổi liên quan được nhóm lại mà không cần thao tác thủ công.

Kết luận

Những lệnh Git được giới thiệu trong bài viết này sẽ giúp bạn giải quyết các vấn đề thực tế mà bạn gặp phải hàng ngày khi sử dụng Git. Cho dù bạn đang quản lý một monorepo, xử lý lịch sử commit lớn hay cố gắng giữ cho kho lưu trữ của mình sạch sẽ, những giải pháp thực tế này đều có thể mang lại sự khác biệt. Hãy bắt đầu với một hoặc hai lệnh phù hợp với quy trình làm việc hiện tại của bạn, và bạn có thể ngạc nhiên trước những cải thiện về năng suất.