J'ai un dépôt git avec de très nombreux (2000+) commits, par exemple:
l-- m -- n
/
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
\
x -- y -- z
et je veux tronquer l'ancien historique des journaux - supprimer toutes les validations de l'historique des journaux à partir (par exemple) de la validation "f" mais en tant que début du référentiel.
Comment faire?
Afin de ne pas perdre un peu d'histoire; mieux vaut d'abord prendre une copie de votre dépôt :). Et c'est parti: (<f>
est le sha du commit f que vous voulez être le nouveau commit racine)
git checkout --Orphan temp <f> # checkout to the status of the git repo at commit f; creating a branch named "temp"
git commit -m "new root commit" # create a new commit that is to be the new root commit
git rebase --onto temp <f> master # now rebase the part of history from <f> to master onthe temp branch
git branch -D temp # we don't need the temp branch anymore
Si vous avez une télécommande où vous souhaitez avoir le même historique tronqué; vous pouvez utiliser git Push -f
. Attention c'est une commande dangereuse; ne l'utilisez pas à la légère! Si vous voulez être sûr que votre dernière version du code est toujours la même; tu peux courir git diff Origin/master
. Cela ne devrait montrer aucun changement (puisque seul l'historique a changé, pas le contenu de vos fichiers).
git Push -f
Les 2 commandes suivantes sont facultatives - elles gardent votre dépôt git en bon état.
git Prune --progress # delete all the objects w/o references
git gc --aggressive # aggressively collect garbage; may take a lot of time on large repos
Une solution possible à votre problème est fournie par git clone
en utilisant --shallow-since
option. S'il n'y a qu'un petit nombre de validations depuis f
et qu'il n'y a aucun problème à les compter, vous pouvez utiliser le --depth
option.
La deuxième option (--depth
) clone uniquement la branche spécifiée. Si vous avez besoin de branches supplémentaires, vous pouvez ensuite ajouter le dépôt d'origine comme télécommande et utiliser git fetch
et pour les récupérer.
Lorsque vous êtes satisfait du résultat, supprimez l'ancien référentiel et renommez le nouveau pour le remplacer. Si l'ancien référentiel est distant, recréez-le après la suppression et poussez-le du nouveau référentiel vers celui-ci.
Cette approche a l'avantage de la taille et de la vitesse. Le nouveau dépôt ne contient que les validations souhaitées et il n'est pas nécessaire d'exécuter git Prune
ou git gc
pour supprimer les anciens objets (car ils ne sont pas là).