2011-01-06 27 views
123

Tôi đang làm điều gì đó rất đơn giản sai. Tôi đang cố gắng chuẩn bị một tệp vá bình thường, vì vậy tôi có thể nộp đơn xin lại một số thay đổi:Tôi có thể nhận được đầu ra tương thích với bản vá từ git-diff không?

$ git diff > before 
$ git diff something_here > save.patch 
$ git checkout . 
$ patch < save.patch 
$ git diff > after 
$ diff before after 
$ 

Với something_heretrống nó gần như làm việc, nhưng tên tập tin là không đúng. Tôi nghĩ tôi chỉ thiếu một vài lựa chọn.

Trong cuộc sống thực, tôi sẽ thực hiện hợp nhất sau khi thanh toán, vì vậy bản vá có thể bị lỗi ở đó, nhưng bạn sẽ thấy những gì tôi nhận được.

Chỉnh sửa Lỗi của tôi ở đây khi đặt câu hỏi sai. Câu hỏi thực tế là, tôi muốn lưu các thay đổi của mình, thực hiện hợp nhất, sau đó áp dụng lại các thay đổi, nếu có thể? Tôi đã hỏi sai cách vì tôi đã sử dụng để sử dụng bản vá để giải quyết các loại sự cố này và git diff giống như đó là điều tôi muốn tôi làm.

Charles Bailey's nhận xét có câu trả lời đúng. Đối với tôi, git-apply là điều đúng đắn để làm (git-stash trông nặng hơn cân nặng mà tôi cần và rebasing và bundle chắc chắn là ngoài cấp độ kỹ năng hiện tại của tôi). Tôi sẽ chấp nhận câu trả lời mà Charles đưa ra (vì bạn không thể chấp nhận nhận xét). Cảm ơn tất cả những lời đề nghị.

Chỉnh sửa, 6 năm sau Như bất kỳ ai quen thuộc với chủ đề đều biết, tôi đã ước tính quá mức độ khó của git stash. Khá nhiều mỗi ngày hoặc lâu hơn, tôi sẽ sử dụng các trình tự sau:

$ git stash 
$ git merge 
$ git stash pop 
+7

Có lý do nào bạn đặc biệt muốn sử dụng 'vá' thay vì' git apply' không? –

+2

Và thậm chí sau đó, bạn có thực sự cần bản vá thay vì một cái gì đó như 'git stash' hoặc các công cụ git khác không? –

+2

Sau khi chỉnh sửa, tôi nghĩ rằng 'git stash' là giải pháp dễ nhất cho những gì bạn đang cố gắng làm, nhưng có rất nhiều cách tiếp cận hoạt động. –

Trả lời

104

Nếu bạn muốn sử dụng bản vá bạn cần phải loại bỏ các a/b/ tiền tố mà git sử dụng theo mặc định. Bạn có thể làm điều này với --no-prefix tùy chọn (bạn cũng có thể làm điều này với tùy chọn bản vá của -p):

git diff --no-prefix [<other git-diff arguments>] 

Thông thường, mặc dù nó là dễ dàng hơn để sử dụng thẳng git diff và sau đó sử dụng đầu ra để nuôi để git apply.

Hầu hết thời gian tôi cố gắng tránh sử dụng các bản vá lỗi văn bản. Thông thường, một hoặc nhiều cam kết tạm thời kết hợp với rebase, git stash và các gói được quản lý dễ dàng hơn.

Đối với trường hợp sử dụng của bạn, tôi nghĩ rằng stash là thích hợp nhất.

# save uncommitted changes 
git stash 

# do a merge or some other operation 
git merge some-branch 

# re-apply changes, removing stash if successful 
# (you may be asked to resolve conflicts). 
git stash pop 
+3

'git diff --no-prefix master> diff.patch' và sau đó' git checkout master' 'patch -p0 Natim

+0

@Natim Vì sự an toàn tối ưu, tôi khuyên bạn nên sử dụng' patch --dry-run

+1

@ ᴠɪɴᴄᴇɴᴛ lợi ích của việc đó là gì? Vì chúng tôi đang sử dụng git, chúng tôi không thể mất bất cứ điều gì phải không? – Natim

15

Phân biệt git có phân đoạn đường phụ được thêm vào đường dẫn tệp.Bạn có thể tước mục này trong đường dẫn bằng cách xác định -p1 với vá, như vậy:

patch -p1 < save.patch 
175

Chỉ cần sử dụng -p1: bạn sẽ cần phải sử dụng -p0 trong trường hợp --no-prefix dù sao, vì vậy bạn chỉ có thể bỏ qua --no-prefix và sử dụng -p1:

$ git diff > save.patch 
$ patch -p1 < save.patch 

$ git diff --no-prefix > save.patch 
$ patch -p0 < save.patch 
+0

Nếu bạn tự hỏi tại sao, [tài liệu người đàn ông] (http://www.gnu.org/software/diffutils/manual/diffutils.html#patch-Directories) tổng hợp nó một cách độc đáo - [nguồn] (http://unix.stackexchange.com/a/26502/17836). – tutuDajuju

7

Một thủ thuật hữu ích để tránh tạo ra các file bản vá tạm thời:

git diff | patch -p1 -d [dst-dir]

+0

Chính xác những gì tôi muốn. Cũng hoạt động hoàn hảo với stashes! 'git stash show -p stash @ {3} | patch -p1 -d [dst-dir] ' – dtmland

7
  1. tôi lưu diff của thư mục hiện hành (bao gồm các file bị giam) đối với các HEAD hiện hành.
  2. Sau đó, bạn có thể vận chuyển tệp save.patch đến bất kỳ đâu (kể cả tệp nhị phân).
  3. Trên máy tính mục tiêu của bạn, áp dụng các bản vá sử dụng git apply <file>

Lưu ý: nó diff là hiện dàn dựng file quá.

$ git diff --binary --staged HEAD > save.patch 
$ git reset --hard 
$ <transport it> 
$ git apply save.patch 
+0

Hahaha. Thật buồn cười. Tôi hỏi câu hỏi này gần bốn năm trước và cách tôi đã làm điều này đã phát triển nhưng nếu bạn đã hỏi tôi hôm qua làm thế nào để làm điều đó, tôi đã đưa ra câu trả lời của bạn và nói tôi đã nhận nó từ câu trả lời cho câu hỏi này. (Trên thực tế tôi có thể sử dụng một 'git diff> save.patch' và' git checkout .' thay vì đặt lại, nhưng yeah ... – Malvolio

+0

Oh đã không nhận thấy 4 tuổi của nó: P. Btw, reset là chỉ để chứng minh nó hoạt động ..Tôi cũng không thấy bất kỳ ai sử dụng 'git apply' hoặc làm cho diff có liên quan đến trạng thái của bạn và con trỏ tới commit cuối cùng có sẵn. Làm chỉ 'git diff' đã không làm bất cứ điều gì ở tất cả –

+0

Vâng, bây giờ tôi tự hỏi làm thế nào tôi phát hiện ra về' git apply'. Điều với 'git diff' là (tôi nghĩ) từ việc sử dụng' git reset' - các mối quan hệ giữa repo, chỉ mục và vùng làm việc là vấn đề. – Malvolio

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