Git stash là chi nhánh cụ thể hay cho toàn bộ kho lưu trữ?


95

Tôi đi vào một chi nhánh và làm một số công việc. Tôi muốn đi vào một chi nhánh khác nhưng không muốn cam kết nên tôi đã làm git stash. Sau đó, tôi đã làm git checkout <otherbranch>. Tôi đã làm một số công việc ở đó và cũng giống như ở chi nhánh đầu tiên, tôi muốn chuyển khỏi nó trước khi thực hiện công việc. Vì vậy, tôi cũng đã làm git stashở đó. Tôi quay trở lại nhánh đầu tiên và cố gắng gỡ bỏ ( git stash pop) vì nghĩ rằng nó sẽ lấy được dấu từ nhánh cụ thể đó. Tôi ngạc nhiên rằng nó đã loại bỏ kho lưu trữ khỏi <otherbranch>(lưu trữ mới nhất). Tôi có ấn tượng rằng kho lưu trữ là dành riêng cho chi nhánh nhưng hành vi này chỉ ra rằng chỉ có một kho lưu trữ cho toàn bộ kho lưu trữ cục bộ.

git stashchi nhánh cụ thể hoặc cho toàn bộ kho lưu trữ? Nếu nó là cho toàn bộ kho, tôi có thể chuyển các tùy chọn cho nó để làm cho nó trở thành chi nhánh cụ thể không?

Câu trả lời:


43

Để xem kho lưu trữ hiện tại:

git stash list

Để chọn một kho cụ thể từ ngăn xếp, hãy tham khảo nó bằng cách hiển thị ở trên.stash@{number}

Nếu bạn muốn hành vi là trên mỗi nhánh, bạn chỉ có thể thực hiện một cam kết (hoặc nhiều lần cam kết) trên nhánh. Bạn luôn có thể "hủy bỏ" (các) cam kết sau đó (ví dụ: với git reset, --softhoặc --mixed; xem tài liệu git reset ; hoặc với git rebase -iđể chỉ giữ (các) cam kết "thực" cuối cùng trong khi loại bỏ các thời gian tạm thời).

(Để thực sự mô phỏng, git stashbạn cần ít nhất hai cam kết, một cho trạng thái chỉ mục và một cho trạng thái cây công việc. Tuy nhiên, nếu bạn không định lưu và khôi phục trạng thái chỉ mục, bạn có thể chỉ git add -Atoàn bộ trạng thái cây công việc và đưa nó vào cam kết tạm thời. Ngoài ra, git stashlà một tập lệnh shell để bạn có thể sao chép và sửa đổi nó khá dễ dàng để làm cho nó hoạt động theo từng nhánh theo mặc định, ví dụ: sử dụng không gian tên làm việc của nó, thay vì toàn cục duy nhất cho toàn bộ repo. Bạn vẫn có thể chuyển kho lưu trữ từ chi nhánh này sang chi nhánh khác bằng cách đặt tên rõ ràng.)refs/pb-stash/branchrefs/stash


bạn có biết làm thế nào để hiển thị danh sách tệp của mỗi stash listmục ngoài mô tả?
lưỡng cư

2
git stash show(hoặc git stash show stash@{<number>}cho một cái gì đó khác với @{0}phiên bản) cung cấp cho bạn một diff --stat; thêm -pđể có được sự khác biệt lớn hơn. Lưu ý: điều này so sánh "cây công việc" trong "túi lưu trữ" với cam kết mà nó treo; không có giao diện front-end để xem những gì trong "chỉ mục" trong túi lưu trữ nhất định.
torek

55

Không và Không. Git stash là trên mỗi kho.

Đây là một trang hay về cách sử dụng nó.


kho thứ hai có ghi đè kho thứ nhất không? IOW, nếu tôi thực hiện hai lần lưu trữ nhưng không có dấu gạch chéo ở giữa, tôi có bị mất lần lưu trữ đầu tiên không?
lưỡng cư

1
Không, bạn sẽ nhận được một ngăn xếp (cuối cùng trong đầu ra) của các kho. Bạn đẩy một stash để stash-stack của bạn, sau đó khác sau đó bạn thoát khỏi thứ 2 sau đó bạn thoát khỏi sự đầu tiên, vv
abasterfield

18

git stash không phải là mỗi nhánh.

  • Thay vì git stash (có thể bị mất dễ dàng khi bạn có nhiều kho và nhánh)
  • Tôi khuyên bạn nên thực hiện a git commitđể lưu mã chưa hoàn thành trong chi nhánh của bạn và khi bạn đã sẵn sàng hoàn thành mã, hãy thực hiện a git reset ${COMMIT_HASH_VALUE}để lấy lại mã chưa hoàn thành
  • git commitgit resetkhi được sử dụng cùng nhau một cách chính xác có thể mô phỏng một git stashcho một nhánh cụ thể

Đây là một tình huống thực tế phổ biến thể hiện giá trị và cách sử dụng các lệnh commitreset:

  • bạn đang làm việc trên nhánh tính năng X và mã của bạn thậm chí không biên dịch hoặc vượt qua các bài kiểm tra
  • có một lỗi có mức độ ưu tiên cao hơn tính năng mới hiện tại và vì vậy bạn phải bắt đầu công việc sửa lỗi ngay lập tức
  • thay vì thực hiện một kho lưu trữ git (và kho lưu trữ bị mất trong hỗn hợp vì bạn có nhiều kho lưu trữ và nhiều nhánh)
  • bạn có thể làm git committrên nhánh tính năng X
    • viết ra COMMIT_HASH_VALUEsau
  • kiểm tra chi nhánh Y mới để sửa lỗi nóng
  • hoàn thành sửa chữa nóng trên nhánh Y (thực hiện yêu cầu hợp nhất để đưa sửa chữa nóng vào đường cơ sở và xóa nhánh sửa chữa nóng)
  • sau đó kiểm tra lại nhánh tính năng X
  • để bật công việc chưa hoàn thành của bạn mà không biên dịch hoặc vượt qua thử nghiệm -> chỉ cần thực hiện git reset ${COMMIT_HASH_VALUE}

(FYI mặc định git reset--mixed)


2
Một phím tắt tiện dụng để đặt lại trong trường hợp này là git reset HEAD~1.
Sam A. Horvath-Hunt

1
@samHH Tôi đã gặp quá nhiều trường hợp với git reset HEAD ^ 1 lần vô tình bị đánh hai lần ... vì vậy tôi chọn không sử dụng HEAD^1hoặc HEAD~1.
Trevor Boyd Smith

11

Tôi không chắc tại sao mọi câu trả lời ở đây đều đề xuất mô phỏng kho với commit+ reset. Stash hoàn toàn tốt để sử dụng, đặc biệt là khi làm việc trên nhiều nhánh. Tôi cũng không muốn cam kết khi tôi làm việc trên nhiều nhánh, vì tôi muốn rằng tất cả các thay đổi đã sửa đổi vẫn được đánh dấu trong trình chỉnh sửa của tôi khi tôi quay lại.

Vì vậy, đây là quy trình lưu trữ:

Bất cứ khi nào bạn phải chuyển nhánh và bạn chưa sẵn sàng cam kết, hãy lưu các thay đổi của bạn vào ngăn xếp

git stash save "Your custom stash message"

Khi bạn quay lại một chi nhánh, hãy kiểm tra kho

git stash list

nhập mô tả hình ảnh ở đây

Nếu bạn ở chi nhánh, FixIssue0203bạn có thể sử dụng sử dụng git stash popvì điều này sẽ áp dụng trên cùngstash@{0} và xóa nó khỏi kho lưu trữ.

Tuy nhiên, nếu trong chi nhánh của ImproveReadmebạn, trước tiên bạn nên áp dụng kho 1 git stash apply stash@{1}và sau đó xóa kho 1 khỏi ngăn xếp git stash drop stash@{1}.

Đó là nó!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.