2012-07-03 31 views
9

Tôi sử dụng git checkout --<dir_name(or)file_name> để hủy tất cả các thay đổi trong thư mục cụ thể hoặc trong tệp. Bất cứ khi nào tôi làm điều đó, GIT sẽ kiểm tra thư mục (hoặc) từ kho lưu trữ.- tùy chọn chạy trong git checkout

Có cách nào tôi có thể nói GIT ?, "không ghi đè các thay đổi, chỉ cho tôi biết những gì sẽ xảy ra."

Tương tự như git clean -n (hoặc) git clean --dry-run.

CẬP NHẬT: Trước khi tôi thực hiện, git checkout --src/, tôi muốn xem các tệp sẽ bị ghi đè là gì. Tôi biết chúng tôi có thể sử dụng git status src/. Nhưng, sẽ không tuyệt vời khi có git checkout -n --src/? Không có nhiều thay đổi lệnh cho người dùng.

+0

Có lẽ tôi đang bối rối nhưng không phải bạn chỉ yêu cầu sự khác biệt giữa cây làm việc của bạn và chỉ mục? Chúng được hiển thị với 'git diff'. –

+0

@TilmanVogel: Như bạn đã biết, lệnh 'git clean' sẽ xóa các tập tin không được theo dõi. nhưng 'git clean -n' sẽ không xóa các tệp, nó chỉ cho biết các tệp sẽ bị xóa là gì. Tôi chỉ muốn biết, Có tùy chọn như vậy trong lệnh git checkout. Cảm ơn. –

+0

Ok, sau đó xem 'git help checkout' dễ dàng trả lời câu hỏi này là "không". Và tôi nghĩ lý do là 'git status' và' git diff' cùng nhau cung cấp tất cả thông tin tương ứng. Tôi cũng thích 'git citool' cho chế độ xem đó. Tất nhiên, câu chuyện là một câu chuyện khác khi sử dụng 'git checkout' trên một thứ khác ngoài chỉ mục. –

Trả lời

3

Bạn có thể chạy

$ git checkout --patch -- <files> 

và nó sẽ yêu cầu đối với từng sự khác biệt cho dù bạn muốn "kiểm tra" sự khác biệt đó. Nếu bạn nói không cho mỗi lời nhắc, thì nó để nó bị ảnh hưởng.

+0

Rất đẹp. Đó là những gì tôi muốn. Cảm ơn. –

+0

Nhưng tôi vẫn cảm thấy, Nó có thể là tuyệt vời nếu 'git checkout' có tùy chọn' -n' giống như 'git clean'. Chỉ cần cung cấp cho chúng tôi danh sách tên tệp chứ không phải nội dung. Dù sao cũng cảm ơn bạn. –

1

Không chắc chắn nhưng là một công việc xung quanh bạn có thể không git stash -u sau đó git apply sau đó git checkout?

Bạn luôn có thể hoàn nguyên về phía sau nếu bạn không hài lòng.

5

Lệnh Git checkout không có tùy chọn dry-run (hoặc tương tự). Tuy nhiên, bạn có thể sử dụng lệnh Git ls-files để xem cái nào làm việc thư mục tập tin khác nhau từ HEAD:

git ls-files -dm -- src/ 

này sẽ liệt kê tất cả các file đã bị xóa hoặc sửa đổi, các tập tin đó thường sẽ được ghi đè bởi một checkout.

lựa chọn khác là sử dụng lệnh Git diff:

git diff --name-only HEAD -- src/ 

này liệt kê tất cả các file mà khác với TRỤ và sẽ được thay thế trên một checkout.

Nếu đây là cái gì đó sẽ được thực hiện thường xuyên, bạn có thể muốn tạo một alias:

git config --global alias.lco "diff --name-only HEAD" 

Sau đó, bạn có thể sử dụng:

git lco -- src/ 
+0

Cảm ơn Dan. Nó rất hữu ích. Tôi đã upvote :-) –

0

Nếu bạn muốn tránh tương tác (a la "nói không với từng lời nhắc"), sử dụng git diff. Nếu bạn muốn có câu trả lời chính xác cho câu hỏi của bạn, hãy sử dụng git diff -R. Nếu bạn chỉ muốn tên tệp, hãy sử dụng git diff --name-only.

Nếu không có cờ -R, git diff sẽ báo cáo tất cả sự khác biệt giữa cây làm việc và chỉ mục của bạn ở định dạng bản vá, tức là định dạng bạn thấy khi bạn phát hành git show <commit>. Các -R đảo ngược đầu ra, cho bạn thấy những gì sẽ xảy ra là những thay đổi bị loại bỏ, như thể loại bỏ bản thân nó là một bản vá.Hãy xem xét ví dụ:

git init /tmp/test && cd /tmp/test 
echo "old line">file 
git add . 
git commit -m "Initial commit" 
echo "new line">file 

Vấn đề hiện tại git diff không có bất kỳ cờ nào. Bạn sẽ nhận được:

$ git diff 
diff --git a/file b/file 
index 0906fba..86ba82a 100644 
--- a/file 
+++ b/file 
@@ -1 +1 @@ 
-old line 
+new line 

Thẳng thắn mà nói, tôi thấy rằng sản lượng đủ dễ dàng để phân tích tôi không bao giờ sử dụng -R cờ. Nếu bạn thường xuyên phát hành các lệnh git diff (và tôi thấy nó là một trong những lệnh phổ biến nhất mà tôi sử dụng), đầu ra đảo ngược có thể không cần thiết. Tất cả tương tự, với mục đích của câu trả lời này, hãy thử:

$ git diff -R 
git diff -R 
diff --git b/file a/file 
index 86ba82a..0906fba 100644 
--- b/file 
+++ a/file 
@@ -1 +1 @@ 
-new line 
+old line 

Kết quả đó mô tả chính xác những gì bạn tìm kiếm: "không ghi đè thay đổi, chỉ cho tôi biết điều gì sẽ xảy ra".

Theo mặc định, lệnh đó sẽ phân biệt toàn bộ thư mục làm việc của bạn với chỉ mục. Nó sẽ cho bạn thấy sự khác biệt trong mọi tập tin đã sửa đổi. Giả sử bạn chỉ muốn xem hiệu ứng trên một tệp. Thật dễ dàng. Chỉ cần sử dụng cùng một danh pháp hai dấu gạch ngang bạn đã sử dụng:

git diff -- <file> 

Bạn sẽ tìm thấy git diff đến là một trong những, lệnh mở rộng hữu ích nhất trong git, và bạn có thể sử dụng nó để làm tất cả các loại hữu ích nhiều thứ. Bạn có thể sử dụng nó để so sánh hai cam kết, hai nhánh hoặc hai tệp. "Hoạt động git điên yêu thích" gần đây nhất của tôi là đường ống git diff đến git apply. Các cựu sản xuất các bản vá dễ hiểu. Sau này áp dụng chúng. Khả năng viết lại lịch sử của bạn khi chúng được kết hợp là vô hạn - tất nhiên là tại địa phương, không bao giờ viết lại lịch sử được chia sẻ. Hãy xem xét một ví dụ khác, tại thời điểm này, nhưng giải trí nghiêm túc (nếu bạn đang gặp phải loại điều này). Từ kho thử nghiệm của chúng tôi, ở trên:

git add . 
git commit -m "Second commit" 
echo "even newer line">file 
git add . 
git commit -m "Third commit" 

Bạn biết không? Tôi không thích lần thứ hai đó. Triển khai của nó là lỗi. Nó đang phá vỡ các bài kiểm tra. Tôi không muốn chia sẻ nó. Tuy nhiên, tôi muốn giữ thông báo cam kết "Thứ hai cam kết" vì điều đó thực sự khó nhập. Tôi có thể rebase nó ra với git rebase -i HEAD~2, nhưng điều đó liên quan đến việc mở trình soạn thảo, xóa một cam kết, chỉnh sửa khác và (ugh) sao chép/dán. Một dev để làm gì? Làm thế nào về điều này:

git checkout ":/Initial" ;# get back to the first commit 
git diff HEAD ":/Third" | git apply ;# apply the diff between the first and third commit 
git add . ;# add the result 
git commit -C ":/Second" ;# with second commit's message 
git checkout -B master HEAD ;# and replace old 'master' 

Kết quả giống như với git rebase. Tôi chỉ quản lý để tránh các phiên tương tác và tôi không phải sử dụng trình chỉnh sửa. Nó có quá mức không? Có lẽ, nhưng chắc chắn là vui. Hơn nữa, việc tạo các trường hợp sử dụng phức tạp hơn rất dễ dàng, đặc biệt khi bạn kết hợp git diff, git applygit add -p.

1

Bạn muốn có tùy chọn chạy khô cho bất kỳ lệnh nào, bất kể ý tưởng được cho là "bạn không cần chạy khô để thanh toán vì bạn có thể nhận danh sách các khác biệt theo cách khác".

Bạn không muốn tùy chọn chạy khô để có danh sách các sự khác biệt, bạn muốn chạy thử để xác minh "Điều gì sẽ xảy ra khi tôi nhấn enter?" trước khi bạn làm điều đó thật. Có một sự khác biệt. Bạn đang kiểm tra hành vi thực tế/chính xác của một chương trình khi có thể có một số sự mơ hồ nếu tất cả những gì bạn đã làm là đọc hướng dẫn sử dụng.

Tôi có một dự án lạ nơi repo được đặt ngay trong '/'. Vì vậy, có một thư mục '/.git' và '/.gitignore' và '/.gitmodules'. /.gitignore và /.Các tệp gitmodules được theo dõi trong repo và đó là vấn đề bởi vì ngay cả khi người dùng nhà phát triển có quyền chỉnh sửa tệp, họ vẫn không có quyền cho git xóa và tạo lại tệp, vì không và có thể 't, có quyền ghi trên'/'chính nó. Nếu git chỉnh sửa các tập tin tại chỗ sẽ không có vấn đề, nhưng git xóa và thay thế, bởi vì người dùng nhận được một lỗi mà git không thể bỏ liên kết các tập tin. Trong quá trình phát triển một sự thay đổi cấu hình repo của chúng tôi, và một số định hướng cho các nhà phát triển theo để loại bỏ vấn đề này trong thời gian tới, trên đường đi tôi muốn biết những gì lệnh này sẽ làm:

git checkout master -- /.git*

và khác biến thể có thể như

git checkout master -- '/.git*'

và những người khác, thay đổi vỏ globbing và/hoặc nhìn thấy như thế nào git chính nó có thể giải thích các giá trị filespec thức. Nếu tôi thoát khỏi một '*' từ vỏ, sẽ git mở rộng một '*', hoặc nó sẽ xử lý nó như là một chữ? Nếu nó mở rộng, nó có bao gồm thư mục '/.git/' không? Nếu nó mở rộng nó, có một số cú pháp regex tôi có thể sử dụng có nghĩa là 'bất kỳ-không-rỗng-ký tự' như một '.' trong regex hoặc '?' trong vỏ globbing? etc etc

Tôi không muốn biết tệp nào khác nhau, tôi muốn kiểm tra hành vi chính xác của git để tìm phiên bản tốt nhất/đơn giản nhất của một lệnh hoặc tập lệnh bất thường.

Đối với điều đó, bạn thực sự muốn có tùy chọn chạy khô. Tôi đã biết các tệp khác nhau. Trong trường hợp này, MANY tệp sẽ khác nhau và tôi không muốn bất kỳ tệp nào trong số đó. Tôi chỉ muốn /.gitignore và /.gitmodules và không có gì khác.

Trong trường hợp này, tôi biết tôi có thể làm điều đó bằng cách chỉ định rõ ràng cả hai trên dòng lệnh.

git checkout master -- /.gitignore /.gitmodules

Nhưng tôi muốn để xem nếu có một globbing cú pháp ngắn mà sẽ nhận được cả hai tự động, tuy nhiên lý tưởng, không bao gồm các thư mục /.git. Và lý tưởng, tôi muốn tìm ra hình thức đơn giản nhất mà tôi có thể làm được. Tôi biết tôi có thể sử dụng vỏ để làm một số mở rộng ưa thích và rất cụ thể, nhưng nếu một cái gì đó như '/ git *' hoạt động, tôi muốn sử dụng nó hơn '/ git {i, m} *'

nhiệm vụ nhỏ và có một số câu trả lời đơn giản. Xin đừng nói cho tôi biết cách giải quyết VẤN ĐỀ CHÍNH XÁC NÀY mà không cần "git checkout --dry-run", hay nói cho tôi biết làm thế nào ngu ngốc để làm repo trong /, tôi cũng biết điều đó. Tôi đã biết một vài cách để hoàn thành công việc ngay lập tức của mình. Đó không phải là vấn đề. Nó có thể dễ dàng liên quan đến nhiều tập tin hơn hoặc một mẫu hình cầu phức tạp hơn vì nó sẽ không thuận tiện để chỉ liệt kê các tệp một cách rõ ràng, hoặc, nó có thể là một loại vấn đề hoàn toàn khác.

Điểm chung, nói chung, áp dụng cho bất kỳ lệnh nào ở bất kỳ đâu, kể cả git checkout, luôn có cách sử dụng cho tùy chọn chạy khô để kiểm tra hành vi của chính chương trình. Đọc hướng dẫn sử dụng hoặc --help không trả lời câu hỏi được trả lời bằng cách chạy khô.

Các vấn đề liên quan