Git stash chưa được xóa: làm thế nào để loại bỏ tất cả các thay đổi chưa được phân giai đoạn?


96

Giả sử hai tập hợp các thay đổi được thực hiện trong một dự án được phiên bản bằng git. Một bộ được dàn dựng và bộ còn lại thì không.

Tôi muốn kiểm tra lại các thay đổi theo giai đoạn bằng cách chạy dự án của mình ở trạng thái này (trước khi cam kết). Cách đơn giản để loại bỏ tất cả các thay đổi chưa theo giai đoạn và chỉ để lại theo giai đoạn là gì? Vì vậy, tôi cần các thay đổi chưa được đánh dấu để biến mất khỏi dự án của mình, nhưng được lưu trữ ở đâu đó để làm việc sau này.

Điều này nghe rất giống git stashlệnh. Nhưng git stashsẽ loại bỏ cả những thay đổi chưa theo giai đoạn và có giai đoạn khỏi dự án của tôi. Và tôi không thể tìm thấy một cái gì đó giống như git stash uncached.


Cho đến ngày hôm nay với git 2.21 của tôi, vẫn chưa có câu trả lời tốt cho điều này. Tất cả các câu trả lời dưới đây đều không chính xác ( -ktùy chọn) hoặc cồng kềnh để sử dụng.
Penghe Geng

Câu trả lời:


98

Cập nhật 2:
Tôi không chắc tại sao mọi người lại phàn nàn về câu trả lời này, có vẻ như nó đang hoạt động hoàn hảo với tôi, đối với các tệp chưa được giải quyết, bạn có thể thêm -ucờ

Lệnh đầy đủ trở thành git stash --keep-index -u

Và đây là một đoạn trích từ git-stashtrợ giúp

Nếu tùy chọn --keep-index được sử dụng, tất cả các thay đổi đã được thêm vào chỉ mục sẽ được giữ nguyên.

Nếu tùy chọn --include-unracked được sử dụng, tất cả các tệp chưa được kiểm soát cũng được lưu trữ và sau đó được dọn dẹp bằng git clean, để lại thư mục làm việc ở trạng thái rất sạch. Nếu tùy chọn --all được sử dụng thay thế thì các tệp bị bỏ qua sẽ được lưu trữ và làm sạch ngoài các tệp chưa được theo dõi.

Và đây là ảnh gif của nó trông như thế nào:

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

Cập nhật:

Mặc dù đây là câu trả lời được chọn, nhưng nhiều người đã chỉ ra rằng [câu trả lời bên dưới] (https://stackoverflow.com/a/34681302/292408) là câu trả lời chính xác, tôi khuyên bạn nên kiểm tra.

Tôi đã kiểm tra lại câu trả lời của mình hôm nay (31/1/2020) với phiên bản git 2.24.0và tôi vẫn tin rằng nó đúng, tôi đã thêm một lưu ý nhỏ ở trên về các tệp chưa được kiểm tra. Nếu bạn cho rằng nó không hoạt động, vui lòng đề cập đến phiên bản git của bạn.

Câu trả lời cũ :
Nếu --keep-indextùy chọn được sử dụng, tất cả các thay đổi đã được thêm vào chỉ mục vẫn được giữ nguyên:

git stash --keep-index

Từ tài liệu củagit-stash :

Kiểm tra cam kết từng phần

Bạn có thể sử dụng git stash save --keep-indexkhi bạn muốn thực hiện hai hoặc nhiều cam kết trong số các thay đổi trong cây công việc và bạn muốn kiểm tra từng thay đổi trước khi cam kết:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part'     # commit fully tested change
$ git stash pop                  # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'

Tuy nhiên, nếu bạn chỉ muốn kiểm tra trực quan các thay đổi theo giai đoạn, bạn có thể thử difftool:

git difftool --cached

4
cũng xem git stash [-p|--patch]cảm giác giống như lưu trữ tương tác. Từ man git stash"Với --patch, bạn có thể tương tác chọn các nhóm từ sự khác biệt giữa HEAD và cây làm việc được lưu trữ."
đây

1
Tôi thường add -p, checkout -preset -p, không bao giờ cố gắng stash -p, thanks for the tip: D
Mohammad AbuShady

18
Lưu ý rằng câu trả lời này cũng sẽ lưu trữ những thay đổi mà bạn đã thực hiện.
Ben Flynn

Câu trả lời này không thực sự hữu ích vì nó sẽ dẫn đến nhầm lẫn. Câu trả lời này tốt hơn là stackoverflow.com/a/34681302/292408 .
Elijah Lynn

1
@ElijahLynn Tôi đã liên kết đến câu trả lời khác vì tôi thấy rất nhiều người nói rằng đó là câu trả lời hay hơn, cảm ơn bạn đã nhận xét
Mohammad AbuShady

99

Câu trả lời được chấp nhận cũng lưu trữ các thay đổi theo giai đoạn như một số đã chỉ ra và nó không lưu trữ các tệp chưa được theo dõi. Đây là một cách để làm điều đó mà không nhận được các thay đổi theo giai đoạn của bạn trong kho lưu trữ, đồng thời xóa và lưu trữ các tệp không được theo dõi.

Ý tưởng là thực hiện cam kết tạm thời đối với các thay đổi theo giai đoạn của bạn, sau đó lưu trữ các thay đổi chưa theo giai đoạn, sau đó bỏ cam kết tạm thời:

# temp commit of your staged changes:
$ git commit --message "WIP"

# stage your previously unstaged files before stashing (so you get untracked files):
$ git add .

$ git stash

# now un-commit your WIP commit:
$ git reset --soft HEAD^

Tại thời điểm này, bạn sẽ có một tập hợp các thay đổi chưa theo giai đoạn và sẽ chỉ có các thay đổi theo giai đoạn trong bản sao làm việc của bạn.


21
Đây thực sự là câu trả lời chính xác IMO. Các --keep-indextùy chọn trong câu trả lời được chấp nhận hiện nay vẫn còn ẩn nấp gì trong chỉ mục, nó chỉ còn giữ nó trong chỉ mục. Vì vậy, sau đó nó được nhân bản và sự vui nhộn xảy ra sau đó.
Ken Williams

3
@KenWilliams <del> hilarity </del> <ins> bi kịch </ins>
tuespetre 13/09/17

@KenWilliams Điều đó thực sự khiến tôi khó chịu. OP, bạn có thể vui lòng điều chỉnh câu trả lời đã chọn?
MikeMurko

2
Bạn git add .có thể muốn cải thiện bước này vì bước git add --allnày cũng sẽ lấy các tệp trong thư mục phía trên thư mục làm việc hiện tại.
Elijah Lynn

1
Đây là câu trả lời tốt nhất cho đến nay, vì tùy chọn --keep-index trong câu trả lời được chấp nhận là sai lầm. Đây phải là câu trả lời được chấp nhận.
Elijah Lynn

21

Tôi thấy câu trả lời được đánh dấu không phù hợp với tôi vì tôi cần thứ gì đó thực sự chỉ lưu trữ những thay đổi chưa được phân giai đoạn của tôi. Câu trả lời được đánh dấu, lưu trữ git stash --keep-indexcả những thay đổi theo giai đoạn và không theo giai đoạn. Phần này cũng --keep-indexchỉ giữ nguyên chỉ mục trên bản sao đang làm việc. Điều đó có hiệu quả với OP, nhưng chỉ vì anh ấy đã hỏi một câu hỏi hơi khác với câu trả lời mà anh ấy thực sự muốn.

Cách đúng duy nhất mà tôi đã tìm thấy để lưu trữ các thay đổi chưa theo giai đoạn là hoàn toàn không sử dụng kho lưu trữ:

git diff > unstaged.diff
git apply -R unstaged.diff

git checkout -- .cũng sẽ hoạt động thay vì apply -R.

Làm việc công việc làm việc ...

git apply unstaged.diff
rm unstaged.diff

1
Ở đây git version 2.6.1.windows.1, git stash -khoạt động như mô tả.
koppor

Đây phải là câu trả lời được chấp nhận! Đây là luồng duy nhất trong nhiều luồng stackoverflow thực hiện những gì nó tuyên bố và không dựa vào việc thực hiện cam kết tạm thời!
user643011

1
@ user643011: Cam kết tạm thời không phải là một điều xấu trong git. Chúng không tốn kém gì và không gây hại cho ai.
Fritz

1
@Fritz: Không thể thực hiện cam kết tạm thời trong một số trường hợp. Nó có thể không thành công nếu bạn có một hook cam kết trước để kiểm tra mã làm việc hiện tại. Nếu các thay đổi theo giai đoạn của bạn là tốt nhưng các thay đổi chưa theo giai đoạn của bạn thì không, thì cách tiếp cận này sẽ không thực hiện được các thay đổi theo giai đoạn.
Penghe Geng

1
Điều này không bao gồm các tệp chưa được theo dõi. Bạn cần phải sử dụng "git ls-files" để tìm & bao gồm những người trong bản vá diff
acyclic

5

Git: Thay đổi không theo giai đoạn chuỗi

Điều này sẽ lưu trữ tất cả các sửa đổi mà bạn không thêm vào:

git stash -k

Lưu ý rằng các tệp mới được tạo (và không được thêm) sẽ vẫn ở trong thư mục làm việc của bạn trừ khi bạn cũng sử dụng công -utắc.

git stash -k -u 

Ngoài ra, thư mục làm việc của bạn phải sạch sẽ (tức là tất cả các thay đổi cần được thêm vào) khi bạn bật git stash sau này.

http://makandracards.com/makandra/853-git-stash-unstaged-changes


13
Điều này tương đương với git stash --keep-index. Các tệp theo giai đoạn được bao gồm trong kho lưu trữ.
Benjamin Cheah
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.