2017-09-11 3 views
0

Ich möchte einen 500kb json-Text verfolgen, der seinen Inhalt minutiös ändert. Ich möchte git verwenden, damit ich git pull auf einem anderen Server verwenden kann, um die neueste Version dieser Datei herunterzuladen, ohne das Problem, dass sich die Datei während des Downloads ändern könnte und ich auch eine Version dieser Datei für die letzten Monate haben möchte/Jahre auf diese Weise gleichzeitig.truncate git repository keepinng reguläre Snapshots

Ich dachte an ein Git-Repository zu schaffen, wo ich jede Datei ändern begehen, aber ich merkte, nach einigen Tagen, dieses Repository die Größe vieler GB (auch mit git gc weil es so viel in der Datei ändert) wird

Ich könnte den Git regelmäßig auf eine bestimmte Tiefe kürzen, aber das ist nicht das, was ich brauche. Ich brauche die Information, wie die Datei aussah wie vor einer Woche, vor einem Monat, vor einem Jahr. obwohl ich nicht so viele Commits benötige, ist es in der Vergangenheit umso länger.

Ist das überhaupt möglich mit git und bash magic? Mir geht es gut mit löschen und neu erstellen das Repository und --amend in diesem Git

Oder würden Sie eine andere Lösung vorschlagen?

+0

Ist eine geeignete Gruppe von 'Cron'-Jobs, die jede Minute/Stunde/Tag/Monat eine gültige Lösung ausgelöst werden? Ich vermute, dass eine 'git'-Lösung viel zu hochentwickelt ist, insbesondere wenn man bedenkt, dass jedes Mal, wenn Sie versuchen, das Repository zu kürzen, jedes Hash darin neu berechnet werden muss. – Phylogenesis

+0

Haben Sie versucht, 'git gc' oder' git gc --aggressive' zu ​​laufen, um zu sehen, wie stark Ihr git repo geschrumpft werden kann? – Mort

+0

Ich möchte git verwenden, damit ich git pull auf einem anderen Server verwenden kann, um die neueste Version dieser Datei ohne das Problem herunterzuladen, dass sich die Datei während des Downloads ändern könnte und ich auch eine Versionierung dieser Datei für die letzte haben möchte Monate/Jahre auf diese Weise gleichzeitig – rubo77

Antwort

1

Es gibt mindestens eine Möglichkeit, dies zu tun; Ich werde unten einen Ansatz skizzieren. Zuerst ein paar Dinge zum Nachdenken:

Abhängig von der Art der Änderungen, die auftreten, möchten Sie vielleicht sehen, ob häufiges Packen der Datenbank helfen könnte; git ist ziemlich gut darin, verschwendeten Speicherplatz zu vermeiden (zumindest für Textdateien).

Natürlich mit dem Commit-Last beschreiben Sie - 1440 Commits pro Tag, geben oder nehmen? - Die Geschichte wird tendenziell wachsen. Dennoch, es sei denn, die Änderungen sind bei jedem Commit dramatisch, es scheint, als könnte es besser gemacht werden als "viele GB in ein paar Tagen"; und vielleicht würden Sie ein Niveau erreichen, auf dem eine Kompromiss-Archivierungsstrategie praktisch wäre.

Es lohnt sich auch immer darüber nachzudenken, ob "alle Daten, die ich behalten muss" größer sind als "alle Daten, auf die ich regelmäßig zugreifen muss"; Denn dann können Sie überlegen, ob einige der Daten in Archiv-Repos gespeichert werden sollen, möglicherweise auf Backup-Medien in irgendeiner Form, und nicht als Teil des Live-Repos.

Und wie Sie in Ihrer Frage anspielen, sollten Sie überlegen, ob git das beste Werkzeug für den Job ist. Ihre beschriebene Nutzung nutzt nicht die meisten Fähigkeiten von git; noch übt es die Funktionen aus, die git wirklich übertreffen. Umgekehrt können andere Tools die Geschichte schrittweise vereinfachen.

Aber mit all den sagte, könnten Sie immer noch die Entscheidung treffen mit „pro Minute“ Daten zu starten, dann ist es schließlich fallen auf „pro Stunde“, und vielleicht später noch reduzieren „auf * pro Woche.

(ich würde raten zu definieren viele Granularität Ebenen; die meisten "Bang für Ihr Geld" kommt mit Verwerfen sub-stündliche Snapshots. Stunde-> Tag wäre Borderline, Tag-> Woche wäre wahrscheinlich verschwenderisch . Wenn Sie auf wöchentlich herunterkommen, das ist sicherlich spärlich genug ...)

Also wenn einige Daten "ausalten", was zu tun ist, schlage ich vor, dass Sie so verwenden könnten die Kombination von Rebasing (und/oder verwandten Operationen), Tiefenlimits und Ersatz (je nach Ihren Bedürfnissen). Je nachdem, wie Sie diese kombinieren, können Sie die Illusion eines nahtlosen Verlaufs beibehalten, ohne die SHA-ID eines "aktuellen" Commits zu ändern.(Bei komplexeren Techniken, könnten Sie sogar nie zu arrangieren einen SHA-ID ändern, aber dies ist deutlich härter und die Platzersparnis etwas reduzieren.)

So in den folgenden Diagrammen gibt es eine Wurzel commit identifiziert als 'O'. Nachfolgende Commits (die winzigen Änderungen) werden durch einen Buchstaben und eine Nummer identifiziert. Der Buchstabe gibt den Tag an, an dem der Commit erstellt wurde, die Zahlen markieren nacheinander die Minuten.

Sie erstellen Ihr initiales Commit und platzieren Zweige für jede Granularität des Verlaufs, den Sie eventuell verwenden. (Wie ändert jede Minute ansammeln, werden sie gehen Sie einfach auf master.)

O <--(master)(hourly)(weekly) 

Nach ein paar Tagen haben Sie

O <-(hourly)(weekly) 
\ 
    A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1 <--(master) 

Und vielleicht haben Sie sich entschieden haben, um Mitternacht, dass jede Unter Stunde Schnappschüsse, die 24 Stunden alt sind, können verworfen werden.

So wie Tag C startet, sind die A Snapshots älter als 24 Stunden und sollte auf stündliche Snapshots reduziert werden. Zuerst müssen wir die stündlichen Schnappschüsse

git checkout hourly 
git merge --squash A60 
git commit -m 'Day A 1-60' 
git merge --squash A120 
git commit -m 'Day A 61-120' 
... 

Und das gibt Ihnen

O <-(weekly) 
|\ 
| A60' - A120' - ... - A1380' - A1440' <-(hourly) 
\ 
    A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1 <--(master) 

Hier A1440' ist ein Umschreiben von A1440, aber mit einer anderen Herkunft (so dass sein direkter Elternteil erstellen „vor einer Stunde“ statt "vor einer Minute").

Als nächstes, um die Geschichte nahtlos zu machen, würden Sie A1440' als seine Eltern identifizieren. Wenn Sie nicht über das Ändern der SHA-ID von jedem Commit (einschließlich Strom sind) ist es egal, wird ein rebase

git rebase --onto A1440' A1440 master 

arbeiten Oder in diesem Fall (da die TREE s bei A1440 und A1440' gleich sind) würde es äquivalent zu Re-Parent B1 sein - siehe die Dokumente git filter-branch für Details dieses Ansatzes. Wie auch immer Sie mit

O <-(weekly) 
|\ 
| A60' - A120' - ... - A1380' - A1440' <-(hourly) 
|          \ 
|          B1' - B2' - ... - B1439' - B1440' - C1' <-(master) 
\ 
    A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1 

Hinweis enden würde, dass, obwohl die Granularität der Veränderungen in den B und C Commits unverändert ist, sind diese noch „neu geschrieben“ verpflichtet (daher die ' Notation); und tatsächlich wurden die ursprünglichen Commits noch nicht physisch gelöscht. Sie sind jedoch unerreichbar, so dass sie schließlich von gc gereinigt werden; Wenn es sich um ein Problem handelt, können Sie dies beschleunigen, indem Sie Reflogs verwerfen, die älter als 24 Stunden sind, und dann manuell gc ausführen.

Alternativ, wenn Sie SHA-IDs für die B und C Commits erhalten möchten, können Sie git replace verwenden.

git replace A1440 A1440' 

Dies hat jedoch eine Reihe von Nachteilen. Es gibt ein paar bekannte Macken mit Ersatz. Auch in diesem Szenario sind die ursprünglichen Commits nicht unerreichbar (auch wenn sie nicht standardmäßig angezeigt werden). Sie müssten den Zweig master fluten, um sie loszuwerden.Der einfachste Weg, einen Zweig flachzufalten, besteht darin, den Repo zu klonen, aber dann müssen Sie durch zusätzliche Ringe springen, um die Ersatzreferenzen zu verbreiten. Dies ist also eine Option, wenn Sie nie wollen, dass der master ref "erkennt", dass er sich in abnormaler Weise bewegt, aber nicht so einfach.