web-dev-qa-db-fra.com

Git: erreur "Impossible de" écraser "sans une validation précédente lors de la création d'une nouvelle base

J'ai le texte suivant dans le texte à faire de git rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

Maintenant, quand j'essaie d'écraser le premier (56bcce7) et que je choisis le second en ajoutant "s" avant le premier, j'obtiens l'erreur suivante:

Cannot 'squash' without a previous commit

Quelqu'un peut-il m'expliquer ce que cela signifie et comment puis-je le faire?

Je veux écraser le premier commit (56bcce7) et "sélectionner et reformuler" le deuxième (e43ceba) commit

64
Dawny33

La base interactive présente les commits dans l'ordre inverse de celui auquel vous êtes habitué lorsque vous utilisez git log. git rebase -i rejoue les validations sélectionnées dans l'ordre exact (du haut vers le bas) dans le fichier d'instructions de base enregistré. Lors de l’écrasement, la validation sélectionnée pour être écrasée est combinée avec la validation qui le précède dans la liste (modifiée), c’est-à-dire la validation de la ligne précédente. Dans votre cas, il n'y a pas de commit précédent pour 56bcce7. Vous devez faire l'une des choses suivantes

  • git rebase -i HEAD~3 (si vous voulez écraser 56bcce7 dans 684f917)
  • Si vous voulez combiner 56bcce7 avec e43ceba et e43ceba ne dépend pas de 56bcce7, il vous suffit de les réorganiser:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    UPDATE: La réponse de Gus ci-dessous suggère une meilleure façon de faire la même chose, sans réorganiser les deux commits:

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    Cela écrasera/fusionnera les deux commits en un. Lorsque la base interactive demande un message de validation reformulé pour 56bcce7, indiquez le message de validation décrivant l'union de 56bcce7 et e43ceba.

59
Leon

J'ai eu un problème similaire que j'ai résolu comme suit:

Voici le groupe de commit que je voulais écraser:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Comme vous pouvez le constater, je ne voulais pas. 4, mais 1, 2 et 3 n’avaient aucun engagement antérieur à squash into. D'où le ne peut pas "écraser" sans un commit précédent erreur.

Ma solution consistait à utiliser l'option r pour # r, reword = use commit, but edit the commit message

Donc ma liste de commits ressemblait à ceci:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Après la sauvegarde, le shell interactif m'a demandé de reformuler le commit choisi.

Après cela, mon journal de validation a abouti à une seule validation qui a généré un historique de validation plus propre.

53
Gus

J'ai eu ce problème et la raison pour laquelle c'est arrivé dans mon cas était que, vous ne pouvez pas écraser les anciens commits sur un nouveau commit. Voici un exemple, disons que vous avez 3 commits:

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Maintenant, si vous dites git rebase -i HEAD~3 et que vous faites quelque chose comme

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

Cela entraînera l'erreur:

erreur: ne peut pas "écraser" sans un commit précédent Vous pouvez résoudre ce problème avec "git rebase --edit-todo" puis exécutez "git rebase --continue". Ou vous pouvez abandonner le rebase avec 'git rebase --abort'.

Solution:

Lorsque vous écrasez des commits, vous devriez calmer les commits récents sur les anciens, et non l'inverse. Dans l'exemple, cela ressemblera à ceci:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Cela fonctionnera très bien, si vous voulez tous vos messages de validation, je suggérerais correction au lieu de squash.

8
DvixExtract

Il sera préférable de simplement dire dans l'éditeur interactif contenant les commits, git écrasera toujours de haut en bas et il faudra laisser une entrée "pick" en bas pour recevoir les squash d'en haut.

1
ekyu88

J'ai également déjà rencontré ce problème tout à l'heure, c'est juste imprudent. Vous pouvez résoudre le problème comme suit: lorsque vous essayez d'écraser le premier (56bcce7) et choisissez le second, vous devez ajouter "s" avant la deuxième ligne mais pas le premier. vous pouvez également faire référence au site Web suivant: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html

0
user8073722