Faire la validation actuelle la seule validation (initiale) dans un repository Git?

J’ai actuellement un repository Git local, que je transmets à un repository Github.

Le référentiel local contient environ 10 commits et le référentiel Github en est une copie synchronisée.

Ce que je voudrais faire, c’est supprimer TOUT l’historique de la version du référentiel Git local, afin que le contenu actuel du référentiel apparaisse comme le seul commit (et donc les anciennes versions des fichiers du référentiel ne soient pas stockées).

Je voudrais alors pousser ces changements vers Github.

J’ai étudié le rebit de Git, mais cela semble être plus adapté à la suppression de versions spécifiques. Une autre solution potentielle consiste à supprimer le repo local et à en créer un nouveau, même si cela créera probablement beaucoup de travail!

ETA: Il y a des répertoires / fichiers spécifiques qui ne sont pas suivis – si possible je voudrais maintenir le désarchivage de ces fichiers.

Voici l’approche de la force brute. Il supprime également la configuration du référentiel.

Note : Cela ne fonctionne PAS si le référentiel a 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é )

rm -rf .git 

Étape 2: reconstruire le repository Git avec uniquement le contenu actuel

 git init git add . git commit -m "Initial commit" 

Étape 3: pousser vers GitHub.

 git remote add origin  git push -u --force origin master 

La seule solution qui fonctionne pour moi (et maintient le fonctionnement des sous-modules) est

 git checkout --orphan newBranch git add -A # Add all files and commit them git commit git branch -D master # Deletes the master branch git branch -m master # Rename the current branch to master git push -f origin master # Force push master branch to github git gc --aggressive --prune=all # remove the old files 

La suppression de .git/ provoque toujours d’énormes problèmes lorsque j’ai des sous-modules. Utiliser git rebase --root me causerait des conflits (et cela a pris beaucoup de temps depuis que j’ai beaucoup d’historique).

Ceci est mon approche préférée:

 git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree}) 

Cela créera une nouvelle twig avec un commit qui ajoute tout dans HEAD. Cela ne change rien d’autre, donc c’est complètement sûr.

L’autre option, qui pourrait s’avérer très compliquée si vous avez beaucoup de commits, est une rebase interactive (en supposant que votre version de git est> = 1.7.12): git rebase --root -i

Lorsqu’il est présenté avec une liste d’engagement dans votre éditeur:

  • Changer “pick” en “reword” pour le premier commit
  • Changer “pick” pour “réparer” tous les autres commit

Sauver et fermer. Git va commencer à rebaser.

A la fin, vous obtiendrez un nouveau commit racine qui sera une combinaison de tous ceux qui ont suivi.

L’avantage est que vous n’avez pas à supprimer votre référentiel et si vous avez des doutes, vous avez toujours une solution de rechange.

Si vous voulez vraiment détruire votre historique, réinitialisez master sur cette validation et supprimez toutes les autres twigs.

Variante de la méthode proposée par larsmans :

Enregistrez votre liste de fichiers non suivis:

 git ls-files --others --exclude-standard > /tmp/my_untracked_files 

Enregistrez votre configuration git:

 mv .git/config /tmp/ 

Effectuez ensuite les premiers pas de larsmans:

 rm -rf .git git init git add . 

Restaurez votre configuration:

 mv /tmp/config .git/ 

Débloquez les fichiers non suivis:

 cat /tmp/my_untracked_files | xargs -0 git rm --cached 

Puis commettez:

 git commit -m "Initial commit" 

Et enfin, poussez vers votre repository:

 git push -u --force origin master 

Créez une twig, copiez-y tous les contenus, validez-la puis supprimez la twig principale:

 git checkout --orphan newBranch; git add -A ;git commit -am 'first commit' ;git branch -D master;git branch -m master; git push -f origin master; git gc --aggressive --prune=all 

Vous pouvez utiliser des clones peu profonds (git> 1.9):

 git clone --depth depth remote-url 

Lectures complémentaires: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/

La méthode ci-dessous est exactement reproductible, il n’est donc pas nécessaire de relancer le clone si les deux côtés étaient cohérents, exécutez simplement le script de l’autre côté.

 git log -n1 --format=%H >.git/info/grafts git filter-branch -f rm .git/info/grafts 

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’histoire” pour chaque twig du repository:

http://sam.nipl.net/b/git-kill-history

voir aussi: http://sam.nipl.net/b/confirm

 git for-each-ref --format='git update-ref -d %(refname)' \ refs/{heads,tags} | sh -x current=$(git commit-tree -m 'Initial commit' `git write-tree`) git update-ref -m 'Initial commit' `git symbolic-ref HEAD` $current 

Cela supprimera toutes les twigs et balises locales, effectuera une validation sans historique avec l’état de votre extraction actuelle sur la twig en cours, et laissera le rest de votre repo intact. Vous pouvez ensuite forcer vos télécommandes à votre guise.

Ce que je voudrais faire, c’est supprimer TOUT l’historique de la version du référentiel Git local, afin que le contenu actuel du référentiel apparaisse comme le seul commit (et donc les anciennes versions des fichiers du référentiel ne soient pas stockées).

Une réponse plus conceptuelle:

git automatiquement ramasse les anciens commits si aucun tag / twigs / refs ne les pointent. Il vous suffit donc de supprimer toutes les balises / twigs et de créer un nouvel engagement orphelin, associé à n’importe quelle twig. Par convention, vous laisseriez la twig master pointer sur cette validation.

Les anciens commits inaccessibles ne seront plus jamais vus par quiconque à moins qu’ils ne creusent avec des commandes git de bas niveau. Si cela vous suffit, je m’arrêterais là et laisserais le GC automatique faire son travail quand il le souhaite. Si vous voulez vous en débarrasser immédiatement, vous pouvez utiliser git gc (éventuellement avec --aggressive --prune=all ). Pour le repository git distant, vous ne pouvez pas forcer cela, sauf si vous avez un access shell à leur système de fichiers.

J’ai résolu un problème similaire en supprimant simplement le dossier .git de mon projet et en le réintégrant avec le contrôle de version via IntelliJ. Remarque: le dossier .git est masqué. Vous pouvez l’afficher dans le terminal avec ls -a , puis le supprimer en utilisant rm -rf .git .

Pour supprimer le dernier commit de git, vous pouvez simplement exécuter

 git reset --hard HEAD^ 

Si vous supprimez plusieurs validations du haut, vous pouvez exécuter

 git reset --hard HEAD~2 

supprimer les deux derniers commits. Vous pouvez augmenter le nombre pour supprimer encore plus de commits.

Plus d’infos ici.

Git tutoturial ici fournit une aide sur la façon de purger le référentiel:

vous souhaitez supprimer le fichier de l’historique et l’append à .gitignore pour vous assurer qu’il n’est pas ré-commis accidentellement. Pour nos exemples, nous allons supprimer Rakefile du référentiel GitHub.

 git clone https://github.com/defunkt/github-gem.git cd github-gem git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch Rakefile' \ --prune-empty --tag-name-filter cat -- --all 

Maintenant que nous avons effacé le fichier de l’historique, assurons-nous que nous ne le commettons pas accidentellement.

 echo "Rakefile" >> .gitignore git add .gitignore git commit -m "Add Rakefile to .gitignore" 

Si vous êtes satisfait de l’état du référentiel, vous devez forcer les modifications pour remplacer le référentiel distant.

 git push origin master --force 

Pour cela, utilisez la commande Shallow Clone git clone –depth 1 URL – Elle ne clonera que le HEAD actuel du référentiel