Trong quá trình làm việc chắc hẳn các bạn sẽ không tránh khỏi những trường hợp như này, đang code dở một tính năng mới (chưa kịp hoàn thiện), thì lại có một yêu cầu khẩn cấp từ sếp hoặc có một bug cần phải xử lý ngay thời điểm đó.

Mỗi lần gặp tình huống này, nếu trường hợp code ở hai branch khác nhau thì không sao, code tính năng mới ở một nhánh, xử lý vấn đề khẩn cấp ở một nhánh khác, tuy nhiên vấn đề sẽ rắc rối hơn chút khi bạn cần sửa cùng một file, cùng class, hoặc cần sửa trên chính branch bạn đang viết feature luôn. Vậy làm thế nào để xử lý vấn đề này một cách chuyên nghiệp nhất?

Git stash

Trước khi đi vào chi tiết việc git stash giải quyết vấn đề chuyên nghiệp như thế nào, chúng ta sẽ đề cập một chút đến flow git bình thường như sau:

git-command-advance

Working Directory

Đây là nơi chúng ta làm việc, mọi tệp mà chúng ta tạo và sửa đổi trong dự án đều được lưu trữ trong working-directory (thư mục dự án), chúng ta có thể sử dụng lệnh git status  để xem danh sách các tệp được sửa đổi bởi nhánh hiện tại.

Như hình bên dưới, nó sẽ hiển thị những tệp nào đã được sửa đổi trong không gian làm việc hiện tại và những tệp nào chưa được thêm vào quản lý git.

git status

Staging Area

Khu vực này gọi là bộ nhớ đệm lưu trữ, tại đây lưu trữ tất cả các commit của bạn, có trách nhiệm cực kì quan trọng, tuy nhiên bài viết này mình không tập trung phân tích chi tiết luồng xử lý của khu vực này.

Khi sử dụng lệnh git add file-abc-xyz , chúng ta đưa tệp có tên file-abc-xyz vào vùng lưu trữ tạm thời, nếu tất cả các tệp cần được đưa vào, chúng ta có thể sử dụng  git add .  để thêm tất cả các tệp đã sửa đổi vào vùng lưu trữ tạm thời.

Các tệp ở khu vực này được chuẩn bị cho lần gửi tiếp theo tới local repository

Lệnh git add -p : lệnh này hay ở chỗ, trong một file mình đã xử lý, thì phần code phía trên mình muốn commit nó vào lần commit sắp tới, còn phần code bên dưới mình không muốn commit nó nhưng mình đã sửa rồi và không muốn vứt ra chỗ khác, thì lệnh này là phương án tuyệt vời.

Bạn có thể hình dung bằng ảnh bên dưới:

git add -p
  • Mũi tên thế nhất: đoạn này mình không muốn commit nó, thế nên khi được hỏi thì mình điền n
  • Mũi tên thứ hai: đoạn này mình muốn commit nó, thế nên khi được hỏi thì mình điền y
  • Mũi tên thứ ba: đoạn này mình không muốn commit, nên mình điền n

Tới lúc này khi kiểm tra lại bằng git status , ta thấy trong cùng một file, thì phần code mà mình muốn commit thì đã được đẩy vào khu vực staging area (xanh lá), còn phần code chưa được đẩy vào thì vẫn nằm ở ngoài (đỏ)

git status

Git Local Repository

Kho lưu trữ cục bộ git, ở đây khi code đã được đẩy vào bộ nhớ đệm (Staging Area) ở bước trước thì chúng ta có thể sử dụng lệnh git commit -m "typing message commit here" để gửi tệp vào kho lưu trữ cục bộ, sau đó dùng lệnh git push origin branch để đẩy các thay đổi đến kho từ xa.

Đến đây xuất hiện kịch bản như ở đầu bài, bạn cần sửa lỗi khi đoạn mã viết được một nửa, nhưng bạn không muốn gửi đoạn mã chưa viết xong thì phải làm sao ? git stash lúc này sẽ giúp bạn

git stash save "typing log stash here" : lưu trữ các đoạn code xử lý dở vào khu vực lưu trữ tạm thời, xem ảnh bên dưới để hình dung rõ hơn.

Ban đầu git status để theo dõi hiện trạng, khi đó hệ thống có file đã sửa và muốn commit, có file đã sửa và không muốn commit

git status: xem hiện trạng trước khi dùng lệnh git stash

Sau đó dùng lệnh git stash save "typing log stash here" , lúc này ta thấy trên branch master đã không còn bất kì thay đổi nào nữa, và chúng ta thoải mái xử lý công việc của mình.

git stash save “typing log stash here”

Vậy thì sau khi xử lý xong vấn đề khẩn cấp, bạn quay lại công việc của mình, và cần lấy lại những thay đổi đã đẩy vào stash thì làm thế nào?

Dùng lệnh git stash apply stash@{id_stash} hoặc lệnh git stash pop để lấy lại những thay đổi, tuyệt vời luôn.

git stash apply stash@{id_stash} hoặc lệnh git stash pop

Dưới đây là các lệnh git stash mình thường xuyên dùng:

  • git stash list : xem danh sách những stash đã lưu
  • git stash save "typing log stash here" : lưu những thay đổi hiện tại thành 1 stash commit
  • git stash apply stash@{id_stash} : dùng để lấy lại những thay đổi từ stash đẩy vào branch cục bộ hiện tại
  • git stash pop : chức năng giống hệt lệnh trên, tuy nhiên nó sẽ lấy những thay đổi từ stash trên cùng, sau đó clear stash commit đó đi (mình chỉ dùng lệnh này khi đảm bảo được cái stash commit mới nhất mình đã đặt trong stash bao gồm những gì, thì mình sẽ chỉ lấy cái đầu tiên, tuy nhiên phải rất cẩn thận vì nhiều khi không để ý lại lấy những thay đổi không mong muốn vào branch hiện tại thì rất mất công ngồi loại bỏ)
  • git stash clear : xóa toàn bộ kho lưu trữ stash

Well, giờ lại có vấn đề mới, giả sử mình lỡ tay dùng lệnh git stash clear toàn bộ kho lưu trữ stash, trong khi chưa kịp apply lại những phần mình cần thì phải làm sao để lấy lại được code bây giờ???

thực hiện clear stash trước khi apply, sau đó lấy lại stash
git stash apply commit_id

Quá trình của việc lấy lại stash đã clear của tôi như sau:

  • git stash save "message" ban đầu lưu những đoạn code đã sửa thành một stash
  • git stash clear : xóa toàn bộ dữ liệu trong kho lưu trữ stash
  • git log --graph --oneline --decorate $( git fsck --no-reflog | awk '/dangling commit/ {print $3}') : lấy lại pipeline lịch sử
  • git stash apply commit_id : lấy lại code từ stash đã xóa vào branch hiện tại

Một số bài viết liên quan: