2012-05-04 30 views
5

Tôi đang làm việc trên một dự án mà mọi người có thể gửi câu chuyện và nhờ những người khác đóng góp. Thay vì chỉ chỉnh sửa mục nhập trong cơ sở dữ liệu, tôi muốn lưu trữ những thay đổi mà mọi người thực hiện thay vì toàn bộ các thay đổi mới. Sau đó, tôi có thể tự động áp dụng các diff nếu mọi người muốn hoàn nguyên về phiên bản trước đó. Tôi cũng có thể dễ dàng giới thiệu người dùng là Người chỉnh sửa chỉ với văn bản được sửa đổi để họ có thể chuyển ngay đến các thay đổi.Làm cách nào để tôi có thể phân biệt và vá/hợp nhất các chuỗi thay vì tệp?

Tôi biết cách lấy các tệp khác và vá các tệp khác với chúng. Nhưng tôi đang tạo một ứng dụng web với Python và Django, và tôi sẽ lưu trữ tất cả những khác biệt này trong cơ sở dữ liệu MySQL. Với hiệu suất đó không phải là vấn đề lớn đối với ứng dụng này, tôi đã chuẩn bị để lấy dữ liệu từ DB, tạo tệp và chạy git diffpatch trên các tệp đó.

Có cách nào tốt hơn là tạo tệp mới và xóa chúng mỗi khi tôi muốn tạo phiên bản mới hoặc áp dụng một phiên bản mới? Có cách nào để chạy diffs trên văn bản thẳng thay vì các tập tin? Ví dụ. thiết lập các biến trong bash là nội dung của (những gì sẽ là) một tập tin (nhưng thực sự là dữ liệu từ DB), và chạy git diff trên chúng? Tôi muốn kiểm soát những hành động này từ một tệp Python sau khi người dùng gửi biểu mẫu.

Tôi thực sự đang tìm kiếm một cách tốt để bắt đầu về vấn đề này, vì vậy mọi trợ giúp sẽ được đánh giá cao.

Cảm ơn thời gian của bạn,

ParagonRG

+4

Bạn chắc chắn có thể áp dụng các nguyên tắc lưu trữ diffs thay vì toàn bộ văn bản trong cơ sở dữ liệu, nhưng đó là một chút kỳ lạ mà bạn muốn sử dụng một VCS cho mục đích này. .. (bạn đã xem http://docs.python.org/library/difflib.html) chưa? – geoffspear

+0

Cảm ơn, hãy nhìn vào điều này ngay bây giờ! – Paragon

+0

Thật không may difflib đã không cho phép xây dựng lại văn bản từ diffs trừ khi sử dụng diffs lưu trữ toàn bộ văn bản và thay đổi của nó. Do đó tôi đã xây dựng một mô-đun để làm điều này; xin vui lòng xem câu trả lời của tôi dưới đây. – Paragon

Trả lời

4

Tôi đã thực hiện khá nhiều tìm kiếm giải pháp cho việc này. Python's difflib là khá hợp pháp, nhưng tiếc là nó có xu hướng yêu cầu các chuỗi khác chứa toàn bộ chuỗi gốc với các bản ghi về những gì đã được thay đổi. Điều này khác với, ví dụ, một git diff, nơi bạn chỉ nhìn thấy những gì đã được thay đổi và một số bối cảnh phụ. difflib cũng cung cấp một hàm gọi là unified_diff mà thực sự cung cấp một diff ngắn hơn, nhưng nó không cung cấp một hàm để xây dựng lại một chuỗi từ một chuỗi và một diff. Ví dụ. nếu tôi tạo ra một khác biệt của text1 và text2, được gọi là diff1, thì tôi không thể tạo text2 ra khỏi text1 và diff1.

Do đó, tôi đã tạo một mô-đun Python đơn giản cho phép các chuỗi được xây dựng lại, cả chuyển tiếp và ngược, từ một chuỗi đơn và các khác biệt liên quan. Nó được gọi là merge_in_memory, và có thể được tìm thấy tại https://github.com/danielmoniz/merge_in_memory. Chỉ cần kéo kho lưu trữ và chạy setup.py.

Một ví dụ đơn giản của việc sử dụng của nó:

import merge_in_memory as mim_module 

str1 = """line 1 
line 2""" 
str2 = """line 1 
line 2 changed""" 

merger = mim_module.Merger() 
print merger.diff_make(str1, str2) 

Sản lượng này sẽ:

--- 
+++ 
@@ -1,2 +1,2 @@ 
line 1 
-line 2 
+line 2 changed 

diffs chỉ đơn giản là chuỗi (máy phát điện chứ không phải tan, khi chúng được khi sử dụng difflib) .Bạn có thể tạo ra một số lượng khác biệt và áp dụng chúng cùng một lúc (ví dụ:tua nhanh qua lịch sử hoặc theo dõi lại) với chức năng diff_apply_bulk().

Để đảo ngược lịch sử, chỉ cần đảm bảo rằng thuộc tính reverse được đặt thành True khi gọi diff_bulk() hoặc diff_apply_bulk. Ví dụ:

merge = self.inline_merge.diff_apply_bulk(text3, [diff1, diff2], reverse=True) 

Nếu bạn bắt đầu với text1 và văn bản được tạo 2 và text3 với diff1 và diff2, thì văn bản 1 được xây dựng lại với dòng mã bên trên. Lưu ý rằng danh sách các khác biệt vẫn đang trong thứ tự tăng dần. Một 'hợp nhất', tức là. áp dụng một diff cho một chuỗi, chính nó là một chuỗi.

Tất cả điều này cho phép tôi lưu trữ các khác biệt trong cơ sở dữ liệu dưới dạng VARCHAR đơn giản (hoặc bạn có). Tôi có thể kéo chúng ra theo thứ tự và áp dụng chúng theo một trong hai hướng để tạo ra các văn bản tôi muốn, miễn là tôi có một điểm khởi đầu.

Vui lòng để lại bất kỳ nhận xét nào về điều này vì đây là mô-đun Python đầu tiên của tôi.

Cảm ơn,

ParagonRG

1

Có một cái nhìn tại libgit. Đó là giao diện C (và mọi ngôn ngữ khác) cho phép bạn thao tác kho lưu trữ git theo nhiều cách khác nhau.

Có vẻ như mức độ khá thấp để làm cho nó thực sự cam kết, khác biệt và vân vân có thể tẻ nhạt, nhưng ít nhất nó cũng có chức năng add a blob to the repo without it needing to be on disk.

Cách thay thế của khóa học là tạo kho lưu trữ tệp thông thường và bản sao làm việc và công cụ trả lại qua lại giữa cơ sở dữ liệu và hệ thống tệp bằng cách sử dụng các cuộc gọi os.system.

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