2012-05-04 17 views
5

Sto lavorando a un progetto in cui le persone sono in grado di inviare storie e hanno altre persone che contribuiscono. Piuttosto che semplicemente modificare una voce nel database, vorrei memorizzare le modifiche apportate dalle persone piuttosto che l'intero nuovo set di modifiche. Quindi posso applicare in modo dinamico diffs se le persone vogliono tornare a una versione precedente. Posso anche presentare facilmente agli utenti che sono gli editor con solo il testo modificato in modo che possano saltare direttamente alle modifiche.Come posso diff e patch/unire stringhe invece di file?

Sono a conoscenza di come trasferire file diff e applicare patch ad altri file. Ma sto realizzando un'app web con Python e Django, e conserverò tutte queste differenze in un database MySQL. Dato che le prestazioni non sono un problema importante per questa app, sono pronto a estrarre i dati dal DB, creare file ed eseguire git diff e patch su quei file.

C'è un modo migliore di creare nuovi file e cancellarli ogni volta che voglio creare una nuova versione o applicare una nuova diff? C'è un modo per eseguire diff su testo semplice invece di file? Per esempio. impostando le variabili in bash come contenuto di (quale sarebbe) un file (ma in realtà sono dati dal DB) ed eseguendo git diff su di esse? Mi piacerebbe controllare queste azioni da un file Python dopo che l'utente ha inviato un modulo.

Sto solo cercando un buon modo per iniziare questo problema, quindi qualsiasi aiuto sarebbe molto apprezzato.

Grazie per il vostro tempo,

ParagonRG

+4

si può certamente applicare i principi della memorizzazione diff invece che il testo completo nel database, ma è un po 'strano che ci si vuole usare un VCS per lo scopo. .. (hai guardato http://docs.python.org/library/difflib.html)? – geoffspear

+0

Grazie, esaminando questo ora! – Paragon

+0

Sfortunatamente difflib non ha permesso di ricostruire il testo da diff a meno che non si utilizzi diff che memorizzino l'interezza del testo e le sue modifiche. Ho quindi creato un modulo per farlo; per favore vedi la mia risposta qui sotto. – Paragon

risposta

4

Ho fatto un bel po 'di ricerca di una soluzione per questo. Python's difflib è abbastanza legittimo, ma sfortunatamente tende a richiedere che le stringhe di confronto contengano l'intera stringa originale con i record di ciò che è stato cambiato. Questo differisce da, ad esempio, un diff di git, dove si vede solo ciò che è stato cambiato e un contesto extra. difflib fornisce anche una funzione chiamata unified_diff che effettivamente fornisce un diff più breve, ma non fornisce una funzione per ricostruire una stringa da una stringa e una diff. Per esempio. se ho fatto una diff di text1 e text2, chiamata diff1, non potrei generare text2 di text1 e diff1.

ho quindi fatto un semplice modulo Python che consente di stringhe da ricostruire, sia in avanti che indietro, da una singola stringa e suoi diff correlate. Si chiama merge_in_memory e può essere trovato a https://github.com/danielmoniz/merge_in_memory. Basta estrarre il repository ed eseguire setup.py.

Un semplice esempio del suo utilizzo:

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) 

Questo stamperà:

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

diff sono semplicemente stringhe (generatori piuttosto tan, come sono quando utilizzano difflib) .You può creare una numero di diff e applicarli contemporaneamente (es.avanzamento rapido di una cronologia o traccia indietro) con la funzione diff_apply_bulk().

Per tornare alla cronologia, è sufficiente assicurarsi che l'attributo reverse sia impostato su True quando si chiama diff_bulk() o diff_apply_bulk. Per esempio:

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

Se si inizia con text1 e testo2 generati e text3 con DIFF1 e diff2, quindi text1 viene ricostruito con la riga di codice precedente. Si noti che l'elenco delle diff è ancora in ordine crescente. Un 'unione', es. applicando un diff a una stringa, è esso stesso una stringa.

Tutto questo mi permette di memorizzare diff nel database VARCHAR come semplici (o quello che-hanno-te). Posso estrarli in ordine e applicarli in entrambe le direzioni per generare il testo che voglio, purché abbia un punto di partenza.

Non esitate a lasciare un commento su questo, come è il mio primo modulo Python.

Grazie,

ParagonRG

1

Date un'occhiata al libgit. È un'interfaccia C (e ogni altra lingua) che ti consente di manipolare un repository git in vari modi.

Sembra piuttosto di basso livello in modo che ottenerlo effettivamente, diff e così via potrebbe essere noioso, ma ha almeno una funzione per add a blob to the repo without it needing to be on disk.

L'alternativa, naturalmente, è creare un normale repository basato su file e copiare e far funzionare il bounce avanti e indietro tra il database e il file system utilizzando le chiamate os.system.

Problemi correlati