Comment annuler la validation initiale de git?

358

Je m'engage dans un dépôt git pour la première fois; Je regrette ensuite l'engagement et souhaite le revenir. J'essaie

# git reset --hard HEAD~1

Je reçois ce message:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

Cette validation est la première validation du référentiel. Une idée de comment annuler la validation initiale de git?

Chau Chee Yang
la source

Réponses:

566

Il vous suffit de supprimer la branche sur laquelle vous vous trouvez. Vous ne pouvez pas l'utiliser git branch -Dcar cela a un contrôle de sécurité contre cela. Vous pouvez utiliser update-refpour ce faire.

git update-ref -d HEAD

Ne pas utiliser rm -rf .gitou quoi que ce soit comme ça que cela va complètement effacer la totalité de votre dépôt , y compris toutes les autres branches, ainsi que la branche que vous essayez de réinitialiser.

CB Bailey
la source
1
J'ai essayé cela pendant un rebase - je voulais diviser le tout premier commit - puis git statusje l' ai fait , et à ma grande surprise, git a dit fatal: Not a git repository (or any parent up to mount point ...)!
Matt Fenwick
1
cela n'a pas fonctionné pour moi. Créez des fichiers, dont certains doivent être ignorés, mais non .gitignore. git add ., git commit -m "initial commit", git update-ref -D HEAD, Créez un .gitignore, notez que git est encore voir les fichiers qu'il a ajouté plus tôt qui devrait ignorer. En d'autres termes, git update-ref -d HEADcela ne m'a pas ramené à l'état avant le commit initial.
gman
1
Mais c'est le point de la question d'origine. Revenir à l'état juste avant la validation initiale.
gman
2
git reset --hard HEAD~1supprimerait les fichiers ajoutés pour toutes les autres validations. De toute évidence, la question est de savoir comment atteindre le même état que cette commande fonctionne dans tous les autres cas. Voir cet essentiel pour prouver que votre solution ne fonctionne pas gist.github.com/greggman/522fa69a21d6cfb3ff0b
gman
11
Au cas où quelqu'un est perturbé par les commentaires de GMan: git update-ref -d HEAD ne nous revenions en fait la commettras initiale, mais conserve tous les changements précédemment ajoutés à l'commises index. Si vous souhaitez également supprimer ces modifications, exécutez simplement ce qui suit git reset --hard. Même si elle est incomplète, cette réponse est en effet la meilleure, donc évitez de l'utiliser rm -fr .git(sauf si vous savez ce que vous faites).
rsenna
62

Vous pouvez supprimer le HEAD et restaurer votre référentiel dans un nouvel état, où vous pouvez créer un nouveau commit initial:

git update-ref -d HEAD

Après avoir créé un nouveau commit, si vous avez déjà poussé vers remote, vous devrez le forcer sur le remote pour écraser le commit initial précédent:

git push --force origin
frazras
la source
1
À noter ... c'est la commande correcte mais elle ne supprime pas la tête ... elle supprime la référence (située sous .git \ refs \ heads) que le fichier .git \ HEAD a extraite. Après avoir exécuté cette commande, vous pouvez toujours trouver le fichier HEAD pointant vers le fichier refs / heads / <nom> que vous avez supprimé mais si vous suivez ce chemin, vous verrez que la référence head n'existe plus.
DanK
15

Cette question a été liée à partir de ce billet de blog et une solution alternative a été proposée pour les nouvelles versions de Git:

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

Cette solution suppose que:

  1. Vous n'avez qu'un seul commit sur votre masterbranche
  2. Il n'y a pas de branche appelée old_masterdonc je suis libre d'utiliser ce nom

Il renommera la branche existante old_masteret créera une nouvelle branche orpheline master (comme elle est créée pour les nouveaux référentiels) après laquelle vous pouvez librement supprimer old_master... ou non. Dépend de vous.

Remarque: Le déplacement ou la copie d'une branche git préserve son reflog (voir ce code ) tout en supprimant puis en créant une nouvelle branche la détruit. Puisque vous souhaitez revenir à l'état d'origine sans historique, vous souhaiterez probablement supprimer la branche, mais d'autres voudront peut-être considérer cette petite note.

insensé
la source
11

Dans les conditions stipulées dans la question:

  • La validation est la première validation dans le référentiel.
  • Ce qui signifie qu'il y a eu très peu de commandes exécutées:
    • a git init,
    • vraisemblablement certaines git addopérations,
    • et un git commit,
    • et c'est tout!

Si ces conditions préalables sont remplies, le moyen le plus simple d'annuler la validation initiale serait:

rm -fr .git

à partir du répertoire où vous l'avez fait git init. Vous pouvez ensuite refaire le git initpour recréer le référentiel Git, et refaire les ajouts avec les modifications que vous avez regrettées de ne pas avoir faites la première fois, et refaire le commit initial.

DANGER! Cela supprime le répertoire du référentiel Git.

Il supprime le répertoire du référentiel Git de manière permanente et irrécupérable, sauf si vous avez des sauvegardes quelque part. Dans les conditions préalables, vous n'avez rien que vous souhaitez conserver dans le référentiel, donc vous ne perdez rien. Tous les fichiers que vous avez ajoutés sont toujours disponibles dans les répertoires de travail, en supposant que vous ne les avez pas encore modifiés et que vous ne les avez pas supprimés, etc. Cependant, cela n'est sûr que si vous n'avez rien d'autre dans votre référentiel. Dans les circonstances décrites dans la question «Valider le référentiel pour la première fois - puis le regretter», c'est sûr. Très souvent, cependant, ce n'est pas sûr.

Il est également sûr de le faire pour supprimer un référentiel cloné indésirable; il n'endommage pas le référentiel à partir duquel il a été cloné. Il jette tout ce que vous avez fait dans votre copie, mais n'affecte pas autrement le référentiel d'origine.

Soyez prudent, mais il est sûr et efficace lorsque les conditions préalables sont remplies.

Si vous avez fait d'autres choses avec votre référentiel que vous souhaitez conserver, alors ce n'est pas la technique appropriée - votre référentiel ne remplit plus les conditions préalables pour que cela soit approprié.

Jonathan Leffler
la source
9
C'est un mauvais conseil. Et s'il y a d'autres choses dans le repo que vous ne voulez pas perdre?
Matt Fenwick
5
Alors ce ne serait pas le commit initial, n'est-ce pas? Il n'y a qu'un seul commit initial.
Jonathan Leffler
9
"Alors ce ne serait pas le commit initial" - en fait, oui. Vous négligez le cas très courant de plusieurs branches. Voir la réponse de Charles.
Matt Fenwick
2
Utile, cependant, devrait être accompagné d'un avertissement.
Simon Bengtsson
5
Cela fonctionne réellement. La réponse acceptée ne le fait pas. Voir le commentaire
gman
3

Tu ne peux pas. Donc:

rm -rf .git/
git init
git add -A
git commit -m 'Your new commit message'
ma11hew28
la source
1
Il a essayé de dire git reset --hard, alors pourquoi le ferait-il git add -A?
Aristotle Pagaltzis
3

Je vais ajouter ce qui a fonctionné pour moi à la fin. J'avais besoin de supprimer la validation initiale sur un référentiel car les données en quarantaine avaient été mal placées, la validation avait déjà été poussée.

Assurez-vous que vous êtes actuellement sur la bonne branche.

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

Cela a pu résoudre le problème.

Important

C'était sur un référentiel interne qui n'était pas accessible au public, si votre référentiel était accessible au public, supposez que tout ce dont vous avez besoin pour revenir en arrière a déjà été supprimé par quelqu'un d'autre.

Edward
la source
1

Je me demande pourquoi "modifier" n'est pas suggéré et a été barré par @damkrat, car amend me semble être la bonne façon de résoudre le plus efficacement le problème sous-jacent de corriger le mauvais commit car il n'y a pas de but de n'avoir aucune initiale commettre. Comme certains l'ont souligné, vous ne devez modifier la branche "publique" comme master que si personne n'a cloné votre dépôt ...

git add <your different stuff>
git commit --amend --author="author name <[email protected]>"-m "new message"
Richard
la source
- l'auteur n'est requis que si quelqu'un corrige la paternité du commit
Richard
0

git reset --hard faire des changements, puis faire

git add -A
git commit --amend --no-edit 

ou

git add -A
git commit --amend -m "commit_message"

et alors

git push origin master --force

--force réécrira le commit que vous avez réinitialisé à la première étape.

Ne faites pas cela, car vous êtes sur le point d'aller à l'encontre de l'idée des systèmes VCS et de git en particulier. La seule bonne méthode consiste à créer une nouvelle branche et à la supprimer. Voir git help branchpour info.

damkrat
la source
-1

Tout ce que vous avez à faire est d'annuler le commit.

git revert {commit_id}'

Ensuite, poussez-le

git push origin -f
abdallah Nofal
la source
Il n'est pas possible de faire cela au premier commit.
Utilisateur qui n'est pas un utilisateur