2017-09-11 15 views
0

Je veux garder une trace sur un texte json 500kb qui modifie son contenu minutieusement. Je voudrais utiliser git, donc je peux utiliser git pull sur un autre serveur pour télécharger la dernière version de ce fichier sans le problème, que le fichier pourrait changer pendant le téléchargement et je veux aussi avoir un versionnement de ce fichier pour les derniers mois/années de cette façon en même temps.Dépôt git tronqué keepinng snapshots réguliers

Je pensais que la création d'un dépôt git où je commets chaque changement de fichier, mais je remarqué, au bout de quelques jours, ce dépôt obtient la taille de plusieurs Go (même avec git gc parce qu'il change tellement dans le fichier)

Je pourrais tronquer le git régulièrement à une profondeur particulière mais ce n'est pas ce dont j'ai besoin. J'ai besoin de l'information, comment le fichier a ressemblé il y a une semaine, un mois, il ya un an. Bien que je n'aie pas besoin d'autant de commits, plus c'est long. Est-ce encore possible avec git et un peu de magie bash? Je suis bien avec la suppression et la recréation du référentiel et en utilisant --amend dans ce git

Ou suggérez-vous une autre solution?

+0

Est-ce qu'un ensemble approprié de tâches 'cron' déclenchées chaque minute/heure/jour/mois est une solution valide? Je soupçonne qu'une solution 'git' est trop sur-élaborée, d'autant plus que chaque fois que vous essayez de tronquer le dépôt, il faudra recalculer tous les hashs. – Phylogenesis

+0

Avez-vous essayé d'exécuter 'git gc' ou' git gc --aggressive' pour voir à quel point votre repo git peut être réduit? – Mort

+0

Je voudrais utiliser git, donc je peux utiliser git pull sur un autre serveur pour télécharger la dernière version de ce fichier sans le problème, que le fichier puisse changer pendant le téléchargement et je veux aussi avoir un versioning de ce fichier pour le dernier mois/années de cette façon en même temps – rubo77

Répondre

1

Il y a au moins un moyen de le faire; Je vais décrire une approche ci-dessous. Voici d'abord quelques points à considérer:

Selon la nature des changements qui se produisent, vous pourriez vouloir voir si l'emballage fréquent de la base de données pourrait aider; git est assez bon pour éviter l'espace gaspillé (pour les fichiers texte, au moins).

Bien sûr, avec la charge de validation que vous décrivez - 1440 validations par jour, donner ou prendre? - L'histoire aura tendance à croître. Pourtant, à moins que les changements soient dramatiques sur chaque commit, il semble que cela pourrait être mieux que "beaucoup de GB dans quelques jours"; et peut-être vous atteindriez un niveau où une stratégie d'archivage de compromis deviendrait pratique.

Il est toujours utile de réfléchir également à la question de savoir si «toutes les données que je dois conserver» sont plus grandes que «toutes les données auxquelles j'ai besoin d'un accès régulier»; car vous pouvez alors déterminer si certaines données doivent être conservées dans des dépôts d'archives, éventuellement sur des supports de sauvegarde sous une forme ou une autre, plutôt que dans le cadre d'un dépôt en direct. Et, comme vous faites allusion dans votre question, vous pourriez vouloir considérer si le git est le meilleur outil pour le travail. Votre utilisation décrite n'utilise pas la plupart des capacités de git; il n'exerce pas non plus les fonctionnalités qui font vraiment git excel. Et inversement, d'autres outils peuvent faciliter l'effacement progressif de l'historique.

Mais avec tout cela dit, vous pouvez toujours prendre la décision de commencer par « par minute » les données, puis finalement tomber à « l'heure », et peut-être réduire encore plus tard par semaine ».

(Je déconseillerais de définir trop plusieurs niveaux de granularité, le plus "pour votre argent" viendra avec rejeter des instantanés sub-horaires.Heure-> jour serait limite, jour-> semaine serait probablement un gaspillage Si vous vous rendez à hebdomadaire, c'est assez rare ...)

Alors quand certaines données "vieillit", que faire? Je suggère que vous pourriez utiliser ainsi Combinaison de rebasing (et/ou d'opérations connexes), de limites de profondeur et de remplacements (en fonction de vos besoins). Selon la manière dont vous les combinez, vous pouvez conserver l'illusion d'un historique transparent sans modifier l'ID SHA de toute validation "en cours".(Avec des techniques plus complexes, vous pouvez même organiser à jamais changer un ID SHA, mais cela est nettement plus difficile et réduire ainsi les économies d'espace un peu.)

Ainsi, dans les schémas ci-dessous, il y a une racine allouent identifiée comme 'O'. Les commits suivants (les changements minutieusement) sont identifiés par une lettre et un nombre. La lettre indique le jour où le commit a été créé, les chiffres marquent séquentiellement les minutes.

Vous créez votre validation initiale et y placez des branches pour chaque granularité de l'historique que vous utiliserez éventuellement. (Comme les changements accumulent chaque minute, ils vont aller sur master.)

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

Après quelques jours, vous avez

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

Et peut-être que vous avez décidé que, à minuit, tous les sous-heures Un instantané de 24 heures peut être supprimé. Débute, les instantanés A ont plus de 24 heures et doivent être réduits à des instantanés horaires. D'abord, nous devons créer les instantanés horaires

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' 
... 

Et cela vous donne

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

Ici A1440' est une réécriture de A1440, mais avec une filiation différente (telle que son parent direct est « il y a une heure » au lieu de "il y a une minute").

Ensuite, pour rendre l'historique transparent, vous auriez B1 identifier A1440' comme parent. Si vous ne se soucient pas de changer l'ID SHA de chaque commit (y compris ceux en cours), un rebasage travaillera

git rebase --onto A1440' A1440 master 

Ou dans ce cas (puisque les TREE s à A1440 et A1440' sont les mêmes), il serait être équivalent à reparent B1 - voir les docs git filter-branch pour les détails de cette approche. De toute façon, vous finiriez avec

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

Notez que même si la granularité des changements dans les B et C commits ne change pas, ceux-ci sont encore « réécrites » engage (donc la notation '); et en fait les commits originaux n'ont pas encore été effacés physiquement. Ils sont inaccessibles, cependant, ils seront finalement nettoyés par gc; Si c'est un problème, vous pouvez accélérer ce processus en éliminant les reflogs de plus de 24 heures et en exécutant manuellement gc. Si vous souhaitez conserver les ID SHA pour les validations B et C, vous pouvez utiliser git replace.

git replace A1440 A1440' 

Cela présente un certain nombre d'inconvénients. Il y a quelques bizarreries connues avec des remplacements. Dans ce scénario également, les commits d'origine ne sont pas inaccessibles (même s'ils ne sont pas affichés par défaut); vous devez superficielle la branche master pour se débarrasser d'eux.La façon la plus simple de faire une branche est de cloner le repo, mais vous devez ensuite passer à travers des cerceaux supplémentaires pour propager les refs de remplacement. Donc, ceci est une option si vous ne voulez jamais que le master réf "réalise" qu'il se déplace d'une manière anormale, mais pas aussi simple.