J'ai actuellement un référentiel Git local, que je pousse vers un référentiel Github.
Le référentiel local a environ 10 validations, et le référentiel Github en est un double synchronisé.
Ce que je voudrais faire, c'est supprimer TOUT l'historique des versions du référentiel Git local, de sorte que le contenu actuel du référentiel apparaisse comme le seul commit (et donc les anciennes versions de fichiers dans le référentiel ne sont pas stockées).
J'aimerais ensuite transmettre ces modifications à Github.
J'ai étudié le rebase de Git, mais cela semble être plus adapté à la suppression de versions spécifiques. Une autre solution potentielle est de supprimer le référentiel local et d'en créer un nouveau - bien que cela créerait probablement beaucoup de travail!
ETA: Il existe des répertoires / fichiers spécifiques qui ne sont pas suivis - si possible, je voudrais maintenir le non-suivi de ces fichiers.
la source
Réponses:
Voici l'approche par force brute. Il supprime également la configuration du référentiel.
Remarque : cela ne fonctionne PAS si le référentiel contient des sous-modules! Si vous utilisez des sous-modules, vous devez utiliser par exemple un rebase interactif
Étape 1: supprimer tout l'historique ( assurez-vous d'avoir une sauvegarde, cela ne peut pas être annulé )
Étape 2: reconstruire le référentiel Git avec uniquement le contenu actuel
Étape 3: appuyez sur GitHub.
la source
.gitignore
devriez les gérer, non?git commit -m "Initial commit"
vous pouvez probablement ignorer lagit remote add ...
partie, en supposant qu'elle était déjà dans votre configuration, et passer directement à la poussée. Ça a marché pour moi.La seule solution qui fonctionne pour moi (et fait fonctionner les sous-modules) est
La suppression
.git/
cause toujours d'énormes problèmes lorsque j'ai des sous-modules. L'utilisationgit rebase --root
me causerait en quelque sorte des conflits (et prendrait longtemps car j'avais beaucoup d'histoire).la source
git push -f origin master
comme le dernier op et le soleil brillera encore sur votre repo frais! :)git gc --aggressive --prune all
tout le point de perdre l'histoire serait raté.Voici mon approche privilégiée:
Cela va créer une nouvelle branche avec un commit qui ajoute tout dans HEAD. Cela ne change rien d'autre, donc c'est complètement sûr.
la source
git-rev-parse
documents. Ce qui se passe icigit-commit-tree
nécessite une référence à un arbre (un instantané du dépôt), maisHEAD
est une révision. Pour trouver l'arbre associé à un commit, nous utilisons le<rev>^{<type>}
formulaire.git push --force <remote> new_branch_name:<remote-branch>
L'autre option, qui pourrait s'avérer être beaucoup de travail si vous avez beaucoup de commits, est une rebase interactive (en supposant que votre version git soit> = 1.7.12):
git rebase --root -i
Lorsqu'une liste de validations s'affiche dans votre éditeur:
Sauver et fermer. Git va commencer le rebasage.
À la fin, vous auriez un nouveau commit racine qui est une combinaison de tous ceux qui l'ont suivi.
L'avantage est que vous n'avez pas à supprimer votre référentiel et si vous avez des doutes, vous avez toujours un repli.
Si vous voulez vraiment nuancer votre historique, réinitialisez master à ce commit et supprimez toutes les autres branches.
la source
error: failed to push some refs to
git push --force-with-lease
. force-with-lease est utilisé car il est moins destructeur que --force.Variante de la méthode proposée par Larsmans :
Enregistrez votre liste de non-traces:
Enregistrez votre configuration git:
Effectuez ensuite les premières étapes de larsmans:
Restaurez votre configuration:
Détachez vos fichiers non suivis:
Engagez ensuite:
Et enfin, poussez vers votre référentiel:
la source
Vous trouverez ci-dessous un script adapté de la réponse de @Zeelot. Il devrait supprimer l'historique de toutes les branches, pas seulement de la branche principale:
Cela a fonctionné pour mes besoins (je n'utilise pas de sous-modules).
la source
git branch
inclura un astérisque à côté de votre branche extraite, qui sera ensuite globglé, ce qui entraînera sa résolution dans tous les fichiers ou dossiers comme s'il s'agissait également de noms de branche. Au lieu de cela, j'ai utiliségit branch --format="%(refname:lstrip=2)"
ce qui m'a donné uniquement les noms des succursales.git push --force origin master
, ougit push --force-with-lease
? Apparemment, ce dernier est plus sûr (voir stackoverflow.com/questions/5509543/… )Vous pouvez utiliser des clones peu profonds (git> 1.9):
Pour en savoir plus: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
la source
git filter-branch
est l'outil de chirurgie majeure.--parent-filter
obtient les parents sur stdin et devrait imprimer les parents réécrits sur stdout; unixtrue
sort avec succès et n'imprime rien, donc: pas de parents.@^!
est l' abréviation de Git pour "le responsable principal mais pas l'un de ses parents". Supprimez ensuite toutes les autres références et appuyez à loisir.la source
Supprimez simplement le dépôt Github et créez-en un nouveau. De loin l'approche la plus rapide, la plus simple et la plus sûre. Après tout, qu'avez-vous à gagner à exécuter toutes ces commandes dans la solution acceptée lorsque tout ce que vous voulez, c'est la branche principale avec un seul commit?
la source
La méthode ci-dessous est exactement reproductible, il n'est donc pas nécessaire de réexécuter le clone si les deux côtés étaient cohérents, il suffit d'exécuter le script de l'autre côté également.
Si vous souhaitez ensuite le nettoyer, essayez ce script:
http://sam.nipl.net/b/git-gc-all-ferocious
J'ai écrit un script qui "tue l'historique" pour chaque branche du référentiel:
http://sam.nipl.net/b/git-kill-history
voir aussi: http://sam.nipl.net/b/confirm
la source
git-hash: not found
etSupport for <GIT_DIR>/info/grafts is deprecated
git log HEAD~${1:-0} -n1 --format=%H
, ici, sam.aiki.info/b/git-hash Il serait préférable de tout mettre dans un script pour la consommation publique. Si je l'utilise à nouveau, je pourrais trouver comment le faire avec la nouvelle fonctionnalité qui remplace les "greffons".Une réponse plus conceptuelle:
git récupère automatiquement les anciens commits si aucune balise / branche / référence ne pointe vers eux. Il vous suffit donc de supprimer toutes les balises / branches et de créer un nouveau commit orphelin, associé à n'importe quelle branche - par convention, vous laisseriez la branche
master
pointer vers ce commit.Les anciens commits inaccessibles ne seront alors plus jamais vus par quiconque à moins qu'ils ne creusent avec des commandes git de bas niveau. Si cela vous suffit, je m'arrête là et je laisse le GC automatique faire son travail quand il le souhaite. Si vous voulez vous en débarrasser tout de suite, vous pouvez utiliser
git gc
(éventuellement avec--aggressive --prune=all
). Pour le référentiel git distant, il n'y a aucun moyen pour vous de forcer cela, sauf si vous avez un accès shell à leur système de fichiers.la source
Voici:
Également hébergé ici: https://gist.github.com/Zibri/76614988478a076bbe105545a16ee743
la source
J'ai résolu un problème similaire en supprimant simplement le
.git
dossier de mon projet et en réintégrant le contrôle de version via IntelliJ. Remarque: le.git
dossier est masqué. Vous pouvez l'afficher dans le terminal avecls -a
, puis le supprimer à l'aide derm -rf .git
.la source
Pour cela, utilisez la commande Shallow Clone git clone --depth 1 URL - Il clone uniquement le HEAD actuel du référentiel
la source
Plus d'infos ici.
Git tutoturial fournit ici de l' aide sur la façon de purger le référentiel:
la source