Question Rendre le commit actuel le seul commit (initial) dans un dépôt Git?


J'ai actuellement un dépôt Git local, que je pousse dans un dépôt 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 est de supprimer TOUT l'historique des versions du référentiel Git local, de sorte que le contenu actuel du dépôt apparaisse comme le seul commit (et donc les anciennes versions des fichiers dans le référentiel ne sont pas stockées).

J'aimerais ensuite pousser ces changements à Github.

J'ai étudié Git rebase, mais cela semble mieux 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 existe des répertoires / fichiers spécifiques qui ne sont pas suivis - si possible, je voudrais conserver le suivi de ces fichiers.


507
2018-03-13 11:41


origine


Réponses:


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

Remarque: Cela ne fonctionne PAS si le dépôt a des sous-modules! Si vous utilisez des sous-modules, vous devez utiliser par exemple rebase interactif

Étape 1: supprimer toute l’histoire (Assurez-vous que vous avez une sauvegarde, cela ne peut pas être annulé)

rm -rf .git

Étape 2: reconstruire le repo Git avec seulement le contenu actuel

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

Étape 3: pousser vers GitHub.

git remote add origin <github-uri>
git push -u --force origin master

802
2017-10-27 18:16



La seule solution qui fonctionne pour moi (et qui fait fonctionner les 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

Effacer .git/ provoque toujours d'énormes problèmes lorsque j'ai des sous-modules. En utilisant git rebase --root serait en quelque sorte causer des conflits pour moi (et prendre longtemps depuis que j'avais beaucoup d'histoire).


448
2018-03-22 13:53



C'est mon approche préférée:

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

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.


67
2018-03-14 20:24



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 est> = 1.7.12):git rebase --root -i

Lorsque présenté avec une liste de commits dans votre éditeur:

  • Changez "pick" en "reword" pour le premier commit
  • Changez "pick" en "fixup" tous les autres commit

Sauver et fermer. Git va commencer à rebaser.

A la fin vous auriez un nouveau commit racine qui est une combinaison de tous ceux qui sont venus après.

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 réellement réaliser un historique, réinitialisez le maître à ce commit et supprimez toutes les autres branches.


29
2018-04-19 08:58



Variante de larsmansLa méthode proposée:

Sauvegardez votre liste de fichiers inutiles:

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

Enregistrez votre configuration git:

mv .git/config /tmp/

Ensuite, effectuez 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

Ensuite, commettez:

git commit -m "Initial commit"

Et enfin pousser à votre dépôt:

git push -u --force origin master

15
2018-03-12 14:53



Créez une branche, copiez tout son contenu, validez-la puis supprimez la branche master:

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

6
2018-04-04 11:05



Vous pouvez utiliser peu profond clones (git> 1,9):

git clone --depth depth remote-url

En lire plus: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/


5
2018-02-06 16:46



La méthode ci-dessous est exactement reproductible, il n'est donc pas nécessaire d'exécuter à nouveau 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 branche du dépôt:

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

voir également: http://sam.nipl.net/b/confirm


2
2018-04-05 01:42



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 branches locales et les tags, effectuera un seul commit sans historique avec l'état de votre commande actuelle sur la branche actuelle et laissera intact tout le reste de votre dépôt. Vous pouvez ensuite forcer vos télécommandes à votre guise.


1
2018-04-04 11:27



Ce que je voudrais faire est de supprimer TOUT l'historique des versions du référentiel Git local, de sorte que le contenu actuel du dépôt apparaisse comme le seul commit (et donc les anciennes versions des fichiers dans le référentiel ne sont pas stockées).

Une réponse plus conceptuelle:

git automatiquement ramasse les anciennes validations si aucune balise / branche / ref ne pointe dessus. Il vous suffit donc de supprimer tous les tags / branches et de créer un nouveau commit orphelin, associé à n'importe quelle branche - par convention vous laisseriez la branche master pointez sur ce commit.

Les anciens commits inatteignables 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 voudrait. Si vous voulez vous débarrasser d'eux tout de suite, vous pouvez utiliser git gc (éventuellement avec --aggressive --prune=all). Pour le référentiel git distant, vous n'avez aucun moyen de le forcer, sauf si vous avez un accès shell à leur système de fichiers.


0
2018-04-11 18:54



J'ai résolu un problème similaire en supprimant simplement le .git dossier de mon projet et réintégrer avec le contrôle de version via IntelliJ. Noter la .git le dossier est caché. Vous pouvez le voir dans le terminal avec ls -a , puis retirez-le en utilisant rm -rf .git .


0
2018-06-05 05:41