2012-05-04 10 views
5

私は、人々が物語を提出し、他の人々が貢献できるようなプロジェクトに取り組んでいます。単にデータベースのエントリを編集するのではなく、新しい変更のセット全体ではなく、人が行う変更を保存したいと思います。その後、以前のバージョンに戻したい場合は、差分を動的に適用できます。編集者であるユーザーには変更されたテキストのみを簡単に提示することができます。その結果、変更が正しく反映されます。ファイルの代わりに文字列を変更してパッチ/マージする方法はありますか?

私はdiffファイルを取得し、他のファイルにパッチを適用する方法を知っています。しかし、私はPythonとDjangoでWebアプリケーションを作っています。これらの差分をすべてMySQLデータベースに格納します。パフォーマンスがこのアプリの主要な問題ではないことを考えると、私はDBからデータを取り出し、ファイルを作成し、それらのファイルにgit diffpatchを実行する準備ができています。

新しいバージョンを作成したり、新しい差分を適用したりするたびに、新しいファイルを作成して削除するよりも良い方法はありますか?ファイルの代わりにストレートテキストで差分を実行する方法はありますか?例えば。 bashの変数をファイルの内容(実際にはDBのデータ)に設定し、git diffを実行していますか?ユーザーがフォームを送信した後、これらのアクションをPythonファイルから制御したいと思います。

私は実際にこの問題を始めるには良い方法を探しています。だから、どんな助けでも大歓迎です。お時間を

おかげで、

ParagonRG

+4

は、あなたは確かに代わり、データベース内のフルテキストの差分を保存するの原則を適用することができますが、それはあなたが目的でVCSを使用するだろうと少し奇妙です。 ..(あなたはhttp://docs.python.org/library/difflib.htmlを見ましたか?) – geoffspear

+0

ありがとう、これを今見て! – Paragon

+0

残念ながら、difflibは、テキスト全体とその変更を保存するdiffを使用しない限り、diffからテキストを再構築することはできませんでした。したがって私はこれを行うためのモジュールを作りました。下の私の答えを見てください。 – Paragon

答えて

4

私はかなりの解決策を探しました。 Python's difflibはかなり合法ですが、残念ながらdiff文字列に元の文字列全体が含まれ、変更されたもののレコードが含まれている必要があります。これは、例えばgit diffとは異なります。ここでは、変更された内容と追加のコンテキストのみが表示されます。 difflibはunified_diffという関数も提供していますが、これは実際には短いdiffを提供しますが、文字列とdiffから文字列を再構築する関数は提供しません。例えば。 diff1というtext1とtext2のdiffを作成した場合、text1とdiff1のうちtext2を生成できませんでした。

私は、単一の文字列とそれに関連するdiffから文字列を前後に再構築することができる単純なPythonモジュールを作成しました。これはmerge_in_memoryと呼ばれ、https://github.com/danielmoniz/merge_in_memoryにあります。単にリポジトリを取り出し、setup.pyを実行してください。

その使用の簡単な例:

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) 

この意志出力:(difflibを使用する場合、そのままではなく、黄褐色ジェネレータ)

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

差分は、単に文字列である。あなたが作成することができ差分の数を一度に適用します(つまり、早送り、履歴またはトラックバック)をdiff_apply_bulk()機能で実行します。

履歴に戻すには、diff_bulk()またはdiff_apply_bulkのいずれかを呼び出すときにreverse属性がTrueに設定されていることを確認するだけです。たとえば、次のように

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

あなたはテキスト1で始まり、DIFF1とDIFF2とテキスト2とテキスト3を生成した場合は、テキスト1は、上記のコード行で再構築されます。差異のリストは依然として昇順であることに注意してください。 '合併'、すなわち。文字列にdiffを適用すると、それ自体が文字列です。

これはすべて、データベース内のdiffを単純なVARCHAR(またはwhat-have-you)として格納することを可能にします。私は出発点がある限り、それらを順番に引き出して、どちらかの方向に適用して、私が望むテキストを生成することができます。

私の最初のPythonモジュールであるので、これに関するコメントを残しておきたいと思います。

おかげで、

ParagonRG

1

libgitを見てください。これは、さまざまな方法でgitリポジトリを操作できるC(および他のすべての言語)インターフェイスです。

かなり低レベルなので、実際にコミットすると、diffなどが面倒かもしれませんが、少なくともadd a blob to the repo without it needing to be on diskの機能を持っています。

もちろん、通常のファイルベースのリポジトリと作業コピーを作成し、os.systemコールを使用してデータベースとファイルシステムの間を行き来することもできます。

関連する問題