Merge and Rebase

Merge và rebase đều là đem sự thay đổi ở một branch sang branch khác.

Merge

Áp dụng những sự thay đổi từ branch khác vào branch hiện tại.

Cú pháp:

git merge branch_name

Giả sử ta có hai branch A và B. Merge branch B vào branch A như sau:

git checkout A
git merge B

Sau khi merge thì branch A sẽ có thêm một commit (merge commit).

Minh họa:

Rebase

Rebase khác merge ở chỗ nó nối toàn bộ danh sách commit vào một branch duy nhất. Từ “rebase” có nghĩa là thay thế phần core data sao cho ý nghĩa cuối cùng không thay đổi.

Cú pháp:

git rebase branch_name

Câu lệnh giúp rebase branch hiện tại bằng branch branch_name (nối các commit của branch hiện tại vào branch branch_name).

Giả sử ta có hai branch main và feature. Rebase feature với base là main như sau:

git checkout feature
git rebase main

Sau khi rebase thì toàn bộ các commit ở branch feature sẽ được nối vào sau commit cuối cùng của branch main.

Minh họa:

Điểm mạnh của rebase so với merge là:

  • Nó làm cho lịch sử commit trở nên tuyến tính và dễ đọc.
  • Lược bỏ được các merge commit không cần thiết.

Attention

Chỉ nên dùng rebase cho những branch nào không public và không được nhiều người follow.

Câu lệnh git rebase còn có option -i cho phép chỉnh sửa nội dung các commit hoặc thứ tự của chúng trước khi rebase.

Seealso

Fetch

Câu lệnh git fetch vừa là git pull vừa là git merge.

Cherry Pick

Cho phép chọn một số commit cụ thể từ branch khác và cho vào branch hiện tại. Trong trường hợp ta lỡ commit nhầm branch thì ta có thể dùng tính năng này.

Chúng ta cũng có thể dùng để tạo ra một hotfix commit khi đang code dang dở một feature nào đó mà có bug từ production. Branch main sẽ chọn hotfix commit đó để fix bug cho người dùng.

Cú pháp:

git cherry-pick commitHash

Giả sử ta có hai branch như sau:

a - b - c - d      main
	 \
	   e - f - g   feature

Để chọn commit f và cho vào branch main, trước tiên ta cần chuyển sang branch main:

git checkout main

Sau đó dùng cherry-pick như sau:

git cherry-pick f

Git history khi đó sẽ có dạng như sau:

a - b - c - d - f   main
	 \
	   e - f - g    feature

Seealso

Stash

Giúp lưu tạm code đang làm dở vào stack, mà cụ thể là RAM máy tính (nếu tắt máy thì sẽ bị mất).

Lưu vào stash với message:

git stash save "I have no idea"

Hiển thị danh sách các stash:

git stash list

Kết quả có dạng như sau:

stash@{0}: WIP on master: 4e22905 abc 1865891265912
stash@{1}: On master: Toi dang Code cai gi the nay
(END)

Apply stash:

git stash apply

Câu lệnh này sẽ apply stash mới nhất (theo cơ chế truy xuất của stack).

Để apply một stash cụ thể thì specify stash ID phía sau. Ví dụ:

git stash apply 'stash@{0}'

Để apply và xóa luôn stash thì dùng pop:

git stash pop [Stash ID]

Seealso

Config

Trong Git có ba loại config scope:

Cấu hình có scope nhỏ hơn sẽ cascade cấu hình có scope lớn hơn. Nói cách khác, cấu hình local sẽ overwrite cấu hình global và system.

Xem các config:

git config --list
git config --list --system
git config --list --global
git config --list --local

Nếu không chỉ định scope thì output sẽ là một danh sách tổng hợp cả ba loại config.

Thêm hoặc xóa config:

# to add
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
 
# to remove
git config --global --unset user.name
git config --global --unset user.email

Để chỉnh sửa config thì dùng:

git config --edit

Patch

Giả sử ta có một số thay đổi ở và muốn gửi những thay đổi này sang một máy khác hoặc cho người khác. Ta có thể dùng lệnh sau:

git diff > name.patch

Câu lệnh này sẽ sinh ra một file có tên là name.patch (với name là tùy ý). Chúng ta có thể gửi file này đi và bên nhận sẽ apply những thay đổi như sau:

git apply name.patch

Conventional Commit

Some types:

Filter Branch

Xóa file khỏi toàn bộ lịch sử của git:

git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch recon/oppo/domains-alive-ffuf.txt' \
--prune-empty --tag-name-filter cat -- --all

Archive

Nén file tracked bởi git:

git archive --format=zip --output=archive.zip HEAD

Resources