Git diff chống lại một stash


Câu trả lời:


1872

Xem stash gần đây nhất:

git stash show -p

Xem một stash tùy ý:

git stash show -p stash@{1}

Từ các git stashtrang:

Theo mặc định, lệnh hiển thị diffstat, nhưng nó sẽ chấp nhận bất kỳ định dạng nào được biết đến với git diff (ví dụ: git stash show -p stash @ {1} để xem stash gần đây thứ hai ở dạng bản vá).


72
stash@{0}là mặc định; bạn chỉ cần một đối số nếu bạn muốn xem xét các stash trước đó.
Cascabel

52
Đúng. Tôi chỉ cung cấp nó để rõ ràng làm thế nào để xem xét các stash khác bên cạnh {0}.
Amber

74
Điều này sẽ không hiển thị sự khác biệt giữa stash và dir hoạt động hiện tại, nhưng giữa stash và cha mẹ ban đầu của nó. Đúng? Từ trang hướng dẫn: "Hiển thị các thay đổi được ghi trong ngăn chứa dưới dạng khác biệt giữa trạng thái được lưu trữ và cha mẹ ban đầu của nó."
Magne

14
@Amber - Đúng, mặc dù nếu cây làm việc hiện tại của bạn bị bẩn, nó quan trọng và làm cho nó phức tạp hơn một chút. Tôi đến đó từ góc độ đó, và tìm thấy một thủ tục tôi chia sẻ trong câu trả lời của tôi dưới đây.
Magne

6
những gì hiện -pđứng cho?
Gerald

308

Để xem stash gần đây nhất:

git stash show -p

Để xem một stash tùy ý:

git stash show -p stash@{1}

Ngoài ra, tôi sử dụng git diff để so sánh stash với bất kỳ nhánh nào.

Bạn có thể dùng:

git diff stash@{0} master

Để xem tất cả các thay đổi so với chủ chi nhánh.


Hoặc bạn có thể sử dụng:

git diff --name-only stash@{0} master

Để dễ dàng tìm thấy chỉ thay đổi tên tập tin.


10
Điều này không trả lời câu hỏi cụ thể. Nếu bạn đã tạo stash từ master (để lưu công việc cho sau này), sau đó thực hiện một số cam kết cho công việc khác trên master, sau đó git diff stash@{0} master, bạn sẽ nhận được một stash khác với master hiện tại (bao gồm cả công việc được thực hiện trên master sau stash đã được thực hiện), không phải các tệp / dòng mà stash sẽ thay đổi, đó là những gì câu hỏi là về.
Tom De Leu

52
Tôi rất vui vì bạn đã trả lời câu hỏi ngay cả khi đó không phải là câu trả lời cho câu hỏi chính xác. Nó đã cung cấp thêm thông tin và tôi nghĩ thật tuyệt khi biết làm thế nào để có sự khác biệt giữa một nhánh và bất kỳ nhánh nào khác mà bạn muốn so sánh với nó. Tôi cũng thích học cờ
Rebekah Waterbury

6
này cũng cho phép nhìn vào sự khác biệt bằng trình xem tùy chỉnh khác, ví dụ nhưgit difftool --tool=... stash@{0} HEAD
Andre Holzner

9
@TomDeLeu Quan sát tốt và một điểm quan trọng. Để so sánh một mục stash với cha mẹ của nó, điều này dường như hoạt động:git diff stash@{0}^ stash@{0}
erikprice

1
Đồng thời, bạn có thể thêm tên tệp git diff stash@{0} master -- filenameđể nhận các thay đổi đối với một tệp cụ thể.
David

104

Nếu nhánh mà các thay đổi được lưu trữ của bạn dựa trên đã thay đổi trong thời gian đó, lệnh này có thể hữu ích:

git diff stash@{0}^!

Điều này so sánh stash với cam kết mà nó dựa trên.


rất tốt, tôi đã thêm một bí danh vào ~/.gitconfig:laststash = diff stash@{0}^!
sbeam 17/03/2016

5
Cặp đôi hoàn hảo: git difftool stash^!đối với khác biệt của lần gửi cuối cùng với cam kết, nó được dựa trên, git difftool stash HEADđối với khác biệt của lần gửi cuối cùng với cam kết hiện tại (stash @ {n} cho các lần gửi trước đó)
ChrisV


"git diff stash @ {0} ^!" sôi sùng sục xuống "git diff stash @ {0} ^ stash @ {0} ~ 1 ^ stash @ {0} ~ 2 ......." nhưng vì git diff chỉ mất 2 lần xác nhận, nó cho thấy sự khác biệt giữa stash @ {0} và ^ stash @ {0} ~ 1 và trông ^ ở đầu cam kết thứ 2 không tạo ra bất kỳ sự khác biệt nào và git bỏ qua nó.
Naga Kiran

Tôi thích phiên bản này để có thể sử dụng công cụ tìm khác biệt ưa thích của tôi (Tất nhiên là so sánh!). Điều này cũng cho thấy sự thay đổi trong stash này mà tôi tin là câu hỏi ban đầu, trái ngược với một thay thế được đề cập trong các ý kiến ​​trên "git diff stash @ {X} ^ stash @ {X}" không chỉ hiển thị khác so với stash diff.
dùng107172

44

Nếu cây làm việc của bạn bị bẩn , bạn có thể so sánh nó với stash bằng cách trước tiên cam kết cây làm việc bẩn, sau đó so sánh nó với stash. Sau đó, bạn có thể hoàn tác cam kết với cây làm việc bẩn (vì bạn có thể không muốn có cam kết bẩn đó trong nhật ký cam kết của mình).

Bạn cũng có thể sử dụng cách tiếp cận sau đây để so sánh hai stash với nhau (trong trường hợp đó bạn chỉ bật một trong các stash lúc đầu).

  • Cam kết cây làm việc bẩn thỉu của bạn:

    git add .
    git commit -m "Dirty commit"
    
  • Khác biệt với bản cam kết đó:

    git diff HEAD stash@{0}
    
  • Sau đó, sau đó, bạn có thể hoàn nguyên cam kết và đưa nó trở lại vào thư mục làm việc:

    git reset --soft HEAD~1
    git reset .
    

Bây giờ bạn đã phân biệt cây làm việc bẩn thỉu với stash của mình và quay lại nơi ban đầu.


Có một cách để làm điều này nhưng chỉ nhìn thấy một sự khác biệt của các tệp sẽ bị thay đổi bởi những gì trong stash?
lagweezle

Năm 2020 điều này đơn giản hơn nhiều; kiểm tra của tôi câu trả lời up-to-date .
David Deprost

Thú vị, tôi không biết về git stash show -l . Liệu nó có khác với bản sao mới nhất chống lại bản sao (bẩn) không? Làm thế nào để bạn sử dụng nó mà không nhận được error: switch l requires a value?
Magne

Vâng, thực sự, nó khác với bản sao làm việc (có thể bẩn). Bạn sử dụng nó đơn giản bằng cách nhập git stash show -l. Về lý do tại sao nó không làm việc cho bạn, tôi chỉ có thể đoán bạn có thể đang ở phiên bản cũ hơn của git? Tôi đang sử dụng git v2.20.1 và nó hoạt động hoàn hảo không có lỗi.
David Deprost

25

Câu trả lời của @ Magne là ngày duy nhất (rất muộn) trả lời cách giải thích linh hoạt / hữu ích nhất cho câu hỏi, nhưng nó hơi phức tạp hơn mức cần thiết. Thay vì cam kết và đặt lại, chỉ cần bỏ bản sao làm việc của bạn, so sánh, sau đó hủy bỏ.

git stash save "temp"
git diff stash@{0} stash@{1}
git stash pop

Điều đó cho bạn thấy sự khác biệt giữa đỉnh ngăn xếp và thư mục làm việc của bạn bằng cách tạm thời thay đổi thư mục làm việc của bạn trở thành đỉnh của ngăn xếp (stash @ {0}), di chuyển từ trên xuống dưới (stash @ {1} ) sau đó so sánh bằng cách sử dụng đỉnh ban đầu ở vị trí set bộ mới 'để bạn thấy những thay đổi sẽ dẫn đến việc áp dụng nó lên trên công việc hiện tại của bạn.

"Nhưng nếu tôi không có công việc hiện tại thì sao?" Sau đó, bạn đang ở trong trường hợp nhàm chán bình thường. Chỉ cần sử dụng câu trả lời của @ Amber

git stash show

hoặc câu trả lời của @ czerasz

git diff stash@{0}

hoặc thừa nhận rằng stashing và unstashing là nhanh chóng và dễ dàng, chỉ cần hủy bỏ các thay đổi và kiểm tra chúng. Nếu bạn không muốn chúng tại thời điểm này, hãy ném chúng (chỉ mục hiện tại / thư mục làm việc thay đổi) đi. Đầy đủ đó

git stash apply
git diff
git reset
git checkout

3
Cách tiếp cận đơn giản này (stash và sau đó so sánh với stash khác) là an toàn và dễ hiểu. Đối với một số trường hợp sử dụng, bạn có thể muốn lưu trữ các tệp không bị theo dõi vớigit stash save -u
mleonard

19

Điều này hoạt động với tôi trên phiên bản git 1.8.5.2:

git diff stash HEAD

2
Gây hiểu lầm! Câu hỏi là: Làm thế nào tôi có thể thấy những thay đổi không được thực hiện đối với cây làm việc hiện tại? Điều này cho thấy sự khác biệt giữa stash và HEAD có thể RẤT khác với những gì sẽ được áp dụng git stash apply.
MikeJansen

Vui lòng đọc thêm câu hỏi "Tôi muốn biết những thay đổi sẽ được thực hiện trước khi áp dụng chúng!". Tôi đang cung cấp một câu trả lời nhanh chóng cho điều này.
yerlilbilgin

Ngoài ra, bạn có thể thấy tất cả các câu trả lời khác bằng cách nào đó về việc phân biệt đầu hiện tại (hoặc bộ làm việc) chống lại stash. Tại sao chỉ có câu trả lời của tôi sai lệch? Đó không phải là công bằng.
yerlilbilgin

@yerlilbilgin Xem phản hồi của tôi về câu trả lời của bạn dưới đây.
MikeJansen

Chúng ta có thể gọi là CHÍNH, theo mặc định, phải không?
Al.G.

10

Trong trường hợp, để so sánh một tệp trong cây làm việc và trong ngăn chứa, hãy sử dụng lệnh dưới đây

git diff stash@{0} -- fileName (with path)

9

Nếu bạn có công cụ cho diff (như ngoài so sánh)

git difftool stash HEAD

1
Gây hiểu lầm! Câu hỏi là: Làm thế nào tôi có thể thấy những thay đổi không được thực hiện đối với cây làm việc hiện tại? Điều này cho thấy sự khác biệt giữa stash và HEAD có thể RẤT khác với những gì sẽ được áp dụng git stash apply.
MikeJansen

1
Nếu bạn nghĩ rằng điều này là sai lệch, xin vui lòng kiểm tra tất cả các câu trả lời khác. Đó không phải là công bằng!
yerlilbilgin

1
Bạn sẽ lưu ý rằng tôi đã sao chép cùng một bình luận cho câu trả lời khác giống như câu trả lời sai (khá giống với câu trả lời). Những câu trả lời khác đã có một nhận xét tương tự tôi để lại một mình. Nếu bạn hiểu cách hoạt động của git stash, thì bạn sẽ nhận ra rằng khác biệt giữa stash với HEAD không phải là những gì được áp dụng (đó là những gì OP yêu cầu). "Stash" thực tế là sự khác biệt giữa cam kết stash và những gì trước đó. Bản vá này sau đó được áp dụng cho ĐẦU. Vì vậy, nếu bạn muốn biết những gì OP yêu cầu, bạn phải hiển thị sự khác biệt giữa stash và cam kết trước nó, câu trả lời đúng.
MikeJansen

1
Điều này trả lời câu hỏi trực tiếp hơn bất kỳ câu trả lời dài (không cần thiết) nào khác, và thực hiện chính xác những gì OP yêu cầu, rút ​​ngắn HEAD. Tôi có thể sửa đổi câu trả lời của @ yerlilbilgin để loại bỏ ĐẦU nhưng tôi nghĩ rằng bất kỳ ai sử dụng git đều có thể tìm ra phần đó và tôi kéo dài câu trả lời sẽ khiến nó không thể đọc được. Không đổ lỗi cho @yerlibilgin.
Sridhar Sarnobat

4

Một cách để làm điều này mà không cần di chuyển bất cứ điều gì là tận dụng thực tế patchcó thể đọc git diff (cơ bản là khác biệt)

git stash show -p | patch -p1 --verbose --dry-run

Điều này sẽ cho bạn thấy một bản xem trước từng bước về những gì bản vá thường sẽ làm. Lợi ích bổ sung cho điều này là bản vá sẽ không ngăn bản thân viết bản vá lên cây làm việc, nếu vì lý do nào đó bạn thực sự cần git để im lặng về việc cam kết trước khi sửa đổi, hãy tiếp tục và xóa --dry- chạy và làm theo hướng dẫn dài dòng


2

Kết hợp những gì tôi đã học được trong chủ đề này và trong bài viết này , khi tôi muốn xem "những gì bên trong thùng rác", lần đầu tiên tôi chạy:

git stash show stash@{0}

Điều đó sẽ hiển thị những tập tin đã được sửa đổi. Sau đó, để có được một hình ảnh khác biệt đẹp trong một Difftool, tôi làm:

git difftool --dir-diff stash@{0} stash@{0}^

Điều này sẽ hiển thị tất cả sự khác biệt cùng một lúc của stash đã cho so với cha mẹ của nó.

Bạn có thể định cấu hình công cụ tìm khác ~/.gitconfig, ví dụ như với Meld :

...
[diff]
    tool = meld

1

FWIW Điều này có thể hơi dư thừa đối với tất cả các câu trả lời khác và rất giống với câu trả lời được chấp nhận tại chỗ; nhưng có lẽ nó sẽ giúp được ai đó

git stash show --helpsẽ cung cấp cho bạn tất cả những gì bạn cần; bao gồm thông tin chương trình stash.

hiển thị [<stash>]

Hiển thị các thay đổi được ghi lại trong ngăn chứa dưới dạng khác biệt giữa trạng thái được lưu trữ và cha mẹ ban đầu của nó. Khi không được đưa ra, hiển thị cái mới nhất. Theo mặc định, lệnh hiển thị diffstat, nhưng nó sẽ chấp nhận bất kỳ định dạng nào được biết đến với git diff (ví dụ: git stash show -p stash @ {1} để xem stash gần đây thứ hai ở dạng bản vá). Bạn có thể sử dụng các biến cấu hình stash.showStat và / hoặc stash.showPatch để thay đổi hành vi mặc định.


1

Cô ấy danh sách stash

git stash list 
stash@{0}: WIP on feature/blabla: 830335224fa Name Commit
stash@{1}: WIP on feature/blabla2: 830335224fa Name Commit 2

Vì vậy, lấy số stash và làm:

Bạn có thể làm:

 git stash show -p stash@{1}

Nhưng nếu bạn muốn tìm khác biệt (điều này khác với hiển thị stash, đó là lý do tại sao tôi viết câu trả lời này. Hãy Diffxem xét mã hiện tại trong chi nhánh của bạn và showchỉ hiển thị những gì bạn sẽ áp dụng )

Bạn có thể dùng:

git diff stash@{0}

hoặc là

git diff stash@{0} <branch name>

Một điều thú vị để làm là:

git stash apply
git stash apply stash@{10}

Điều này áp dụng stash mà không xóa nó khỏi danh sách, bạn có thể git checkout .xóa những thay đổi đó hoặc nếu bạn vui lòng git stash drop stash@{10}xóa stash khỏi danh sách.

Từ đây tôi không bao giờ khuyên bạn nên sử dụng git stash popvà sử dụng kết hợp git stash applygit stash dropNếu bạn áp dụng một stash ở nhánh sai ... đôi khi rất khó để khôi phục mã của bạn.


1

Tùy thuộc vào những gì bạn muốn so sánh stash với (cây làm việc cục bộ / cam kết cha mẹ / cam kết đầu), thực tế có một số lệnh có sẵn, trong đó có lệnh cũ git diffvà cụ thể hơn git stash show:

╔══════════════════════╦═══════════════════════════════╦═══════════════════╗
║ Compare stash with ↓ ║ git diff                      ║ git stash show    ║
╠══════════════════════╬═══════════════════════════════╬═══════════════════╣
║ Local working tree   ║ git diff stash@{0}            ║ git stash show -l ║
║----------------------║-------------------------------║-------------------║
║ Parent commit        ║ git diff stash@{0}^ stash@{0} ║ git stash show -p ║
║----------------------║-------------------------------║-------------------║
║ HEAD commit          ║ git diff stash@{0} HEAD       ║   /               ║
╚══════════════════════╩═══════════════════════════════╩═══════════════════╝

Mặc dù git stash showtrông thân thiện với người dùng hơn từ cái nhìn đầu tiên, nhưng git diffthực sự mạnh mẽ hơn ở chỗ nó cho phép chỉ định tên tệp cho một khác biệt tập trung hơn. Cá nhân tôi đã thiết lập bí danh cho tất cả các lệnh này trong plugin zsh git của mình .

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.