Bí kíp luyện Git cơ bản cho người mới (P2): Làm việc cục bộ
Người bạn đồng hành trên con đường trở thành cao thủ Git
Chào mừng bạn đến với cuộc hành trình chinh phục Git. Nếu bạn đang ở đây, có lẽ bạn đã nghe nói về Git như một công cụ "thần thánh" mà mọi lập trình viên đều phải biết, hoặc có thể bạn đã từng trải qua những đêm dài mất ngủ vì lỡ tay xóa mất file quan trọng hay ghi đè lên công sức của đồng đội. Dù lý do là gì, bạn đã đến đúng nơi.
Cuốn "bí kíp" này không phải là một tài liệu tham khảo khô khan liệt kê hàng trăm câu lệnh. Thay vào đó, nó được viết dưới dạng một câu chuyện, một lộ trình tuyến tính sẽ dẫn dắt bạn đi từng bước, từ việc hiểu được "nỗi đau" mà Git sinh ra để giải quyết, cho đến việc sử dụng thành thạo những kỹ thuật phức tạp nhất. Chúng ta sẽ cùng nhau theo chân một lập trình viên tên Bình, chứng kiến những vấn đề anh gặp phải và khám phá cách Git, với triết lý và công cụ của mình, trở thành người hùng giải quyết những vấn đề đó.
Bạn đang đọc phần 2 của cuốn bí kíp này bao gồm nội dung ở 3 chương 4 đến 6. Những chương này sẽ cung cấp cho bạn kiến thức về cách ta phân nhánh dữ liệu, gợp dữ nhánh dữ liệu và làm việc từ xa thông qua các kho chứa.
Nếu bạn đang cảm thấy lạ lẫm, hãy quay lại Phần 1 của cuốn bí kíp tại đây.
Chương IV: Nghệ thuật Phân thân - Làm chủ các Nhánh (Branch)
Chúng ta đã học cách tạo ra một dòng lịch sử tuyến tính. Nhưng sức mạnh thực sự của Git, thứ làm nó trở thành công cụ không thể thiếu cho làm việc nhóm và các dự án phức tạp, nằm ở khả năng quản lý nhiều dòng lịch sử song song. Phần này sẽ giới thiệu cho bạn khái niệm mạnh mẽ nhất của Git: branch (nhánh). Bạn sẽ học cách tạo ra các không gian làm việc độc lập để phát triển tính năng mới hoặc sửa lỗi mà không làm ảnh hưởng đến dòng công việc chính.
Vấn đề: Nỗi sợ làm hỏng Dòng chảy Chính
Câu chuyện của Bình tiếp tục. Dự án learning-git của anh đang tiến triển tốt trên nhánh chính, nơi chứa phiên bản ổn định của câu chuyện. Theo mặc định, nhánh này thường được đặt tên là main (hoặc master trong các dự án cũ).
Bây giờ, Bình có một ý tưởng lớn: anh muốn thêm một nhân vật phản diện vào câu chuyện, một con rồng lửa hung tợn. Đây là một thay đổi lớn, có thể mất vài ngày để hoàn thiện và có thể tạm thời làm cho câu chuyện trở nên lủng củng. Anh rất lo lắng rằng việc thêm code mới này có thể làm hỏng phiên bản truyện đang rất ổn định trên nhánh main.
Đúng lúc đó, sếp của anh đọc qua bản thảo và phát hiện một lỗi chính tả khẩn cấp cần sửa ngay lập tức. Bình rơi vào thế tiến thoái lưỡng nan. Anh không thể sửa lỗi trên phiên bản hiện tại vì nó đã lẫn lộn với những dòng code dang dở về con rồng. Anh cũng không thể giao nộp phiên bản có con rồng vì nó chưa hoàn thiện. Anh cần một cách để tạm gác công việc về con rồng sang một bên, quay về phiên bản ổn định để sửa lỗi, rồi sau đó quay lại tiếp tục công việc dang dở.
Giải pháp của Git: Branching - Các Dòng Thời gian Song song
Git giải quyết vấn đề này một cách vô cùng thanh lịch thông qua khái niệm branching (phân nhánh).
Hãy tưởng tượng lịch sử commit của bạn là một dòng thời gian. Nhánh main là dòng thời gian chính, nơi mọi thứ đều ổn định và sẵn sàng để "xuất bản".
Khi bạn muốn bắt đầu một công việc mới (như thêm nhân vật phản diện), thay vì làm việc trực tiếp trên dòng thời gian chính, bạn tạo ra một nhánh mới. Việc này giống như bạn đang tạo ra một "dòng thời gian song song" hoặc một "vũ trụ song song" tách ra từ một điểm cụ thể trên dòng thời gian chính. Trong vũ trụ song song này, bạn có thể thoải mái thử nghiệm, thêm thắt, thậm chí phá vỡ mọi thứ mà không hề ảnh hưởng đến dòng thời gian chính.
Khi công việc trong nhánh mới đã hoàn thành và ổn định, bạn có thể "hợp nhất" (merge) nó trở lại dòng thời gian chính. Chúng ta sẽ tìm hiểu về việc hợp nhất ở phần sau.

Quản lý các "dòng thời gian song song" với "Branch"
Bản chất của một Branch
Điều kỳ diệu là, một branch trong Git không phải là một bản sao chép toàn bộ thư mục dự án. Nó cực kỳ nhẹ. Về bản chất, một branch chỉ là một con trỏ (pointer) trỏ đến một commit cụ thể. Khi bạn tạo một commit mới trên một nhánh, con trỏ đó sẽ tự động di chuyển đến commit mới nhất. Vì vậy, việc tạo ra hàng chục, hàng trăm nhánh trong Git là một thao tác cực kỳ nhanh chóng và không tốn dung lượng đĩa. Đây là một ưu điểm vượt trội so với các VCS cũ.
HEAD là gì?
Làm sao Git biết bạn đang làm việc trên nhánh nào? Đó là nhờ một con trỏ đặc biệt tên là HEAD. HEAD giống như một cái mác "Bạn đang ở đây" trong trung tâm thương mại. Nó luôn trỏ đến nhánh hiện tại mà bạn đang làm việc. Khi bạn chuyển nhánh, thực chất là bạn đang di chuyển con trỏ HEAD sang một nhánh khác.
Các Lệnh Quản lý Nhánh
-
git branch: Liệt kê tất cả các nhánh trong kho chứa của bạn. Nhánh hiện tại sẽ được đánh dấu bằng một dấu sao*. -
git branch <tên-nhánh>: Tạo một nhánh mới tại vị trícommithiện tại của bạn. Lệnh này chỉ tạo nhánh chứ không chuyển bạn sang nhánh đó. -
git checkout <tên-nhánh>: Đây là lệnh "nhảy" giữa các dòng thời gian. Nó sẽ di chuyểnHEADđến nhánh được chỉ định và cập nhật các file trong Working Directory của bạn để khớp với "snapshot" của nhánh đó. -
git switch <tên-nhánh>: Đây là lệnh mới hơn (có từ phiên bản Git 2.23) và được khuyến khích sử dụng thay chocheckoutkhi bạn chỉ muốn chuyển nhánh. Lệnhcheckoutcó quá nhiều chức năng (vừa chuyển nhánh, vừa khôi phục file), đôi khi gây nhầm lẫn.git switchđược tạo ra để thực hiện duy nhất một việc: chuyển nhánh, do đó nó rõ ràng và an toàn hơn. -
git switch -c <tên-nhánh-mới>: Đây là lối tắt cực kỳ tiện lợi, kết hợp hai lệnh: tạo một nhánh mới (branch) và chuyển sang nhánh đó ngay lập tức (switch). Tương đương với lệnh cũgit checkout -b <tên-nhánh-mới>.
Việc Git giới thiệu git switch và git restore (dùng để khôi phục file) là một sự thừa nhận rằng thiết kế ban đầu của checkout quá đa năng và có thể gây rối. Đây là một bước tiến nhằm làm cho giao diện dòng lệnh trở nên trực quan hơn, giúp người dùng mới tránh được những sai lầm không đáng có. Vì vậy, trong cuốn bí kíp này, chúng ta sẽ ưu tiên sử dụng các lệnh hiện đại như switch.
| Tính năng | Lệnh checkout (cũ) | Lệnh switch (mới) | Ghi chú |
|---|---|---|---|
| Chuyển sang nhánh đã có | git checkout <branch> | git switch <branch> | Cả hai đều hoạt động, nhưng switch rõ ràng hơn về mục đích. |
| Tạo và chuyển sang nhánh mới | git checkout -b <new-branch> | git switch -c <new-branch> | Cả hai đều hoạt động, cờ -c là viết tắt của create. |
| Khôi phục file | git checkout -- <file> | Không hỗ trợ | Chức năng này đã được chuyển sang lệnh git restore. |
| Mục đích chính | Đa năng (chuyển nhánh, khôi phục file, detached HEAD) | Chỉ dành cho việc chuyển và tạo nhánh. | switch an toàn và ít gây nhầm lẫn hơn cho người mới. |
| Phiên bản Git | Từ đầu | Từ phiên bản 2.23 trở đi. | Nên cập nhật Git để sử dụng các lệnh mới nhất. |

HEAD và các lệnh xử lý nhánh
Thực hành: Xử lý Đa nhiệm vụ
Hãy cùng Bình giải quyết tình huống khó xử của anh ấy bằng cách sử dụng branch.
-
Kiểm tra nhánh hiện tại: Trong thư mục
learning-gitcủa bạn, gõ:Bash
git branchBạn sẽ thấy chỉ có một nhánh là
* main. -
Tạo nhánh cho tính năng "nhân vật phản diện":
Bash
git switch -c feature/add-villainLệnh này sẽ tạo ra một nhánh mới tên là
feature/add-villainvà chuyển bạn sang đó. Gõ lạigit branchđể kiểm tra, bạn sẽ thấy dấu*đã chuyển sang nhánh mới. -
Làm việc trên nhánh mới: Mở file
story.txtvà thêm vào dòng:Bỗng xuất hiện một con rồng lửa, da vảy lấp lánh như hồng ngọc.Lưu file lại. -
Commit trên nhánh mới:
Bash
git add story.txt git commit -m "feat: Introduce the dragon villain"Commitnày bây giờ chỉ tồn tại trên dòng thời gianfeature/add-villain. -
Xử lý yêu cầu khẩn cấp: Sếp gọi! Có lỗi chính tả. Giờ là lúc thể hiện sức mạnh của
branch.Bash
git switch mainBạn đã quay trở lại dòng thời gian chính. Hãy mở file
story.txtra xem. Phép màu! Con rồng đã biến mất. Working Directory của bạn đã được tự động cập nhật để phản ánh trạng thái của nhánhmain. -
Tạo nhánh để sửa lỗi (hotfix): Đây là một thói quen tốt. Đừng bao giờ sửa lỗi trực tiếp trên
main.Bash
git switch -c hotfix/fix-typo -
Sửa lỗi và commit: Mở
story.txt, tìm và sửa một lỗi chính tả nào đó (ví dụ, sửa "Ngày xửa" thành "Ngày xưa"). Sau đó,committhay đổi này:Bash
git add story.txt git commit -m "fix: Correct typo in the first chapter" -
Khám phá: Bây giờ bạn có ba nhánh:
main,feature/add-villain, vàhotfix/fix-typo. Hãy thử dùnggit switchđể nhảy qua lại giữa chúng. Mỗi lần chuyển, hãy mở filestory.txtđể quan sát sự thay đổi. Bạn sẽ thấy mình có thể du hành qua các "vũ trụ song song" một cách dễ dàng.
Công việc sửa lỗi đã xong, công việc về con rồng vẫn còn đó, an toàn trong nhánh riêng của nó. Cả hai không hề ảnh hưởng đến nhau. Ở phần tiếp theo, chúng ta sẽ học cách để đưa những thay đổi này quay trở lại nhánh chính.
Chương V: Hợp nhất Dòng thời gian - Gặp gỡ Merge và Rebase
Sau khi tạo ra các dòng thời gian song song (nhánh), công việc tiếp theo là làm thế nào để đưa những thay đổi từ các nhánh đó quay trở lại dòng chính. Phần này sẽ giới thiệu hai phương pháp chính để hợp nhất các nhánh: git merge và git rebase. Bạn sẽ hiểu được sự khác biệt cơ bản giữa chúng, cách thực hiện và khi nào nên sử dụng phương pháp nào. Đây là một trong những kỹ năng quan trọng nhất khi làm việc nhóm.
Vấn đề: Mang những Thay đổi Trở về Nhà
Câu chuyện của Bình đang có ba dòng thời gian:
-
main: Dòng thời gian chính, ổn định nhưng có một lỗi chính tả. -
hotfix/fix-typo: Một nhánh tách ra từmainđể sửa lỗi chính tả. Công việc ở đây đã hoàn thành. -
feature/add-villain: Một nhánh khác tách ra từmainđể phát triển tính năng mới. Công việc ở đây cũng đã hoàn thành.
Bây giờ Bình cần:
-
Đưa bản vá lỗi từ nhánh
hotfix/fix-typovào nhánhmainđể cập nhật phiên bản chính thức. -
Đưa tính năng con rồng từ nhánh
feature/add-villainvào nhánhmainđể câu chuyện có thêm tình tiết mới.
Làm thế nào để anh ấy có thể "hợp nhất" các lịch sử này lại với nhau một cách an toàn và hiệu quả?
Giải pháp của Git: Hai Con đường Hợp nhất
Git cung cấp hai cách chính để tích hợp các thay đổi từ một nhánh vào một nhánh khác: git merge và git rebase. Cả hai đều giải quyết cùng một vấn đề, nhưng chúng thực hiện theo những cách rất khác nhau và tạo ra lịch sử commit trông hoàn toàn khác nhau.

Hợp nhất Dòng thời gian với "Merge" và "Rebase"
1. git merge: Người kể chuyện Trung thực
git merge là cách tiếp cận đơn giản và trực tiếp nhất. Nó lấy lịch sử của hai nhánh và hợp nhất chúng lại với nhau.
Câu chuyện: Hãy tưởng tượng main và feature là hai con sông chảy song song. Khi bạn merge nhánh feature vào main, bạn đang tạo ra một điểm hợp lưu, nơi hai dòng sông hòa vào làm một. Git sẽ thực hiện điều này bằng cách tạo ra một merge commit đặc biệt. Commit này có hai commit cha (một từ main, một từ feature), đánh dấu rõ ràng điểm mà hai nhánh đã được hợp nhất.
Cách hoạt động:
-
Chuyển sang nhánh mà bạn muốn nhận các thay đổi (nhánh đích, thường là
main).Bash
git switch main -
Thực hiện lệnh
mergevới tên của nhánh chứa các thay đổi (nhánh nguồn).Bash
git merge <tên-nhánh-nguồn>
Ưu điểm:
-
Không phá hủy (Non-destructive):
mergelà một thao tác an toàn. Nó không thay đổi lịch sửcommitcủa các nhánh hiện có. Nó chỉ thêm mộtcommitmới. -
Dễ truy vết: Lịch sử
commitphản ánh chính xác những gì đã xảy ra. Bạn có thể nhìn vào biểu đồlogvà thấy rõ ràng nhánhfeatuređã được tạo ra khi nào và hợp nhất vàomaintại đâu. Nó giữ lại toàn bộ bối cảnh của quá trình phát triển.
Nhược điểm:
- Lịch sử lộn xộn: Nếu có quá nhiều nhánh được
mergevàomain, lịch sửcommitcó thể trở nên rất phức tạp và khó theo dõi, với nhiềumerge commitxen kẽ.
Trường hợp đặc biệt: Fast-Forward Merge Đôi khi, việc hợp nhất rất đơn giản. Nếu nhánh đích (main) không có commit mới nào kể từ khi nhánh nguồn (feature) được tạo ra, thì lịch sử của chúng vẫn là một đường thẳng. Trong trường hợp này, Git sẽ không tạo merge commit. Thay vào đó, nó chỉ cần di chuyển con trỏ của main lên vị trí commit cuối cùng của feature. Quá trình này được gọi là fast-forward (tua nhanh).
2. git rebase: Người Biên tập Lịch sử
git rebase là một cách tiếp cận mạnh mẽ hơn để tích hợp các thay đổi. Thay vì hợp nhất hai lịch sử, nó viết lại lịch sử.
Câu chuyện: Quay lại với ẩn dụ hai con sông. Thay vì tạo ra một điểm hợp lưu, rebase làm một việc khác. Nó nhấc toàn bộ dòng sông feature lên và đặt nó vào cuối dòng sông main. Kết quả là một con sông duy nhất, chảy thẳng từ đầu đến cuối, trông như thể tất cả công việc đã được thực hiện một cách tuần tự trên cùng một nhánh.
Cách hoạt động:
-
Chuyển sang nhánh mà bạn muốn "di chuyển" (nhánh nguồn, thường là
feature).Bash
git switch feature -
Thực hiện lệnh
rebasevới tên của nhánh mà bạn muốn đặt lên trên (nhánh đích).Bash
git rebase mainSau đó, bạn chuyển về
mainvà thực hiện mộtfast-forward merge.
Ưu điểm:
-
Lịch sử tuyến tính, sạch sẽ: Kết quả cuối cùng là một lịch sử
committhẳng tắp, không có cácmerge commitkhông cần thiết. Điều này làm cho lịch sử dự án cực kỳ dễ đọc và dễ điều hướng bằnggit log. -
Dễ dàng tìm kiếm: Việc có một lịch sử sạch giúp cho việc tìm kiếm một
commitgây ra lỗi (ví dụ bằng lệnhgit bisect) trở nên đơn giản hơn.
Nhược điểm và "Quy tắc Vàng":
-
Viết lại lịch sử:
rebasekhông chỉ di chuyển cáccommit, nó tạo ra cáccommithoàn toàn mới (với mã hash mới) để sao chép các thay đổi. Điều này có thể nguy hiểm. -
Quy tắc Vàng của Rebase: KHÔNG BAO GIỜ
rebasemột nhánh đã được chia sẻ với người khác (ví dụ: nhánhmaintrên một kho chứa từ xa)..- Lý do: Nếu bạn
rebasemột nhánh mà các thành viên khác trong nhóm cũng đang làm việc dựa trên đó, bạn đang viết lại một lịch sử mà họ đang phụ thuộc vào. Khi họ cố gắng cập nhật, Git sẽ thấy hai phiên bản lịch sử hoàn toàn khác nhau cho cùng một nhánh, gây ra sự hỗn loạn và xung đột lớn. Hãy chỉrebasecác nhánh cục bộ, cá nhân của bạn trước khi bạn hợp nhất chúng vào nhánh chung.
- Lý do: Nếu bạn

So sánh Merge và Rebase
Thực hành: Hợp nhất các Nhánh của Bình
Kịch bản 1: Hợp nhất Hotfix (Fast-Forward Merge)
-
Chuyển về
main:Bash
git switch main -
Hợp nhất nhánh
hotfix/fix-typo:Bash
git merge hotfix/fix-typo -
Quan sát kết quả: Bạn sẽ thấy một thông báo có chứa từ "Fast-forward". Lỗi chính tả đã được sửa trên
main. -
Dọn dẹp: Sau khi hợp nhất, nhánh
hotfixkhông còn cần thiết nữa. Bạn có thể xóa nó:Bash
git branch -d hotfix/fix-typo(Cờ
-dlà viết tắt củadelete).
Kịch bản 2: Hợp nhất Tính năng (Merge Commit)
-
Đảm bảo bạn đang ở trên
main:Bash
git switch main -
Hợp nhất nhánh
feature/add-villain:Bash
git merge feature/add-villain -
Quan sát kết quả: Lần này, Git không thể thực hiện
fast-forwardvì nhánhmainđã có mộtcommitmới (từ việcmergehotfix) sau khi nhánhfeatuređược tạo ra. Git sẽ mở trình soạn thảo văn bản mặc định của bạn để yêu cầu bạn xác nhận một thông điệp chomerge commit. Thông điệp mặc định thường là đủ tốt. Chỉ cần lưu và đóng file đó lại. -
Kiểm tra lịch sử:
Bash
git log --oneline --graphBạn sẽ thấy một biểu đồ đẹp mắt cho thấy lịch sử đã được phân nhánh và sau đó hợp nhất lại với nhau. Tính năng con rồng bây giờ đã là một phần của câu chuyện chính.
-
Dọn dẹp:
Bash
git branch -d feature/add-villain
Kịch bản 3: Thử nghiệm với Rebase (Trên nhánh cá nhân)
Hãy làm lại kịch bản 2 nhưng với rebase để thấy sự khác biệt. (Lưu ý: chúng ta cần quay lại trạng thái trước khi merge, bạn có thể bỏ qua bước này nếu chỉ muốn xem, hoặc thực hiện nó trong một thư mục dự án mới).
-
Chuyển sang nhánh
feature:Bash
git switch feature/add-villain -
Rebase lên
main:Bash
git rebase mainLệnh này nói rằng: "Hãy lấy
commit'Introduce the dragon villain' và đặt nó lên trên đỉnh của nhánhmainhiện tại". -
Chuyển về
mainvà hợp nhất:Bash
git switch main git merge feature/add-villainLần này, bạn sẽ thấy đây là một
fast-forward mergevì nhánhfeaturebây giờ đã đi trướcmainmột cách tuyến tính. -
Kiểm tra lịch sử:
Bash
git log --oneline --graphBạn sẽ thấy một lịch sử thẳng tắp.
Commitsửa lỗi chính tả, sau đó đếncommitthêm con rồng. Trông rất gọn gàng!
Kết luận: Cả merge và rebase đều là những công cụ mạnh mẽ. merge an toàn, trung thực và tốt cho các nhánh chung. rebase giúp tạo ra lịch sử sạch sẽ nhưng phải được sử dụng cẩn thận trên các nhánh cá nhân.
Chương VI: Thế giới Rộng lớn - Làm việc với Kho chứa Từ xa (Remotes)
Đến bây giờ, mọi thứ chúng ta làm đều diễn ra trên máy tính cá nhân của Bình (kho chứa cục bộ - local repository). Nhưng sức mạnh thực sự của Git bộc lộ khi cộng tác với người khác. Phần này sẽ dạy bạn cách kết nối kho chứa cục bộ của bạn với một "bản sao trung tâm" trên internet, được gọi là kho chứa từ xa (remote repository). Bạn sẽ học cách sao chép (clone) một dự án, đẩy (push) các thay đổi của mình lên và kéo (pull) các thay đổi của người khác về.
Vấn đề: Làm việc một mình và Rủi ro Mất mát
Bình đã làm việc rất chăm chỉ trên dự án learning-git của mình. Toàn bộ lịch sử, các nhánh, các commit đều nằm gọn trong thư mục .git trên laptop của anh. Nhưng anh bắt đầu lo lắng:
-
Rủi ro mất mát: Nếu ổ cứng laptop của anh bị hỏng thì sao? Toàn bộ công sức của anh sẽ biến mất. Anh cần một bản sao lưu ở một nơi an toàn khác.
-
Nhu cầu cộng tác: An, người bạn thiết kế, cũng muốn tham gia đóng góp vào dự án. Làm thế nào Bình có thể chia sẻ toàn bộ dự án và lịch sử của nó với An một cách hiệu quả? Gửi file zip qua lại rõ ràng không phải là giải pháp, vì nó sẽ lặp lại những vấn đề ở Phần I.
Bình cần một "trung tâm" chung nơi anh và An có thể đồng bộ hóa công việc của mình.
Giải pháp của Git: Remotes và Sự Đồng bộ hóa
Git giải quyết vấn đề này thông qua khái niệm remote (từ xa). Một remote đơn giản là một phiên bản của dự án của bạn được lưu trữ ở một nơi khác, thường là trên một máy chủ trên internet. Các dịch vụ như GitHub, GitLab, hay Bitbucket là những nơi phổ biến nhất để lưu trữ các remote repository này.
Hãy coi remote repository như một điểm hẹn chung. Mọi người trong nhóm vẫn làm việc chủ yếu trên local repository của họ (với tốc độ và sự linh hoạt của Git phân tán), và chỉ khi cần thiết, họ mới đến "điểm hẹn" này để đồng bộ hóa công việc.

Làm việc với Git từ xa thông qua kho lưu trữ
Các Lệnh Tương tác với Remote
1. git clone <URL>: Sao chép một Dự án Hiện có
Đây là lệnh đầu tiên bạn sẽ sử dụng khi tham gia một dự án đã tồn tại. git clone làm hai việc chính:
-
Nó tạo một bản sao đầy đủ của
remote repositorytrên máy của bạn, bao gồm tất cả các file, tất cả các nhánh, và toàn bộ lịch sửcommit. -
Nó tự động thiết lập một kết nối đến
remotegốc. Theo mặc định, Git đặt tên choremotenày làorigin.
2. git remote -v: Xem các Remote đã kết nối
Lệnh này cho phép bạn xem danh sách tất cả các remote mà kho chứa cục bộ của bạn đang kết nối tới. Cờ -v (verbose) sẽ hiển thị cả URL để lấy dữ liệu (fetch) và đẩy dữ liệu (push).
3. git remote add <tên> <URL>: Kết nối một Dự án Local với một Remote mới
Đây là trường hợp của Bình. Anh đã có một dự án trên máy và giờ muốn kết nối nó với một kho chứa trống vừa tạo trên GitHub. Lệnh này sẽ tạo một "lối tắt" tên là <tên> (thường là origin) trỏ đến <URL> của remote repository.
4. git push <tên-remote> <tên-nhánh>: Đẩy Thay đổi Lên
Sau khi bạn đã có những commit mới ở local, git push là lệnh để bạn "đẩy" những commit đó từ nhánh local của bạn lên nhánh tương ứng trên remote. Đây là cách bạn chia sẻ công việc của mình với cả nhóm.
5. git fetch <tên-remote>: Lấy thông tin Cập nhật
Lệnh này kết nối đến remote và tải về tất cả những dữ liệu mới (các commit, các nhánh mới) mà bạn chưa có. Tuy nhiên, git fetch chỉ tải về mà không tự động hợp nhất vào công việc hiện tại của bạn. Nó cập nhật các "nhánh theo dõi từ xa" (remote-tracking branches) của bạn (ví dụ: origin/main). Điều này cho phép bạn xem những gì người khác đã làm trước khi quyết định tích hợp chúng vào nhánh của mình. Đây là một thao tác rất an toàn.
6. git pull <tên-remote> <tên-nhánh>: Kéo và Hợp nhất Thay đổi
git pull là một lệnh tiện lợi hơn nhưng cũng "nguy hiểm" hơn. Về cơ bản, git pull là sự kết hợp của hai lệnh: git fetch và sau đó là git merge. Nó không chỉ tải về các thay đổi mới mà còn cố gắng hợp nhất chúng ngay lập tức vào nhánh làm việc hiện tại của bạn. Điều này rất tiện lợi, nhưng có thể gây ra xung đột (merge conflicts) nếu bạn có những thay đổi cục bộ chưa được đẩy lên. Một quy tắc tốt là luôn kiểm tra các thay đổi trước khi pull, hoặc sử dụng fetch và merge riêng biệt để kiểm soát tốt hơn.

Các lệnh tương tác với Remote
Thực hành: Đưa Dự án lên Mạng và Cộng tác
Hãy giúp Bình đưa dự án của anh ấy lên GitHub và chuẩn bị cho An tham gia.
Bước 1: Tạo một Kho chứa trên GitHub (Công việc của Bình)
-
Truy cập GitHub.com và tạo một tài khoản (nếu bạn chưa có).
-
Nhấn vào nút "+" ở góc trên bên phải và chọn "New repository".
-
Đặt tên cho kho chứa là
learning-git-story. -
Chọn "Public" (để An có thể thấy).
-
Quan trọng: KHÔNG tick vào ô "Add a README file", "Add.gitignore", hoặc "Choose a license". Chúng ta muốn một kho chứa hoàn toàn trống để kết nối với dự án có sẵn của Bình.
-
Nhấn "Create repository".
Bước 2: Kết nối và Đẩy Dự án Local lên GitHub (Công việc của Bình)
-
Trên trang GitHub vừa tạo, sao chép URL của kho chứa. Chọn tab "HTTPS" và sao chép URL trông giống như
https://github.com/YourUsername/learning-git-story.git. -
Quay lại Terminal, trong thư mục
learning-gitcủa bạn, chạy lệnh sau (dán URL bạn vừa sao chép):Bash
git remote add origin https://github.com/YourUsername/learning-git-story.git -
Kiểm tra lại kết nối:
Bash
git remote -vBạn sẽ thấy
originđã được thêm vào. -
Đẩy nhánh
maincủa bạn lên GitHub. Lần đầu tiên, bạn cần dùng cờ-uđể thiết lập mối quan hệ theo dõi (tracking) giữa nhánhmaincục bộ và nhánhmaintrênorigin.Bash
git push -u origin main -
Tải lại trang GitHub của bạn. Bạn sẽ thấy file
story.txtvà toàn bộ lịch sửcommitđã xuất hiện!
Bước 3: Sao chép Dự án về máy (Công việc của An)
Bây giờ, hãy đóng vai An. An muốn lấy dự án về máy của mình để bắt đầu làm việc.
-
Mở Terminal và di chuyển đến một thư mục khác (KHÔNG phải thư mục
learning-gitcủa Bình). -
Sao chép URL HTTPS của dự án từ trang GitHub.
-
Chạy lệnh
clone:Bash
git clone https://github.com/BinhsUsername/learning-git-story.git(Thay
BinhsUsernamebằng username của người tạo repo). -
Một thư mục mới tên là
learning-git-storysẽ được tạo ra. Di chuyển vào đó và dùnggit logđể xem. An bây giờ đã có một bản sao y hệt dự án của Bình.
Bước 4: Đồng bộ hóa Công việc
-
Bình tạo thay đổi mới: Quay lại vai Bình. Anh ấy tạo một nhánh mới, thêm một
commit, vàmergevàomain.Bash
# Trong thư mục learning-git của Bình git switch -c feature/add-ending # Sửa file story.txt, thêm vào "Và họ sống hạnh phúc mãi mãi về sau." git add story.txt git commit -m "feat: Add a happy ending" git switch main git merge feature/add-ending -
Bình đẩy thay đổi lên:
Bash
git push(Vì đã thiết lập tracking với cờ
-uở lần đầu, nên giờ chỉ cầngit push). -
An cập nhật thay đổi: Quay lại vai An. Kho chứa của An bây giờ đã "lỗi thời". Để cập nhật, An chạy lệnh:
Bash
# Trong thư mục learning-git-story của An git pull -
Mở file
story.txttrên máy của An. Cô ấy sẽ thấy câu kết mới mà Bình vừa thêm. Cả hai đã được đồng bộ hóa!
Lời kết
Chúc mừng! Bạn đã hoàn thành phần hai của cuộc hành trình và xây dựng một nền tảng cực kỳ vững chắc. Bạn đã đi từ một chiếc máy tính "trần trụi" đến việc trang bị và định danh cho thanh gươm Git của mình. Quan trọng hơn, bạn đã rèn luyện trong "xưởng rèn cá nhân", nắm vững chu trình làm việc cốt lõi: Chỉnh sửa -> add -> commit.
Với việc làm chủ các nhánh (branch), bạn không còn làm việc trên một dòng thời gian duy nhất, đầy rủi ro nữa. Giờ đây, bạn đã có khả năng "phân thân", tạo ra các vũ trụ song song để tự do thử nghiệm những ý tưởng táo bạo nhất mà không sợ làm hỏng phiên bản chính. Bạn đã làm chủ nghệ thuật làm việc an toàn và hiệu quả khi ở một mình.
Nhưng những dòng thời gian song song này sẽ đi về đâu? Làm thế nào để hợp nhất chúng lại một cách hài hòa? Và làm sao để chia sẻ công việc của bạn với những người đồng đội khác? Ở phần tiếp theo, chúng ta sẽ bước ra thế giới rộng lớn của sự cộng tác, học cách kết nối các dòng thời gian và làm việc cùng nhau.
End of Article