Git format-patch để tương thích với svn?


96

Có cách nào để lấy một bản vá được tạo bằng git format-patch để tương thích với svn để tôi có thể gửi nó đến repo svn không?

Tôi đang thực hiện một repo svn trên github và muốn gửi các thay đổi của mình trở lại repo chính. Tôi cần tạo một bản vá để thực hiện việc này, tuy nhiên bản vá không thể được áp dụng vì các định dạng git vá khác so với svn. Có bí mật nào đó mà tôi chưa khám phá ra không?

CẬP NHẬT: Mặc dù hiện tại không có tập lệnh hoặc cách git gốc nào để thực hiện việc này, nhưng tôi đã tìm được một bài đăng từ đầu năm nay về cách thực hiện việc này theo cách thủ công. Tôi đã làm theo hướng dẫn và đã thành công khi đưa các bản vá git của tôi hoạt động với svn.

Nếu ai đó có thể viết kịch bản để hoàn thành điều này và đóng góp cho dự án git, tôi sẽ được mọi người đánh giá cao.

http://kerneltrap.org/mailarchive/git/2008/1/15/570308/thread#mid-570308


Tôi không thể làm cho nó hoạt động ... bạn có thể đăng tất cả các bước cần thiết không? cảm ơn!
Mauricio Scheffer

1
Chào Anthony. Bạn có cân nhắc thay đổi câu trả lời được chấp nhận thành của Nicholas không?
Simon East

Tôi thứ hai gợi ý của Simon, có câu trả lời của Nicholas Smith là câu được chấp nhận sẽ có lợi cho mọi người vì nó thực tế hơn nhiều.
Albireo

Câu trả lời:


90

Tôi luôn phải Google điều này nhưng cách tôi thấy nó hoạt động hoàn hảo (đối với tôi) là:

  • Tạo bản vá bằng git diff --no-prefix master..branch > somefile.diff, phần chính và phần nhánh là tùy chọn, tùy thuộc vào cách bạn muốn lấy khác biệt của mình.
  • Gửi nó bất cứ nơi nào và áp dụng với patch -p0 < somefile.diff.

Nó dường như luôn hoạt động tốt đối với tôi và dường như là phương pháp đơn giản nhất mà tôi đã gặp.


1
Đây là cách chuẩn để tạo bản vá tương thích SVN với Git. Nó nên được đánh dấu là câu trả lời.
mloskot

--no-pagerkhông còn là một lựa chọn cho git diff.
naught101

Ban đầu nó đã được đăng mà không có --no-pager, tôi không chắc tại sao nó lại được thêm vào trong bản chỉnh sửa. --no-pagerDù sao thì nó vẫn luôn hoạt động tốt đối với tôi .
Nicholas Smith

2
Đối với một cam kết cụ thể: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchđã làm việc cho tôi (ở đâu 056a1ba51407d939289b80là sha-1 của cam kết trước đó và cam kết cụ thể trong git).
Ed Randall

@ Lilás đây là vấn đề với SVN. Diffs / bản vá lỗi trong SVN đã bao giờ có thể xử lý các file loại bỏ
Toofy


17

Đây là tập lệnh trợ giúp để tạo sự khác biệt so với tập thay đổi svn mới nhất và cam kết đã cho: http://www.mail-archive.com/dev@trafficserver.apache.org/msg00864.html

#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
TRACKING_BRANCH=`git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'`
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH) $* |
sed -e "s/^+++ .*/&    (working copy)/" -e "s/^--- .*/&    (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" \
-e "s/^index.*/===================================================================/"

1
Tôi thấy rằng giá trị REV không chính xác nếu bạn không làm việc với bản sửa đổi svn mới nhất. Tôi sửa chữa nó để sử dụng git svn infothay vì như thế này: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin

1
Điều này thật tuyệt! Cảm ơn bạn rất nhiều. Tôi phải làm một sự thay đổi cho nó để làm việc cho nhập khẩu các bản vá lỗi của tôi vào nồi nấu Fisheye, và đó là để thay thế cho khoảng trống trước khi "(sửa đổi" với một tab để thay thế.
Zugwalt

10

SVN có thể không hiểu đầu ra của git diff -p, nhưng bạn có thể sử dụng vũ phu:

  1. Tạo hai bản sao của repo của bạn
  2. Trong một bản sao, hãy xem những thứ mới nhất của bạn
  3. Trong lần kiểm tra bản sao khác, bất cứ thứ gì tương đương với svn ngược dòng. Nếu bạn đã lên kế hoạch trước, bạn có một bản sao của svn ngược dòng trên nhánh của chính nó, hoặc bạn đã gắn thẻ phiên bản svn cuối cùng. Nếu bạn chưa lên kế hoạch trước, hãy sử dụng ngày tháng hoặc gitk để tìm hàm băm git SHA1 gần đúng nhất với trạng thái svn.
  4. Bây giờ tính toán một bản vá thực sự bằng cách chạy diff -rqua hai bản sao.

12
Hoặc chỉ cần làm theo lời khuyên của @ Nicholas-smith và chạy git diff --no-prefix > somefile.difftrong git repo của bạn và gửi nó cho bất kỳ người dùng svn nào để họ áp dụng bản vá patch -p0 < somefile.difftrong thư mục gốc của dự án.
DavidG

10

Subversion <1.6 không hỗ trợ bản vá. Có vẻ như Subversion 1.7 sẽ cho phép áp dụng các bản vá và các phần mở rộng git / hg cho sự khác biệt thống nhất nằm trong danh sách CẦN LÀM của chúng tôi.


4

Đó thực sự là một yêu cầu tính năng vào đầu năm 2008

Linus Torvalds cho biết vào thời điểm đó:

Vì vậy, tôi sẽ tranh luận rằng bạn cần một điều gì đó mạnh mẽ hơn để nói "không làm khác git" và điều đó cũng sẽ không cho phép phát hiện đổi tên ở mức tối thiểu.
Thành thật mà nói, bất kỳ chương trình nào ngu ngốc đến mức không chấp nhận các bản vá git hiện tại (tức là TortoiseSVN), thì chúng tôi chết tiệt không nên chỉ vô hiệu hóa phần nhỏ nhất của nó. Chúng tôi nên đảm bảo rằng chúng tôi không bật bất kỳ phần mở rộng nào khá quan trọng:
ngay cả khi ToirtoiseSVN sẽ bỏ qua chúng, nếu bỏ qua chúng có nghĩa là nó hiểu sai sự khác biệt, nó hoàn toàn không nên được phép.

Đó có thể là lý do tại sao

 git-format-patch: add --no-binary to omit binary changes in the patch.

đã được giới thiệu trong Git1.5.6 vào tháng 5 / tháng 7 năm 2008 (tôi chưa thử nghiệm nó)


0

Đảm bảo các thay đổi của bạn được cam kết và phục hồi trên nhánh git cục bộ của bạn, từ git bash run:

git show --pretty >> myChangesFile.patch


0

Câu trả lời được chấp nhận do Nicholas cung cấp hoạt động tốt, ngoại trừ khi a) tệp nhị phân tồn tại trong khác biệt hoặc b) bạn đang làm việc trong windows Git và có thư mục với khoảng trắng. Để giải quyết vấn đề đó, tôi phải thêm lệnh git diff lồng nhau để bỏ qua các mã nhị phân và lệnh sed để thoát khỏi khoảng trắng. Viết hơi rườm rà, vì vậy tôi đã tạo một bí danh:

[alias]
svnpatch = "!f() { git diff --name-only --no-prefix master...$1 | grep -Ev \"\\.sdf|\\.Doc|\\.dll|\\.zip|\\.exe\" | sed 's_\\s_\\\\\\\\ _g'  | xargs git diff --no-prefix master...$1 > $1.patch; echo "Created $1.patch"; }; f"

Nếu sau đó bạn gõ:

git svnpatch Feature123

... một tệp bản vá Feature123.patch sẽ được tạo với sự khác biệt giữa cơ sở hợp nhất của nhánh cái chính và nhánh Feature123.

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.