2009-07-10 24 views
123

Trong repo git của tôi đang theo dõi một repo svn Tôi đã thực hiện một số chỉnh sửa cho một tệp duy nhất.git chọn lọc hoàn nguyên thay đổi cục bộ từ một tệp

Bây giờ tôi muốn hoàn nguyên các thay đổi đó (như svn revert), nhưng chỉ một phần của tệp.

Tôi muốn có thể xem các khác biệt trên tệp, loại bỏ (hoàn nguyên) các thay đổi mà tôi không muốn và giữ lại các thay đổi mà tôi muốn.

lệnh

git add -i 

dường như có một tùy chọn để làm điều đó nhưng tôi không muốn đến giai đoạn này được nêu ra.

Trả lời

74

Bạn có thể thực hiện việc đó trực tiếp với git checkout -p. Xem Daniel Stutzbach's answer bên dưới.


câu trả lời cũ (trước khi checkout -p đã được giới thiệu):

Bạn có thể làm điều đó như thế này:

git add -i 

(chọn hunks bạn muốn giữ lại)

git commit -m "tmp" 

Bây giờ bạn có một cam kết chỉ với những thay đổi bạn wa nt để giữ, và phần còn lại là unstaged.

git reset --hard HEAD 

Tại thời điểm này, các thay đổi không được cam kết đã bị hủy, vì vậy bạn có một thư mục làm việc sạch sẽ, với những thay đổi bạn muốn giữ trên đầu.

git reset --mixed HEAD^ 

Thao tác này sẽ loại bỏ cam kết cuối cùng ('tmp'), nhưng giữ các sửa đổi trong thư mục làm việc của bạn, không bị chặn.

CHỈNH SỬA: thay thế --soft bằng --mixed để làm sạch khu vực dàn dựng.

+0

này sẽ cam kết những thay đổi mà tôi muốn giữ phải không? Tôi không muốn thực hiện những thay đổi đó. mm có lẽ tôi đang cam kết quá nghiêm túc. Có lẽ tôi nên thư giãn bây giờ vì nó là tất cả trong một repo địa phương. btw git reset --soft HEAD^làm gì? – Pradeep

+0

"git reset --soft HEAD ^" hoàn tác một cam kết theo nghĩa là nó giữ thư mục và chỉ mục hoạt động giống như nó và di chuyển nhánh nhánh hiện tại trở lại. –

+0

Cảm ơn Jakub. Paolo tại sao một soft reset lại đầu - 1 được yêu cầu ở đây? cam kết một phần và thiết lập lại khó khăn là đủ không phải là nó để giữ một số thay đổi và loại bỏ những người khác? – Pradeep

3

Bạn có thể chạy git diff vào file, lưu diff kết quả, chỉnh sửa nó để loại bỏ các thay đổi mà bạn làm muốn lưu, sau đó chạy nó thông qua patch -R để hoàn tác các diffs còn lại.

git diff file.txt >patch.tmp 
# edit patch.tmp to remove the hunks you want to keep 
patch -R <patch.tmp
+0

Tôi có 2 khối trong tệp bản vá và đã xóa một tệp. Không chắc chắn lý do gì nhưng bản vá -R tiếp tục bị từ chối với điều này. – Pradeep

+2

Bạn đề cập đến trong một nhận xét khác rằng 'git diff' hiển thị toàn bộ tệp đã bị thay đổi. Điều này thường xảy ra khi bạn đã lưu tệp bằng cách sử dụng các kết thúc dòng khác nhau từ những gì trước đây. Điều này cũng sẽ gây ra 'vá' để từ chối các tập tin vá lỗi. Điều đó nghe có vẻ như những gì có thể đã xảy ra? –

+0

bạn đã đúng. các kết thúc dòng đang nhận được bật lên bất cứ khi nào tôi sử dụng lệnh vá. Tôi đang ở trên cửa sổ và sử dụng kem/vim. Cần phải sắp xếp điều này ra đầu tiên tôi nghĩ. – Pradeep

2

Hình như bạn muốn

git revert --no-commit $REVSISON 

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

git diff --cached 

để xem những gì thay đổi sẽ được thực hiện trước khi cam (như hoàn nguyên chỉ là một cam kết theo một hướng về phía trước mà sao chép nghịch đảo của một thay đổi trong quá khứ)

Nếu bạn đã có một pur Kho lưu trữ Git, bạn có thể, tùy thuộc vào mục tiêu của bạn, sử dụng tính năng rebase tương tác (git rebase -i) để quay lại cam kết mà bạn không thích và chỉnh sửa commit trước để những thay đổi bạn không thích xảy ra, nhưng nói chung chỉ dành cho nếu bạn BIẾT bạn sẽ không bao giờ muốn xem lại.

+0

Tôi đã hoàn nguyên như bạn đã đề cập đến bản sửa đổi trước đó (có đúng không?) Và bây giờ git diff chỉ hiển thị toàn bộ tệp là đã thay đổi. Nó được cho là để hiển thị các chỉnh sửa mà tôi đã làm? – Pradeep

+0

của nó được cho là để hiển thị những thay đổi "sao lưu" –

1

Đọc lại câu hỏi, có vẻ như bạn muốn hoàn nguyên các thay đổi trong cây đang hoạt động và không thay đổi trước đây nhưng một số câu trả lời khác khiến cho âm thanh như đọc của tôi có thể sai. Bạn có thể làm rõ?

Nếu những thay đổi chỉ trong bản sao làm việc của bạn thì cách đơn giản nhất để làm điều này là giai đoạn thay đổi bạn muốn giữ lại với:

git add -i <file> 

Sau đó, vứt bỏ những thay đổi mà bạn không muốn giữ bằng cách xem phiên bản chỉ số:

git checkout -- <file> 

Sau đó unstage những thay đổi nếu bạn không muốn họ dàn dựng nào:

git reset -- <file> 

Công thức này chỉ chuyển đổi các thay đổi đã chọn thành tệp (hoặc các tệp mà bạn chỉ định) và không tạo bất kỳ cam kết tạm thời nào mà sau đó cần hoàn nguyên.

Nếu bạn muốn có chọn lọc chỉ áp dụng một số thay đổi được thực hiện trong cam kết trước đó thì bạn có thể thiết lập lại một tập tin vào một nhà nước đã cam kết trước đây đầu tiên:

git reset <commit_before_first_unwanted_change> -- <file> 

Sau đó, bạn có thể làm theo các công thức trước đây của git add -i <file> đến giai đoạn những thay đổi mà bạn muốn giữ lại, git checkout -- <file> để vứt bỏ những thay đổi không mong muốn và git reset -- <file> để 'thay đổi' các thay đổi.

279

Tôi tin rằng bạn có thể làm điều đó đơn giản nhất với:

git checkout -p <optional filename(s)> 

Từ manpage:

−p, −−patch 
     Interactively select hunks in the difference between the <tree−ish> 
     (or the index, if unspecified) and the working tree. The chosen 
     hunks are then applied in reverse to the working tree (and if a 
     <tree−ish> was specified, the index). 
 This means that you can use git checkout −p to selectively discard 
     edits from your current working tree. 
+35

Điều này thực sự phải là câu trả lời được chấp nhận, nó thực hiện chính xác những gì bạn muốn. – vdboor

+1

Ngoài ra, nếu bạn không muốn thực hiện điều này có chọn lọc, bạn có thể sử dụng "git checkout - ..." để hủy thay đổi. – db42

+0

Có thực sự, tại sao câu trả lời không thay đổi? – lkraav

0

Các tùy chọn dòng lệnh được mô tả trong các câu trả lời ở đây là tiện dụng khi tập tin là trên một máy chủ mà tôi đang truy cập thông qua một thiết bị đầu cuối ssh. Tuy nhiên, khi tệp trên máy cục bộ của tôi, tôi thích theo cách sau:

Mở tệp trong trình chỉnh sửa netbeans (đi kèm với hỗ trợ git). Netbeans đặt dấu đỏ/xanh/xanh ở số dòng để chỉ ra nơi công cụ đã bị xóa/thêm/sửa đổi (tương ứng).

Nhấp chuột phải vào bất kỳ dấu nào trong số này sẽ cung cấp cho bạn tùy chọn hoàn tác thay đổi đó. Ngoài ra, bạn có thể nhấp chuột phải vào các dấu màu đỏ và màu xanh để tìm phiên bản cũ trong cửa sổ bật lên.

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