Đôi lúc git pull và push đều vô nghĩa với những trường hợp phổ biến trong team tôi

Nội dung bài viết

Video học lập trình mỗi ngày

Hiểu rõ về git có lẽ giờ đây là điều bắt buộc đối với các developers hiện nay. Nhưng hình như đa số anh em chỉ biết mỗi push, pull, merge, rebase và một số thao tác cơ bản khác. Đến khi gặp những tình huống dưới đây mới cảm thấy thiếu hụt về kinh nghiệm sử dụng git.

Quảng cáo về các video về Git

Một phút cho quảng cáo, nếu như bạn chưa biết cách các công ty quản lý code như thế nào trên git thì hãy dành cho mình một chút thời gian để xem qua qua Gitflow - 90% các công ty đều muốn developer phải tuân theo.

Ngoài ra dành cho những bạn có nhiệm vụ hợp nhất branch thì có hai cách phổ biến nhưng sự khác nhau thì thấy rõ đó là Vì sao sếp bắt tôi phải sử dụng git rebase thay vi merge.

Đó là hai bài học chất lượng, có thể nói nếu như học xong, bạn có thể tự tin về sử dung git. Không tin hãy đọc những comments của các đại ca để lại trong đó.

Kết thúc quảng cáo

Cách sử dụng git cho những tình huống phổ biến

Tôi biết ai cũng trải qua những điều kỳ diệu trong công việc của mình, nhưng liệu bạn có ghi lại những điều đó để thế hệ sau or những ai gặp lại những vấn đề mà ta đã từng giải quyết? Ít ai, nhưng riêng tôi thì đã lưu lại trên videoblog. Những điều được trình bày sẽ cải thiện đáng kể cũng như giải quyết những khó khăn trong lập trình và bài ở đây nói về git. Hy vọng rằng những anh em đi theo nghề code này, sẽ rút bớt thời gian để chinh phục nhiều thành công mới. OK.

Tôi sẽ trình bày thêm những cách sử dụng và mô tả những tình huống gặp phải khi phải làm việc trong team và quản lý code theo quy chuẩn của công ty. Kèm theo đó là tôi đã fixed nó như thế nào? Hy vọng sẽ được anh em ủng hộ.

git cherry pick

Đây cũng là một câu hỏi của một bạn khi xem bài Tóm tắt toàn diện về việc sử dụng Git và quy trình làm việc của GitFlow.

  • Tình huống thực tế như sau:

M10 đã làm xong hai task 1task 2 ở nhánh dev. Và lead CR7 được yêu cầu là CHỈ ĐƯA task 1 lên master và chuẩn bị cho production. Như vậy thì làm thế nào, vì M10 đã đưa hai task 1task 2 lên rồi.

  • Mô hình như sau
t1 - t2 - t3 - t4   Master -> CR7
         \
           t5 - t6 - t7 Feature -> M10

Giờ ta muốn đưa t5 vào Master (cr7) thì ta sẽ có như sau:

 t1 - t2 - t3 - t4 - t5   Master -> CR7
         \
           t5 - t6 - t7  Feature -> M10
  • Cách giải quyết:
➜  git-tutorials git:(cr7) git branch m10
➜  git-tutorials git:(cr7) git checkout m10
Switched to branch 'm10'
➜  git-tutorials git:(m10) git add .
➜  git-tutorialse git:(m10) ✗ 
➜  git-tutorials git:(m10) ✗ git commit -m 'task 1'
[m10 2f99b9e] task 1
 1 file changed, 1 insertion(+)
➜  git-tutorials git:(m10) git add .             
➜  git-tutorials git:(m10) ✗ git commit -m 'task 2'
[m10 bab5b59] task 2
 1 file changed, 2 insertions(+), 1 deletion(-)
➜  git-tutorials git:(m10) git log
➜  git-tutorials git:(m10) git log --oneline
➜  git-tutorials git:(m10) 
➜  git log --oneline
bab5b59 (HEAD -> m10) task 2
2f99b9e task 1

Khi xem git log --oneline chúng ta thấy có hai commits như trên. Giờ muốn CR7 chỉ nhận được task 1 thì sử dụng như sau. Đầu tiên chuyển qua nhánh cr7 sau đó sử dụng

➜  git-tutorials git:(cr7) git cherry-pick 2f99b9e

Với 2f99b9e chính là commitHash xem trong git log của M10. Như vậy thì cr7 sẽ có được task 1, có thể xem lại log. Sau đó tạo nhánh cho production. OK như vậy đã xong cho các bạn! Nhưng với tôi thì chưa xong, tôi còn muốn các bạn biết thêm một số tính năng nâng cao khi sử dụng git cherry pick.

Câu hỏi: Tôi muốn chuyển nhiều commits lên một lúc khi sử dụng cherry pick được không?. Vâng, được. Nếu bạn muốn thì không có cách nào tốt hơn khi sử dụng git cherry pick

➜  git-tutorials git:(cr7) git cherry-pick 2f99b9e 2f99b9f

Trong đó 2f99b9e2f99b9f chính là các commitHash. Đến đây sẽ có nhiều đại ca tinh ý sẽ phát hiện có vấn đề vì giả sử 20 commits thì làm như vậy sẽ chết chắc. À không, đương nhiên những gì bạn suy nghĩ về tình huống đó thì các bô lão cũng đã tính hết rồi. Ví dụ, giả sử team chúng ta commits từ t1 đến t99. Giờ ta muốn chỉ lấy t2 đến t20 thì hãy làm như sau:

➜  git-tutorials git:(cr7) git cherry-pick t1..t20

Lệnh trên có thể chuyển tất cả các commit từ t1 sang t20. Chúng phải được đặt theo đúng thứ tự: Commit t1 phải đứng trước t20, nếu không lệnh sẽ không thành công mà không có lỗi.

Lưu ý rằng với lệnh trên, commit t1 sẽ không được đưa vào git Cherry pick. Nếu bạn muốn bao gồm cam kết t1, bạn có thể sử dụng cú pháp sau.

➜  git-tutorials git:(cr7) git cherry-pick t1^..t20

trong quá trình sử dụng git Cherry pick thì không tránh khỏi sự xung đột hay còn gọi là conflict thì anh em học thêm mấy keys này nữa: --continue, --abort, và --quit.

git stash

Tình huống sau đây có lẽ phổ biến hơn nhiều so với tình huống sử dụng git cherry pick như sau:

Một ngày đẹp trời M10 đang làm viết tính năng Giảm hàng tồn kho khi lượt truy cập lớn trong eCommerce. Và đột nhiên lại là lead Cr7 chạy đến và thông báo gấp, có một hotfix ở nhánh master (xem lại video trước để biết hotfix nên từ nhánh nào?) cần thực hiện và sửa ngay. Tại thời điểm này, tính năng của M10 mới phát triển được nửa chừng, vì vậy M10 vội vàng chuyển sang nhánh hotfix thì sẽ chắc chắn có lỗi sau:

error: Your local changes to the following files would be overwritten by

➜  git-rebase-merge git:(m10) git checkout production
error: Your local changes to the following files would be overwritten by checkout:
        task.md
Please commit your changes or stash them before you switch branches.
Aborting

Lỗi này được giải thích sau: Vì hiện tại có các files đang triển khai giữa chừng, theo nguyên tắc bạn phải cần gửi một commit lên trước khi chuyển nhánh khác để làm việc nếu không sẽ bị lỗi như trên. Thực tế tôi đã gặp rất nhiều, các bạn hoảng hốt cho nên commit đại lên cho dù 1/2... và ghi notes lại "Em đang làm 1/2. Mong các anh thông cảm". Không nên làm vậy, hãy chuyên nghiệp cho dù bạn là người rửa chén. Và sau đây là cách giải quyết tình huống trên.

  • Cách giải quyết:

Đừng hoảng hốt, đó là điều kiện tiên quyết khi bạn phải giải quyết điều gì, nhớ nhé, đừng hoảng hốt. Hãy sử dụng git stash. Điều kỳ điệu đang đến... Khi bạn làm điều đó thì những gì bạn đang làm sẽ thu lại một chỗ. Và khi bạn muốn lấy ra thì chỉ cần git stash apply là xong. Gọn gàng sạch sẽ. Chưa dừng lại, tôi sẽ chỉ cho bạn nhiều hơn những gì bạn nhìn thấy.

Có ai hỏi tôi điều này "stash nhiều lần được không?" Xin thưa là thoải mái, và bạn chỉ cần apply theo id stash là ok. Ví dụ như sau:

➜  git-rebase-merge git:(m10) ✗ git stash         
Saved working directory and index state WIP on m10: bab5b59 task 2

➜  git-rebase-merge git:(m10) git stash  list 
stash@{0}: On m10: doing task 4
stash@{1}: On m10: doing task 1
stash@{2}: WIP on m10: bab5b59 task 2

➜  git-rebase-merge git:(m10) git stash  apply stash@{1}
  • Các lệnh stash nên biết:
# Đang làm trước khi chuyển nhánh thì nên
git stash

# Nếu bạn là người cẩn thận thì nên thêm notes vào
git stash save "Doing task 1"

# Danh sách đã stash
git stash list

# Xóa hết
git stash clear

# apply stash gần nhất
git stash apply

# xóa stach gần nhất
git stash pop

Một vài tips nho nhỏ

Nếu như commit mà sai thì hay đọc câu thần chú --amend... để sửa lại hén.

$ git commit --amend -m "Fixes bug #2"

Khi lỡ commits nhưng hối hận và suy nghĩ lại thì nên sử dụng

> git reset --soft <commit-hash>

Ví dụ:

> git log --oneline
> 1
> 2
> 3
> git reset --soft 1
> git log --oneline
> 2
> 3

Bạn thực hiện một vài cam kết trên nhánh hiện tại và đột nhiên nhận ra rằng bạn đã đặt nhầm nhánh mà lẽ ra ở nhánh khác.

> $ git branch feature
> 
> $ git reset --hard [commit hash]
> 
> $ git checkout feature
>

Thao tác trên tương đương với việc hoàn tác các thay đổi của chi nhánh hiện tại và đưa những thay đổi này vào một chi nhánh mới.

Hết. Quyết thắng và bạn muốn pro hơn thì nên xem lại những link và tôi đã gợi ý trong bài viết.

Có thể bạn đã bị missing