Khóa học
Nếu bạn từng làm việc trong một dự án lập trình nhóm, bạn sẽ biết mọi thứ có thể nhanh chóng vượt khỏi tầm kiểm soát thế nào khi nhiều người cùng lúc cố gắng cập nhật các tệp trùng lặp. Xung đột nảy sinh, lỗi len lỏi, và tiến độ chững lại. Đó là lúc nhánh Git phát huy tác dụng—không phải như một mẹo nâng cao mà là nền tảng của phát triển song song, sạch sẽ.
Trong Git, việc tạo nhánh không chỉ được khuyến khích; nó là điều được kỳ vọng. Dù bạn đang thử nghiệm một tính năng mới, sửa lỗi, hay xem xét mã của người khác, nhánh cho phép bạn làm việc mà không giẫm chân lên ai. Chúng cho phép bạn phá vỡ, lặp lại, rồi tích hợp gọn gàng các thay đổi vào mã nguồn chính.
Hướng dẫn này sẽ dẫn bạn qua những điều cốt lõi về tạo nhánh trong Git. Chúng ta sẽ bắt đầu với git branch và git checkout, sau đó nhìn kỹ hơn cách nhánh được tạo, quản lý, hợp nhất và xóa. Chúng ta cũng sẽ bàn về các thực hành tốt nhất để bạn giữ quy trình làm việc không xung đột. Tôi hy vọng rằng đến cuối hướng dẫn, bạn sẽ hiểu nhiều hơn là chỉ ghi nhớ lệnh: bạn sẽ nắm thêm về dòng chảy công việc. Nếu bạn thấy hứng thú và muốn tiếp tục luyện tập, khóa học Introduction to GitHub Concepts của chúng tôi là điểm khởi đầu tuyệt vời.
Tìm hiểu về Nhánh Git
Giờ khi bức tranh tổng quan đã rõ, hãy phân tích nhánh Git là gì. Cốt lõi, một nhánh Git không phải là thư mục riêng hay bản sao đầy đủ của mã nguồn; nó chỉ là một con trỏ nhẹ trỏ đến một commit cụ thể. Đây là một trong những lý do Git nổi bật so với các hệ thống quản lý phiên bản cũ: tạo nhánh nhanh, rẻ, và là trung tâm của quy trình hằng ngày.
Hãy hình dung nhánh như một dòng thời gian. Khi bạn tạo một nhánh mới, về cơ bản bạn nói: "Hãy khám phá một lối đi mới từ đây." Mọi thay đổi của bạn sống trên lối đi này cho đến khi bạn quyết định hợp nhất chúng trở lại nhánh chính hoặc không. Sự linh hoạt này giúp bạn dễ dàng thử ý tưởng, xây tính năng trong môi trường tách biệt, và cộng tác mà không ảnh hưởng đến mã ổn định.
Git theo dõi vị trí hiện tại của bạn trong dự án bằng một tham chiếu đặc biệt gọi là HEAD. Khi bạn chuyển nhánh, HEAD sẽ trỏ đến đỉnh của nhánh mới. Chi tiết hậu trường này cho phép Git chuyển ngữ cảnh rất nhanh, và cũng là lý do lệnh như git checkout và git switch trở nên mượt mà khi bạn hiểu chuyện gì diễn ra bên dưới.
Bằng cách hiểu cách nhánh Git hoạt động, bạn sẽ mở khóa khả năng tổ chức quy trình phát triển với sự rõ ràng và tự tin. Nếu bạn đang theo dõi và muốn thử các khái niệm này, khóa Intermediate Git của DataCamp hướng dẫn chi tiết về tạo nhánh với nhiều bài tập có hướng dẫn.
Liệt kê và Xem Nhánh Git
Bạn đã tạo nhánh và bắt đầu sử dụng chúng, nhưng làm sao để theo dõi mọi thứ? May mắn là Git cung cấp công cụ đơn giản nhưng mạnh để liệt kê, sắp xếp và lọc nhánh, giúp bạn không bao giờ mất dấu quy trình.
Kiểm tra nhánh hiện tại
Đầu tiên, hãy kiểm tra các nhánh tồn tại trong kho cục bộ và xác định nhánh bạn đang đứng.
git branch
Lệnh này liệt kê tất cả nhánh cục bộ. Bạn sẽ thấy dấu hoa thị (*) cạnh nhánh hiện tại. Để xem tập trung hơn, thử:
git branch --show-current
Lệnh này trả về đúng tên nhánh bạn đang làm việc, gọn gàng, sạch sẽ.
Muốn xem cả nhánh trên remote? Dùng:
git branch -r
Và nếu bạn muốn xem cả nhánh cục bộ và remote cùng lúc:
git branch -a
Điều này cho bạn bức tranh đầy đủ về cấu trúc nhánh của dự án, đặc biệt hữu ích khi cộng tác trên các nền tảng như GitHub.
Sắp xếp và lọc nhánh
Khi dự án lớn dần, danh sách nhánh cũng vậy. Sắp xếp và lọc giúp bạn quản lý hiệu quả. Để sắp xếp nhánh theo ngày commit mới nhất, dùng:
git branch --sort=-committerdate
Bạn cũng có thể sắp theo tiêu chí khác như tên tác giả, ngày tạo, hoặc cấu hình upstream. Đây là một lệnh hữu ích để lọc các nhánh chứa một commit cụ thể:
git branch --contains <commit>
Lệnh này cho thấy nhánh nào đã bao gồm commit đó, giúp kiểm tra xem bản sửa lỗi hoặc tính năng đã được hợp nhất vào chúng chưa. Ngược lại, lệnh dưới đây cho thấy những nhánh chưa nhận commit đó:
git branch --no-contains <commit>
Quản lý nhánh hiệu quả không chỉ là tạo nhánh, mà còn là đảm bảo khả năng hiển thị và kiểm soát. Những lệnh này giúp quy trình phát triển gọn gàng, có tổ chức và hiệu quả.
Muốn làm chủ cách chúng liên quan đến cộng tác? Khóa học Foundations of Git cung cấp nền tảng xuất sắc và bao quát các quy trình thực tế bạn sẽ dùng lặp lại.
Tạo Nhánh Git Mới
Giờ bạn đã hiểu cách liệt kê và chuyển đổi giữa các nhánh, hãy đi qua cách tạo nhánh. Tạo nhánh là phần cốt lõi của quy trình Git, và may mắn là việc tạo nhánh mới khá đơn giản, dù bạn đang chuẩn bị nhánh tính năng, hotfix, hay thử nghiệm điều gì đó hoàn toàn mới.
Tạo nhánh mà không chuyển sang nhánh đó
Đôi khi, bạn muốn tạo nhánh mà không lập tức chuyển vào. Điều này hữu ích khi bạn đang chuẩn bị nhiều nhánh cùng lúc hoặc thiết lập quy trình cho người khác.
git branch new-feature
Lệnh này tạo nhánh tên new-feature, nhưng bạn vẫn ở nhánh hiện tại. Bạn có thể chuyển sang nó sau khi sẵn sàng làm việc.
Tạo và chuyển sang nhánh cùng lúc
Nếu bạn bắt tay vào phát triển ngay, bạn có thể tạo và chuyển sang nhánh mới trong một bước. Ở các phiên bản Git cũ, bạn sẽ dùng:
git checkout -b new-feature
Tuy nhiên, trong Git hiện đại, cách rõ ràng và trực quan hơn là:
git switch -c new-feature
Lệnh này vừa tạo nhánh vừa chuyển sang ngay, để bạn sẵn sàng bắt đầu.
Thiết lập nhánh upstream
Khi làm việc với kho remote, bạn thường muốn nhánh cục bộ theo dõi một nhánh remote. Điều này giúp đẩy và kéo cập nhật đơn giản hơn. Để tạo nhánh theo dõi nhánh remote ngay từ đầu, dùng:
git branch --track new-feature origin/new-feature
Nếu bạn đã tạo nhánh và muốn đặt hoặc đổi upstream, lệnh này sẽ xử lý:
git branch --set-upstream-to=origin/new-feature
Cấu hình này đảm bảo nhánh cục bộ biết nên kéo từ đâu hoặc đẩy tới đâu, giữ cho quy trình của bạn mượt mà và kết nối.
Chuyển Đổi Giữa Các Nhánh Git
Khi bạn đã tạo vài nhánh, bạn sẽ thường xuyên cần nhảy qua lại giữa chúng, dù là trở về main để hợp nhất một bản sửa hay chuyển sang nhánh tính năng để tiếp tục mã hóa. Git khiến quá trình này liền mạch, và như hầu hết mọi thứ trong Git, có hơn một cách để làm.
Dùng git checkout
Trong thời gian dài, git checkout là lệnh mặc định để chuyển nhánh:
git checkout feature-login
Lệnh này chuyển thư mục làm việc của bạn sang nhánh feature-login, cập nhật tất cả tệp để phản ánh ảnh chụp của nhánh đó. Nó đáng tin cậy và vẫn được dùng rộng rãi. Nhưng có điều: git checkout làm rất nhiều việc. Nó dùng để chuyển nhánh, khôi phục tệp, thậm chí checkout commit. Điều đó có thể gây rối, nhất là khi bạn mới bắt đầu.
Dùng git switch
Để mọi thứ trực quan hơn, Git đã giới thiệu the git switch ở phiên bản 2.23:
git switch feature-login
Lệnh này làm đúng như bạn mong đợi: chuyển nhánh. Nó không động vào cây làm việc hay đặt lại tệp trừ khi bạn yêu cầu. Đơn giản, an toàn, dễ dạy và dễ nhớ.
Vậy khi nào dùng cái nào?
- Dùng
git switchđể chuyển giữa các nhánh—rõ ràng và chuyên biệt. - Dùng
git checkoutnếu bạn cần khôi phục tệp hoặc checkout một commit cụ thể.
Hợp Nhất Các Nhánh Git
Bạn đã làm việc trên một tính năng ở nhánh riêng. Giờ là khoảnh khắc quyết định: kết hợp thay đổi của bạn vào nhánh chính. Trong Git, quá trình này gọi là merge. Tùy lịch sử của các nhánh, có vài cách tiếp cận.
Merge fast-forward
Giả sử feature branch của bạn bắt đầu từ the main, và khi bạn làm việc, không ai động đến main. Khi đó, Git không cần suy nghĩ nhiều. Nó chỉ việc di chuyển con trỏ main tiến lên commit mới nhất ở feature-branch.
git checkout main
git merge feature-branch
Không có commit mới được tạo—Git fast-forward main. Gọn gàng, đơn giản, hoàn hảo cho dự án cá nhân hoặc nhánh sống ngắn.
Merge ba chiều
Mọi thứ thú vị hơn khi cả hai nhánh cùng tiến triển độc lập. Đồng đội của bạn có thể đã thêm thay đổi vào main trong khi bạn lập trình ở the feature branch. Giờ Git phải xem ba ảnh chụp: tổ tiên chung, nhánh của bạn, và nhánh đích.
git checkout main
git merge feature-branch
Trong trường hợp này, Git tạo một merge commit mới để kết hợp hai nhánh. Nếu có xung đột, ví dụ bạn và đồng đội thay đổi cùng một dòng trong cùng tệp, Git sẽ nhắc bạn tự xử lý. Bạn sẽ chỉnh tệp, đánh dấu đã giải quyết, rồi commit việc hợp nhất.
git add .
git commit
Nếu điều này nghe hơi đáng ngại, Git Merge Tutorial: A Comprehensive Guide with Examples của chúng tôi là phần hướng dẫn tuyệt vời, bao trọn những nền tảng thiết yếu, gồm cả cách xử lý xung đột khéo léo.
Rebase thay vì merge
Bạn không thích các merge commit làm lộn xộn lịch sử? Bạn không đơn độc. Đó là lúc Git rebase xuất hiện. Thay vì tạo một merge commit mới, rebase phát lại thay đổi của bạn lên trên nhánh khác, cho lịch sử tuyến tính, sạch hơn.
git checkout feature-branch
git rebase main
Sau đó, khi merge, Git sẽ thấy một đường thẳng—không cần merge commit. Tuy nhiên, hãy thận trọng khi dùng, đặc biệt với nhánh dùng chung. Việc viết lại lịch sử có thể nguy hiểm nếu người khác cũng đang làm việc trên cùng mã nguồn.
Để biết khi nào nên dùng merge so với rebase (và cách rebase an toàn), khóa Intermediate Git cung cấp hướng dẫn thực hành.
Xóa Nhánh Git
Sau khi merge thành công, nên dọn dẹp các nhánh bạn không còn cần, cả cục bộ lẫn trên remote. Điều này giữ không gian làm việc gọn gàng và lịch sử Git dễ duyệt hơn. Hãy xem cách làm điều đó mà không phải lo lắng về việc lỡ xóa thứ quan trọng.
Xóa nhánh cục bộ
Khi một nhánh đã được hợp nhất và hoàn thành nhiệm vụ, bạn có thể an tâm xóa nó khỏi kho cục bộ:
git branch -d feature-branch
Cờ -d là “delete”. Git sẽ kiểm tra để đảm bảo nhánh đã được merge nhằm tránh mất dữ liệu.
Nhưng nếu bạn muốn xóa nhánh dù nó chưa được merge thì sao? Đó là lúc dùng chữ hoa -D:
git branch -D feature-branch
Lệnh này buộc xóa, ngay cả khi Git cảnh báo nhánh chưa được merge. Trước khi nhấn enter, hãy chắc rằng bạn không cần các thay đổi đó.
Muốn tìm hiểu sâu hơn cách quản lý không gian làm việc cục bộ và nhánh? Xem hướng dẫn Git Pull Force: How to Overwrite a Local Branch With Remote. Đây là tài liệu bổ trợ hữu ích để đảm bảo bạn không chỉ xóa mà còn quản lý nhánh an toàn.
Xóa nhánh trên remote
Dọn dẹp cục bộ chỉ là nửa công việc. Nếu nhánh cũng tồn tại trên remote (như GitHub), bạn cũng nên xóa ở đó, đặc biệt khi đã xong tính năng hoặc sửa lỗi.
git push origin --delete feature-branch
Lệnh này bảo Git xóa nhánh khỏi remote origin. Gọn ghẽ, trực tiếp, giúp tránh remote bị chất đống các nhánh không dùng.
Sau khi xóa nhánh remote, cũng nên dọn dẹp các tham chiếu theo dõi cục bộ.
git fetch -p
Tùy chọn -p là "prune". Nó loại bỏ những nhánh theo dõi remote đã không còn tồn tại trên máy chủ.
Để biết thêm các thói quen vệ sinh Git hữu ích, Git Push and Pull Tutorial và Complete Git Cheat Sheet là tài liệu tham khảo nhanh hoàn hảo.
Đẩy và Kéo Nhánh Git
Sau khi bạn tạo và sắp xếp nhánh trên máy, bước tiếp theo là đồng bộ với kho remote. Điều này thiết yếu cho cộng tác và sao lưu. Hãy cùng đi qua cách đẩy, kéo, và theo dõi nhánh hiệu quả.
Đẩy nhánh mới lên remote
Bạn đã tạo một tính năng mới cục bộ và kiểm thử, giờ muốn chia sẻ với nhóm hoặc sao lưu. Để đẩy một nhánh mới lên kho remote (thường tên origin), dùng:
git push -u origin new-feature
Cờ -u (viết tắt của --set-upstream) bảo Git ghi nhớ nhánh remote cho các lần pull và push sau. Nhờ vậy, lần tới bạn chỉ cần chạy git pull hoặc git push mà không cần chỉ rõ nhánh.
Nếu bạn thắc mắc điều gì diễn ra phía sau khi push hoặc pull, Git Push and Pull Tutorial của chúng tôi giải thích bằng các ví dụ có thể làm theo.
Kéo thay đổi từ nhánh remote
Giả sử ai đó đã đẩy cập nhật lên cùng nhánh bạn đang làm. Bạn sẽ muốn kéo những thay đổi đó về để đồng bộ:
Git pull origin new-feature
Lệnh này fetch các commit mới nhất từ remote và merge vào nhánh cục bộ của bạn. Nếu muốn tránh các merge commit, hãy cân nhắc dùng:
git pull --rebase origin new-feature
Như phần hợp nhất đã giải thích, --rebase giúp lịch sử commit sạch hơn.
Theo dõi một nhánh remote
Khi bạn muốn bắt đầu làm việc với một nhánh đã tồn tại trên remote, cách dễ nhất để thiết lập là:
git checkout --track origin/feature-xyz
Lệnh này checkout nhánh remote và tự động thiết lập theo dõi, giúp các lần pull và push sau dễ dàng.
Sự Cố Thường Gặp và Cách Khắc Phục
Ngay cả với quy trình tốt nhất, mọi thứ cũng không phải lúc nào suôn sẻ. Dù là xung đột khi merge, lỡ xóa nhánh, hay các thay đổi chưa commit cản trở bạn, Git có công cụ để khôi phục. Hãy xem những vấn đề nhánh phổ biến và cách xử lý.
Xử lý xung đột merge
Bạn vừa thử merge một nhánh và Git ném ra xung đột. Điều này xảy ra khi hai nhánh thay đổi cùng phần của một tệp theo cách khác nhau, và Git không thể quyết định giữ thay đổi nào.
Cách giải quyết như sau:
git status
Lệnh này cho biết tệp nào xung đột. Sau đó, bạn có thể dùng:
git diff
Để xem nguyên nhân. Từ đó, mở tệp xung đột, giải quyết khác biệt thủ công, rồi
git add <resolved-file>
git commit
Nếu bạn muốn tìm hiểu thêm về quy trình merge và xử lý xung đột, hãy xem Git Merge Tutorial, cung cấp hướng dẫn đầy đủ.
Khôi phục nhánh đã xóa
Lỡ xóa một nhánh và bắt đầu hoảng? Đừng lo—nếu hành động nhanh, nó chưa mất hẳn.
Bạn có thể khôi phục bằng git reflog, lệnh ghi lại vị trí HEAD gần đây:
git reflog
Tìm hash commit trước khi bạn xóa nhánh, rồi tạo lại bằng:
git checkout -b your-branch-name <commit-hash>
Và như thế, nhánh của bạn đã trở lại. Muốn hiểu rõ hơn cách Git theo dõi các tham chiếu này? Git Reflog Guide của chúng tôi giải thích bằng ví dụ thực tế.
Stash thay đổi trước khi chuyển nhánh
Đôi lúc, bạn muốn chuyển nhánh nhưng đang có thay đổi chưa commit. Git sẽ không cho bạn chuyển nếu có nguy cơ mất việc. Đó là lúc git stash phát huy tác dụng.
git stash
Và Git sẽ tạm thời cất các thay đổi của bạn. Sau khi chuyển nhánh, bạn có thể mang chúng trở lại bằng:
git stash pop
Điều này đặc biệt hữu ích khi nhảy giữa các tính năng hoặc hotfix.
Nếu bạn đang quản lý nhiều thay đổi hoặc dọn dẹp thư mục làm việc, bạn cũng có thể quan tâm đến Git Clean: Remove Untracked Files and Keep Repos Tidy.
Chiến Lược Tạo Nhánh Nâng Cao
Đến lúc này, bạn đã biết cách tạo, chuyển, và quản lý nhánh Git một cách dễ dàng. Nhưng các đội ngũ dùng nhánh trong dự án thực tế ra sao? Câu trả lời nằm ở việc chọn chiến lược tạo nhánh phù hợp—một cấu trúc cho cách và thời điểm dùng nhánh trong quy trình phát triển. Hãy khám phá vài cách tiếp cận phổ biến.
Quy trình nhánh tính năng
Quy trình nhánh tính năng là một trong những chiến lược phổ biến nhất, đặc biệt trong dự án cộng tác. Cách thức như sau:
Mỗi tính năng mới có nhánh riêng, được tạo từ nhánh chính (hoặc develop). Điều này cho phép lập trình viên làm việc độc lập mà không ảnh hưởng đến mã sẵn sàng sản xuất.
git switch -c feature/login-page
Khi tính năng hoàn thiện và đã kiểm thử, nó được merge trở lại nhánh chính (hoặc nhánh staging) qua pull request.
Mô hình này giúp cô lập công việc, khiến việc review mã dễ quản lý hơn, và tránh làm lộn xộn nhánh chính với các tính năng dở dang. Để cộng tác từ xa suôn sẻ, đừng quên đẩy nhánh của bạn:
git push -u origin feature/login-page
Bạn cần ôn lại cách push và pull nhánh? Git Push and Pull Tutorial sẽ hướng dẫn toàn bộ quy trình.
Quy trình GitFlow
Nếu bạn làm việc trên dự án có phát hành định kỳ, GitFlow có thể phù hợp. Quy trình này giới thiệu vai trò có cấu trúc cho các loại nhánh khác nhau:
-
main: luôn chứa mã sẵn sàng sản xuất. -
develop: nhánh tích hợp cho các tính năng. -
feature/*: nhánh sống ngắn cho tính năng mới. -
release/*: nhánh tiền sản xuất cho kiểm thử. -
hotfix/*: Các bản sửa nhanh dựa trênmain.
Đây là ví dụ nhanh về bắt đầu một nhánh tính năng bằng công cụ GitFlow:
git flow feature start payment integration
Chiến lược này thêm chút phức tạp, nhưng tỏa sáng trong các đội lớn nơi cấu trúc rõ ràng và ổn định là ưu tiên. Nếu bạn đang khám phá quy trình ngoài GitHub, hãy xem What GitLab Is: Features, Benefits, and How to Get Started để có góc nhìn khác về thực hành Git có cấu trúc.
Phát triển dựa trên trunk
Bạn thích tối giản nhánh và phát hành nhanh? Trunk-based development có thể hợp gu bạn. Trong chiến lược này, mọi lập trình viên commit vào một nhánh duy nhất, thường là main, với các commit nhỏ và thường xuyên. Thay vì nhánh tính năng sống lâu, cách tiếp cận này khuyến khích nhánh sống ngắn hoặc commit trực tiếp vào main.
Nó nhanh và đơn giản nhưng đòi hỏi kỷ luật, tự động hóa kiểm thử mạnh, và giao tiếp tốt. Mô hình này phổ biến ở startup và các đội thực hành DevOps hoặc CI/CD. Việc chọn chiến lược tạo nhánh phụ thuộc vào quy mô đội, nhịp phát hành, và dĩ nhiên, mức độ cộng tác.
Kết luận
Nhánh là trái tim của hệ thống quản lý phiên bản Git. Chúng cho phép lập trình viên làm việc trên tính năng mới, sửa lỗi, và thử nghiệm trong môi trường tách biệt mà không làm gián đoạn mã nguồn chính. Sự linh hoạt này dẫn đến quy trình gọn gàng, có tổ chức hơn và cộng tác nhóm tốt hơn.
Bằng cách commit thường xuyên, merge có trách nhiệm, và duy trì cấu trúc nhánh sạch, bạn giảm rủi ro xung đột và khiến mã nguồn dễ điều hướng, dễ bảo trì hơn. Không nghi ngờ gì, làm chủ nhánh Git giúp bạn tạo ra phần mềm tốt hơn theo thời gian.
Nhà viết nội dung về công nghệ, chuyên về AI, ML và khoa học dữ liệu, giúp làm rõ và phổ biến những ý tưởng phức tạp.
