Hoàn tác vô tình git stash pop


186

Tôi đã bỏ qua một số thay đổi cục bộ trước khi thực hiện hợp nhất phức tạp, thực hiện hợp nhất, sau đó ngu ngốc quên cam kết trước khi chạy git stash pop. Pop đã tạo ra một số vấn đề (các cuộc gọi phương thức xấu trong một cơ sở mã lớn) đang tỏ ra khó theo dõi. Tôi đã chạy git stash show, vì vậy tôi ít nhất biết những tập tin đã được thay đổi. Nếu không có gì khác, tôi đoán đây là một bài học để cam kết nhiều hơn.

Câu hỏi của tôi: có thể hoàn tác stash pop mà không hoàn tác hợp nhất không?


2
Bạn không được phép git stash popmà không cam kết trước. Bạn đã làm gì để đạt được điều đó?
Chris Jester-Young

Không chắc chắn trung thực (đây là ngày hôm qua). Việc hợp nhất đã không tự cam kết vì có xung đột. Tôi bằng cách nào đó có thể chạy stash pop sau đó.
NREN

1
Tôi đã làm điều này chỉ biết sử dụng phiên bản git 1.7.9.msysgit.0. Tôi đã có các tập tin chưa được chỉnh sửa và stash pop vừa hợp nhất mọi thứ.
PandaWood

Tôi đã có thể chạy git stash popsau khi dàn dựng các thay đổi (mặc dù tôi không cam kết) với phiên bản 2.25.0.windows.1 của git
Artem Hevorhian

Nếu bạn đã lập chỉ mục các thay đổi của mình và mất chúng khi bạn chạy stash pop/applytrước khi thực hiện cam kết, bạn có thể thực hiện git fsck --lost-found. Lệnh này sẽ lặp qua các đốm màu lơ lửng (các tệp thực tế cho những người không quen thuộc với thuật ngữ git) đã được dàn dựng nhưng không được cam kết ở bất cứ đâu (do đó là lơ lửng) và đặt chúng trong thư mục .git / Lost-Found / , nơi bạn có thể git showxem và xem nếu đây là những tập tin mà bạn đang tìm kiếm
Artem Hevorhian

Câu trả lời:


69

Hãy thử sử dụng Làm thế nào để khôi phục một stash bị rơi trong Git? để tìm stash bạn xuất hiện. Tôi nghĩ rằng luôn có hai cam kết cho một stash, vì nó bảo toàn chỉ mục và bản sao làm việc (vì vậy thường thì cam kết chỉ mục sẽ trống). Sau đó, git showhọ để xem khác biệt và sử dụng patch -Rđể không hài lòng họ.


6
Wow mà làm việc. Tôi đã có thể tìm thấy các cam kết stash với git fsck --no-reflog | awk '/dangling commit/ {print $3}'(từ liên kết) và tôi chỉ tìm thấy thủ công từ vấn đề đó. Cảm ơn!
NREN

1
fsck đưa ra một danh sách lớn. Thật tẻ nhạt khi git hiển thị mỗi SHA1 ngoài kia. Làm thế nào để bạn làm điều này ?
meson10

5
@ meson10: Thật không may, các stash được giữ trong một reflog, đó sẽ là cách rõ ràng (nếu chúng là một nhánh thực sự) để xem xét lịch sử của các stash popped. Ngoài ra, hãy để tôi đề xuất rằng downvote + yêu cầu trợ giúp không phải là chiến lược tốt nhất.
Ben Jackson

2
Tôi phải mất một chút xáo trộn để làm cho đúng. Đây là kết quả công việc của tôi : git diff -p ${STACH_SHA1}~1 ${STASH_SHA1} | patch -R -p1; Tôi đã thử với git showđề xuất nhưng đầu ra của nó không tốt cho bản vá; Ngoài ra, tôi phải cung cấp -p1tùy chọn vá để loại bỏ phần tử a/..b/..phần tử git diffđặt trước các tệp nếu không nó sẽ không giải quyết được các đường dẫn từ thư mục gốc của kho lưu trữ. SUGGESTION: thận trọng và thực hiện các mớ hỗn độn trong một nhánh riêng biệt trước khi chơi với bản vá.
basilikode

@BenJackson Trong câu trả lời của bạn "luôn luôn" có nghĩa là cả hai stash popstash pushsẽ kích hoạt một cam kết sẽ lưu các thay đổi vào chỉ mục và thư mục làm việc, phải không?
Artem Hevorhian

36

Từ git stash --help

Recovering stashes that were cleared/dropped erroneously
   If you mistakenly drop or clear stashes, they cannot be recovered through the normal safety mechanisms. However, you can try the
   following incantation to get a list of stashes that are still in your repository, but not reachable any more:

       git fsck --unreachable |
       grep commit | cut -d\  -f3 |
       xargs git log --merges --no-walk --grep=WIP

Điều này giúp tôi tốt hơn câu trả lời được chấp nhận với cùng một kịch bản.


13
Lưu ý rằng rất nhiều giải pháp liên quan đến tìm kiếm "WIP" đang dựa vào các thông báo ẩn mặc định. Nếu bạn cung cấp cho stash tin nhắn rõ ràng của họ, họ có thể không chứa WIP.
Ben Jackson

cảm ơn. Tôi đã thêm tùy chọn --oneline vào lệnh log để cải thiện khả năng đọc.
basslo

Điều này chỉ giúp bạn tìm thấy SHA của cam kết stash. Nhưng nếu được tích hợp với nhận xét @basilikode từ câu trả lời được chấp nhận (git diff SHA ~ 1 SHA | patch -R), nó hoạt động tốt. Tôi khuyên bạn nên sử dụng đường dẫn --dry-run trước để kiểm tra.
Jarek C

2

Nếu việc hợp nhất của bạn không quá phức tạp, một tùy chọn khác sẽ là:

  1. Di chuyển tất cả các thay đổi bao gồm cả thay đổi hợp nhất trở lại stash bằng cách sử dụng "git stash"
  2. Chạy hợp nhất một lần nữa và cam kết các thay đổi của bạn (không có thay đổi từ ngăn chứa bị bỏ đi)
  3. Chạy một "git stash pop" sẽ bỏ qua tất cả các thay đổi từ hợp nhất trước đó của bạn vì các tệp này giống hệt nhau bây giờ.

Sau đó, bạn chỉ còn lại những thay đổi từ stash mà bạn đã bỏ quá sớm.

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.