Mục lục Git - GitHub

Thiết lập ví dụ để tìm hiểu Remote Branch

Ở phần này sẽ sử dụng lại kết quả ví dụ thực hành của phần trước Nhánh trong Git (Tức Local Repo lưu tại thư mục C:\local\myproject).

Nếu đã có một Server Git thì làm theo hướng dẫn tại Remote Repo Git để tạo ra một Remote Repo, sau đó thêm vào Local Repo bằng lệnh git remote add name_remote addr_remote

Nếu muốn có thể thực hiện ngay ở máy local, để có được mô hình làm việc Client/Server với Git mà ý nghĩa giống như triển khai từ một Remote từ Server Git thật. Ta thực hiện theo các bước như sau:

1) Tạo Remote Repo tại máy Local

Chạy Git Bash, gõ các lệnh sau để tạo ra một Remote Repo (thực chất là trên máy của bạn) chứa tại thư mục C:\remote\myproject

$ mkdir /c/remote/                          #Tạo thư mục c:\remote
$ mkdir /c/remote/myproject                 #Tạo thư mục c:\remote\myproject
$ cd /c/remote/myproject/                   #Tạo thư mục c:\remote\myproject
$ git init --bare                           #Tạo bare Repo (remote Repo)
Initialized empty Git repository in C:/remote/myproject/

Bạn đã có một Remote Repo có địa chỉ là C:/remote/myproject/ hoặc /c/remote/myproject/, tất nhiên Remote Repo này mới khới tạo chưa có dữ liệu gì. Bạn có thể cứ để cửa số Git Bash ở đây, để thuận tiện ta gọi cửa sổ này là Git Bash (Remote) để sau này có thể quay lại của sổ lệnh này nhanh chóng

2) Thiết lập Remote cho Local Repo(C1)

Mở một cửa sổ lệnh Git Bash khác, gọi cửa sổ này là Git Bash (C1), từ cửa sổ này chuyển đến thư mục lưu trữ Local Repo(C1) (C:\local\myproject - Repo này là kết quả của phần trước, đang có ba nhánh master, alpha, beta với hình ảnh snapshot như hình dưới)

Ta tiến hành thiết lập Remote cho nó: đặt tên remote là origin và địa chỉ remote chính là /c/remote/myproject/

$ cd /c/local/myproject/
$ git remote add origin /c/remote/myproject/      #Thiết lập remote với tên origin
$ cd /c/remote/myproject/

Sau đó kiểm tra lại Remote của Local Repo này

$ git remote -v
origin  C:/remote/myproject (fetch)
origin  C:/remote/myproject (push)

Đã cấu hình chính xác, tiến hành push tất cả thông tin (tất cả các nhánh dữ liệu Repo) từ Repo(C1) lên Remote.

$ git push --all origin
To C:/remote/myproject
* [new branch]      alpha -> alpha
* [new branch]      beta -> beta
* [new branch]      master -> master

Remote đã có dữ liệu khởi đầu, do Repo(C1) push tất cả các nhánh của nó nên.

3) Clone từ Remote để có Local Repo(C2)

Mở một cửa sổ Git Bash đặt tên cửa sổ này là Git Bash(C2), chạy lệnh để nó clone Remote thành một bản Local, gọi là Local Repo(C2) đặt ở thư mục c:\local\projectonc2

$ git clone /c/remote/myproject/ /c/local/projectonc2
Cloning into 'C:/local/projectonc2'...
$ cd /c/local/projectonc2/
$ git remote -v
origin  C:/remote/myproject (fetch)
origin  C:/remote/myproject (push)

Do Repo(C2) clone từ Remote, nên mặc định nó đã thiết lập Remote với tên origin

Tóm lại đến đây ta có các thứ sau:

  • Một Remote Repository tại địa chỉ /c/remote/myproject/ từ sau sẽ gọi tắt nó là Remote, Remote này đã được khởi tạo dữ liệu từ một Local Repository tên là Repo(C1) - Cửa sổ lệnh Git Bash làm việc với Remote gọi tên là Git Bash (Remote)
  • Một Local Repository tại thư mục /c/local/myproject (là kết quả của bài viết trược), đặt tên Local Repository này Repo(C1) (hàm ý là Local Repository trên máy tính của lập trình viên thứ nhất). Cửa sổ để Git Bash làm việc với nó gọi tên là Git Bash(C1). Repo(C1) đã được thiết lập Remote và đã push tất cả các nhánh lên Remote
  • Một Local Repository tại thư mục /c/local/projectonc2, có được do clone từ Remote, đặt tên Local Repository này Repo(C2) (hàm ý là Local Repository trên máy tính của lập trình viên thứ hai). Cửa sổ để Git Bash làm việc với nó gọi tên là Git Bash(C2)

Ở phần này chủ yếu làm việc với Repo(C2) (tại cửa sổ Git Bash(C2))

Làm việc với Remote Branch

Trong một Local Repo, nếu Remote đặt tên là remotename, và một nhánh tên là branchname thì để biểu thị nhánh này trên Remote sẽ ký hiệu là remotename/branchename. Ví dụ trong Repo(2) Remote đặt tên là origin (mặc định do clone), thì nhánh master trên Remote đó là origin/master

Tạm thời ta sẽ tìm hiểu trên một nhánh, nhánh master

1) Trạng thái nhánh Remote và Local sau khi clone

Tại Repo(C2) cũng kiểm tra trạng thái

$ git log --oneline
544511a (HEAD -> master, origin/master, origin/beta, origin/HEAD) C10
be103d9 C9
1a90428 C8
89b19cb C7
eda207b C6
2c3fa4d C5
bbc3757 (origin/alpha) C4
c7d81e3 C3
0d7ae45 C2
927163b C1
efab635 C0
xt@xtMINGW64 /c/local/projectonc2 (master)
Ta thấy trạng thái nhánh master của Repo(C2)Remote giống nhau, đều đang ở snapshot C10

2) Sự phân nhánh tại Local khi Remote cập nhật

Đầu tiên, giả sử Repo(C1) có thêm 2 commit mới với snapshot là C11, C12. Sau đó Repo(C1) cập nhật master lên Remote. Có nghĩa là nhánh master của Remote thay đổi và HEAD sẽ trỏ đến snapshot C12 (commit cuối). Thực hiện việc đó như sau:

Vào Repo(C1) tạo 1 file mới tên là 6.txt sau đó commit, tiếp tục tạo file mới 7.txt và commit tiếp, cuối cùng là push nhánh master lên Remote

$ touch 6.txt
$ git add .
$ git commit -m"C11"
$ touch 7.txt
$ git add .
$ git commit -m"C12"
$ git push origin master #đẩy commit mới lên Remote

Giờ quay trở lại Repo(C2), cũng tạo ra 2 sự thay đổi (thêm file mới) và mỗi sự thay đổi thực hiện một commit (C13, C14) - nhớ là ở Repo(C2) sau commit không push

$ touch 8.txt
$ git add .
$ git commit -m"C13"
$ touch 9.txt
$ git add .
$ git commit -m"C14"

Tại Remote gõ xem trạng thái, thấy HEAD ở C12

$ git log --oneline -4
31b00bb (HEAD -> master) C12
c187f7c C11
544511a (beta) C10
be103d9 C9

Tại Repo(2) xem trạng thái, thấy HEAD trỏ tới C14, còn origin/master vẫn đứng ở C10

$ git log --oneline -4
e172085 (HEAD -> master) C14
a607f5c C13
544511a (origin/master, origin/beta, origin/HEAD) C10
be103d9 C9

Bây giờ tại Repo(C2) gõ lệnh git fetch origin hoặc git fetch --all lệnh này sẽ tìm trong origin những dữ liệu mới sau đó cập nhật vào dữ liệu của Repo(C2). Sau đó kiểm tra trạng thái

$ git status
On branch master
Your branch and 'remotes/origin/master' have diverged

Nó cho biết nhánh masterorigin/master tại Repo(C2) bị phân nhánh. Có thể chuyển xem log của origin/master

$ git checkout origin/master
$ git log --oneline -4
e172085 (HEAD -> origin/master, master) C14
a607f5c C13
544511a (origin/beta) C10
be103d9 C9
$ git checkout master

Qua đó dựng được tình trạng masterorigin/master bị phân ly như sau:

3) Pull - Hợp nhánh bị phân ly

Để hợp nhánh phân ly trên dùng lệnh merge đã biết để hợp nhánh origin/master vào master sau khi fetch dữ liệu về.

Quá trình trên có thể tự động luôn cả 2 (tức là fetch xong, merge luôn) bằng lệnh git pull

$ git pull origin master

Nếu có yêu cập nhập message khi hợp nhánh thì nhập C15 - Merge remote/origin/master, nếu có xung đột thì xử lý như phần xung đột khi merge

Sau khi pull kiểm tra log

$ git log --oneline -8
7ae3beb (HEAD -> master) C15 - Merge remote/origin/master
e172085 (origin/master) C14
a607f5c C13
31b00bb (origin/master, origin/HEAD) C12
c187f7c C11
544511a (origin/beta) C10
be103d9 C9
1a90428 C8

4) Push - cập nhật lên Remote

Hiện giờ tại Remote do Repo(C1) cập nhật làm cho Remote có master với snapshot cuối C12. Khi Repo(C2) cần cập nhật cũng gọi lệnh push như đã biết

$ git push origin master

Tương tự lúc này Repo(C1) có thể pull về cập nhật các commit mà Repo(C2) cập nhật

5) Xóa nhánh tại Remote

$ git push remotename --delete branchname

Đổi tên nhánh Local và Remote

Để đổi tên một Branch ở Local sau đó thay đổi trên Remote làm như sau:

git branch -m old_branch new_branch         # Đổi tên ở Local
git push origin :old_branch                 # Xóa nhánh ở Remote
git push --set-upstream origin new_branch   # Cập nhật nhánh có tên mới lên Remote

Cập nhật nhánh mới từ Remote vào Local

git pull origin                                   # Cập nhật thông tin từ Remote
git branch -r                                     # Liệt kê các nhánh ở Remote
git checkout -b branchname  origin/branchname     # Tao nhánh mới ở Local theo Remote
Mục lục Git - GitHub