() translation by (you can also view the original English article)
Hãy tưởng tượng rằng bạn đang làm việc trên một tính năng ở trong một dự án phần mềm được quản lý bởi Git. Bạn đang ở ngay giữa chừng trong việc tạo ra một số thay đổi thì bạn nhận được một yêu cầu khắc phục một lỗi nghiêm trọng. Để bắt đầu giải quyết vấn đề, bạn cần một branch mới và một thư mục rỗng. Khi nói đến lệnh Git cơ bản, bạn có hai lựa chọn:
- Chạy
git reset --hard
để loại bỏ những thay đổi đã được commit của bạn. - Ghi lại công việc chưa hoàn tất của bạn như là một commit mới.
Tùy chọn đầu tiên làm mất tất cả công việc của bạn, trong khi cái sau dẫn đến một phần commit không có ý nghĩa. Không có tình huống là được mong đợi cả.
Đây là lúc lệnh git stash
phát huy tác dụng của nó. Giống như git reset --hard
, nó cung cấp cho bạn một thư mục rỗng, nhưng nó cũng ghi lại các thay đổi không đầy đủ bên trong. Sau khi khắc phục xong lỗi nghiêm trọng, bạn có thể tái áp dụng những thay đổi này và bắt đầu lại từ nơi bạn đang dở dang. Bạn có thể xem git stash
như một nút "tạm dừng" cho tiến trình công việc của bạn.



Các yêu cầu
Hướng dẫn này giả sử rằng bạn đã cài đặt Git và bạn đã nắm vững tiến trình làm việc với nó. Bạn sẽ cần phải nắm rõ về việc xác định các thay đổi, tạo các commit, và làm việc với branch. Bạn cũng cần một kho chứa Git để thực hành trên nó.
1. Stash các thay đổi
Trước khi bạn chạy lệnh git stash
, bạn cần phải có một vài sự thay đổi chưa được commit ở trong kho chứa Git của bạn. Ví dụ, nếu bạn chỉnh sửa một tập tin được gọi là foo.py
, thì git status
của bạn sẽ xuất ra kết quả như sau:
1 |
On branch master |
2 |
Changes not staged for commit:
|
3 |
(use "git add <file>..." to update what will be committed) |
4 |
(use "git checkout -- <file>..." to discard changes in working directory) |
5 |
|
6 |
modified: foo.py |
Để stash những thay đổi này, chỉ cần thực thi lệnh git stash
không có tham số.
1 |
git stash |
Nó sẽ lấy cả những sự thay đổi đã xác định và chưa xác định của bạn, ghi chúng lại bên trong, sau đó dọn sạch sẽ thư mục hiện tại. Điều này tạo điều kiện cho bạn để chuyển sang một branch mới và phát triển các tính năng khác mà không lo lắng về phần commit của bạn sẽ làm rối tung mọi thứ.
2. Áp dụng lại những thay đổi đã được Stash
Khi bạn đã sẵn sàng quay trở lại với công việc chưa hoàn tất của bạn, hãy chạy lệnh sau đây để tái áp dụng những thay đổi đã được stash:
1 |
git stash pop |
Những thay đổi gần đây đã được stash sẽ tái xuất hiện trong thư mục hiện tại của bạn và bạn có thể tiếp tục ở đúng nơi mà bạn đã để lại. Tất cả đều ở đó.
3. Giải quyết đụng độ
Cũng giống như lệnh git merge
, git stash pop
có thể dẫn đến xung đột nếu cùng một phần của mã nguồn đã thay đổi kể từ khi bạn thực hiện git stash
. Khi điều này xảy ra, bạn sẽ thấy thông báo sau sau khi chạy git stash pop
:
1 |
Auto-merging foo.py |
2 |
CONFLICT (content): Merge conflict in foo.py |
Bạn cũng sẽ tìm thấy các tập tin bị ảnh hưởng được liệt kê ở dưới Unmerged paths
trong kết quả của lệnh git status
, cũng như các dòng bị ảnh hưởng trong tập tin nguồn.
1 |
<<<<<<< Updated upstream |
2 |
print("Recently committed changes"); |
3 |
=======
|
4 |
print("Incomplete work"); |
5 |
>>>>>>> Stashed changes |
Bạn sẽ cần phải giải quyết xung đột trong tập tin nguồn bằng tay, nhưng bạn thường không muốn commit nó ngay lập tức giống như cách bạn làm sau một xung đột khi git merge
. Phần lớn, bạn sẽ tiếp tục làm việc trên các tính năng chưa hoàn thiện của bạn cho đến khi bạn đã chuẩn bị một commit có ý nghĩa. Sau đó, bạn có thể chỉ cần thêm nó vào chỉ mục và cọmmit nó như bình thường. Nói cách khác, bạn có thể xem các xung đột của git stash pop
giống như bất kỳ thay đổi chưa commit khác.
4. Ngăn xếp Stash
Trong hầu hết trường hợp, các lệnh ở trên là tất cả những gì mà bạn cần khi nói đến một "nút tạm dừng". Tuy nhiên, hiểu những thay đổi được stash đang diễn đạt là gì mở ra cánh cửa cho việc sử dụng nâng cao hơn.
Cho đến lúc này, chúng ta chỉ mới nói về stash một tập hợp các thay đổi duy nhất. Tuy nhiên, mỗi khi bạn chạy git stash
, các thay đổi chưa được commit được lưu trữ trên một ngăn xếp. Điều này có nghĩa rằng bạn có thể stash nhiều tập hợp các thay đổi cùng một lúc.



Điều này là hữu ích trong giai đoạn đầu của phát triển khi bạn không chắc chắn hướng nào mà bạn muốn đi. Thay vì mất các thay đổi của bạn với git reset --hard
, thì bạn có thể giữ các snapshot đang trong tiến trình của bạn trên ngăn xếp stash trong trường hợp bạn muốn tái áp dụng một trong số chúng sau này.
Bạn có thể kiểm tra ngăn xếp stash với tham số list
.
1 |
git stash list |
Nếu bạn đã từng thực hiện lệnh git stash
ba lần, thì nó sẽ ra một cái gì đó như sau:
1 |
stash@{0}: WIP on new-feature: 5cedccc Try something crazy |
2 |
stash@{1}: WIP on new-feature: 9f44b34 Take a different direction |
3 |
stash@{2}: WIP on new-feature: 5acd291 Begin new feature |
Lệnh git stash pop
luôn tái áp dụng snapshot mới nhất, một cái ở trên cùng của ngăn xếp stash. Tuy nhiên, chúng ta cũng có thể lấy và chọn snapshot mà bạn muốn tái áp dụng với lệnh apply
. Ví dụ, nếu bạn muốn tái áp dụng tập hợp các thay đổi thứ hai, bạn sẽ sử dụng lệnh sau đây:
1 |
git stash apply stash@{1} |
Cũng giống như git stash pop
, những thay đổi sẽ tái xuất hiện trong thư mục hiện tại của bạn và bạn có thể tiếp tục làm việc trên tính năng chưa hoàn tất. Lưu ý rằng việc này sẽ không tự động loại bỏ snapshot khỏi ngăn xếp stash. Thay vào đó, bạn sẽ cần phải xoá nó thủ công bằng lệnh drop
.
1 |
git stash drop stash@{1} |
Một lần nữa, làm việc với ngăn xếp stash giúp giải quyết những trường hợp nguy cấp đối với hầu hết người sử dụng Git. Các lệnh git stash
và git stash pop
sẽ đủ cho hầu hết các nhu cầu của bạn, mặc dù git stash list
cũng tỏ ra hữu ích nếu bạn quên vị trí hoạt động của stash cuối cùng ở đâu.
Kết luận
Commit những snapshot có ý nghĩa là trung tâm của bất kỳ hoạt động Git nào. Những commit có mục đích, được đóng gói làm cho nó dễ dàng hơn để điều hướng lịch sử của dự án, tìm ra nơi mà lỗi phát sinh và quay trở lại thay đổi.
Mặc không hoàn toàn là một lệnh sử dụng thường xuyên, nhưng git stash
có thể là một công cụ rất thuận tiện cho việc tạo ra các commit có ý nghĩa. Nó cho phép bạn lưu trữ các công việc chưa hoàn tất trong khi tránh cần phải commit một phần của snapshot vào lịch sử lâu dài của dự án. Ghi nhớ điều này trong lần tới nếu bạn muốn tạm dừng bất cứ điều gì mà bạn đang làm và quay trở lại nó sau này.