7

私は、人々がストーリーを投稿し、他の人々に貢献してもらうプロジェクトに取り組んでいます。データベース内のエントリを単純に編集するのではなく、新しい一連の変更全体ではなく、人々が行った変更を保存したいと考えています。その後、人々が以前のバージョンに戻したい場合は、差分を動的に適用できます。また、編集者であるユーザーに、変更されたテキストのみを簡単に提示して、変更にすぐにジャンプできるようにすることもできます。

差分ファイルを取得して他のファイルにパッチを適用する方法を認識しています。しかし、私は Python と Django を使用して Web アプリを作成しており、これらすべての差分を MySQL データベースに保存します。このアプリのパフォーマンスは大きな問題ではないので、DB からデータを取得し、ファイルを作成し、それらのファイルを実行する準備ができgit diffpatchいます。

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

私は本当にこの問題を始めるための良い方法を探しているだけなので、どんな助けでも大歓迎です。

御時間ありがとうございます、

パラゴンRG

4

2 に答える 2

6

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

そのため、単一の文字列とそれに関連する差分から文字列を順方向と逆方向の両方で再構築できるようにする単純な 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)

これは出力されます:

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

diff は単純な文字列です (difflib を使用するときのように tan ジェネレーターではなく)。関数を使用して、多数の diff を作成し、それらを一度に適用できます (つまり、履歴を早送りしたり、トラックバックしたりします) diff_apply_bulk()

履歴を元に戻すには、またはreverseを呼び出すときに属性が True に設定されていることを確認します。例えば:diff_bulk()diff_apply_bulk

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

text1 から開始し、diff1 と diff2 を使用して text2 と text3 を生成した場合、text1 は上記のコード行で再構築されます。差分のリストはまだ昇順になっていることに注意してください。「マージ」、つまり。文字列に差分を適用すると、それ自体が文字列になります。

これにより、差分を単純な VARCHAR (または what-have-you) としてデータベースに保存できます。開始点がある限り、それらを順番に引き出して、どちらの方向にも適用して、必要なテキストを生成できます。

これは私の最初の Python モジュールであるため、お気軽にコメントを残してください。

ありがとう、

パラゴンRG

于 2012-05-05T02:39:17.483 に答える
1

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

かなり低レベルに見えるので、実際にコミットしたり、差分を取ったりするのは面倒かもしれませんが、少なくとも、ディスク上になくても blob をレポに追加する機能があります。

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

于 2012-05-04T15:41:06.363 に答える