J'essaie de fusionner 2 commits en 1, j'ai donc suivi "squashing commits with rebase" de git ready .
L'Iran
git rebase --interactive HEAD~2
Dans l'éditeur résultant, je passe pick
à squash
, puis je sauvegarde-quitte, mais le rebase échoue avec l'erreur
Impossible de 'squash' sans un commit précédent
Maintenant que mon arbre de travail a atteint cet état, j'ai du mal à récupérer.
La commande git rebase --interactive HEAD~2
échoue avec:
Le rebase interactif a déjà commencé
et git rebase --continue
échoue avec
Impossible de 'squash' sans un commit précédent
Réponses:
Sommaire
Le message d'erreur
signifie que vous avez probablement tenté de «vous écraser vers le bas». Git écrase toujours un commit plus récent dans un commit plus ancien ou «vers le haut» comme affiché sur la liste de tâches de rebase interactive, c'est-à-dire dans un commit sur une ligne précédente. Changer la commande sur la toute première ligne de votre liste de tâches
squash
produira toujours cette erreur car il n'y a rien pour le premier commit à écraser.The Fix
Revenez d'abord à votre point de départ
Dis que ton histoire est
Autrement dit, a était le premier commit, puis b et enfin c. Après avoir commis c, nous décidons d'écraser b et c ensemble:
(Remarque: l'exécution par défaut
git log
achemine sa sortie vers un pageur,less
par défaut sur la plupart des plates-formes. Pour quitter le pageur et revenir à votre invite de commande, appuyez sur laq
touche.)La course à pied
git rebase --interactive HEAD~2
vous donne un éditeur avec(Notez que cette liste de tâches est dans l'ordre inverse par rapport à la sortie de
git log
.)Modification de B
pick
àsquash
entraînera l'erreur que vous avez vu, mais si au contraire vous de squash c en b (dans le récent engagement plus ou « vers le haut squashing ») en modifiant la liste des tâches àet en sauvegardant votre éditeur, vous obtiendrez un autre éditeur dont le contenu est
Lorsque vous enregistrez et quittez, le contenu du fichier modifié devient le message de validation du nouveau commit combiné:
Remarque sur l'historique de réécriture
Le rebase interactif réécrit l'histoire. Tenter de pousser vers une télécommande contenant l'ancien historique échouera car il ne s'agit pas d'une avance rapide.
Si la branche que vous avez rebasée est une branche de sujet ou de fonctionnalité dans laquelle vous travaillez par vous - même , ce n'est pas grave. Pousser vers un autre référentiel nécessitera la
--force
option, ou bien vous pourrez, selon les autorisations du référentiel distant, supprimer d'abord l'ancienne branche, puis pousser la version rebasée. Des exemples de ces commandes susceptibles de détruire le travail sont hors de portée de cette réponse.La réécriture de l'historique déjà publié sur une branche dans laquelle vous travaillez avec d'autres personnes sans très bonne raison, comme la fuite d'un mot de passe ou d'autres détails sensibles, force le travail sur vos collaborateurs et est antisocial et ennuiera les autres développeurs. La section «Récupération à partir d'une rebase en amont» dans la
git rebase
documentation explique, avec un accent supplémentaire.la source
git log hashoftheoldcommit
et cela a fonctionné, maisgit log --graph
S'il y a plusieurs validations, vous pouvez utiliser
git rebase -i
pour écraser deux validations en une seule.S'il n'y a que deux validations que vous souhaitez fusionner, et qu'il s'agit des «deux plus récentes», les commandes suivantes peuvent être utilisées pour combiner les deux validations en une seule:
la source
git reset --soft HEAD~10
, où 10 est le nombre de validations que vous souhaitez fusionner.HEAD
en utilisant l'git reset --soft 47b5c5...
emplacement de47b5c5...
l'ID SHA1 du commit.Rebase: vous n'en aurez pas besoin:
Un moyen plus simple pour le scénario le plus fréquent.
Dans la plupart des cas:
En fait, si tout ce que vous voulez, c'est simplement combiner plusieurs validations récentes en une seule, mais que vous n'avez pas besoin
drop
,reword
et que d'autres rebases fonctionnent.vous pouvez simplement faire:
~n
est le nombre de commits à voix basse un-commit (c. -à~1
,~2
...)Utilisez ensuite la commande suivante pour modifier le message de validation.
qui est à peu près la même chose qu'une longue portée de
squash
et unpick
.Et cela fonctionne pour n commits mais pas seulement pour deux commits comme indiqué ci-dessus.
la source
~n
est le nombre de commits à un-commit doucement (ie~1
,~2
...)n
dernières validations, mais lesn
validations au milieu? Puis-je le faire facilement?git rebase -i
c'est ce que vous devez faire poursquash
travailler. @chumakoffn
les commits les plus récents en un, première utilisationgit reset --soft @~m
, oùm = n - 1
Vous devez d'abord vérifier le nombre de commits que vous avez:
Il existe deux statuts:
La première est qu'il n'y a que deux commits:
Par exemple:
(Dans ce cas, vous ne pouvez pas utiliser git rebase pour le faire), vous devez faire ce qui suit.
Un autre est qu'il y a plus de deux commits; vous voulez fusionner les commit C et D.
Par exemple:
(sous cette condition, vous pouvez utiliser git rebase)
Et que d'utiliser "squash" pour le faire. Le reste aminci est très facile. Si vous ne savez toujours pas, veuillez lire http://zerodie.github.io/blog/2012/01/19/git-rebase-i/
la source
git push -f origin master
pourrait être nécessaire.En supposant que vous étiez dans votre propre branche de sujet. Si vous souhaitez fusionner les 2 dernières validations en une seule et ressembler à un héros, dérivez la validation juste avant d'avoir effectué les deux dernières validations.
Squash valide ensuite l'autre branche dans cette nouvelle branche:
Cela apportera les changements mais ne les engagera pas. Alors, engagez-les et vous avez terminé.
Vous pouvez maintenant fusionner cette nouvelle branche de sujet dans votre branche principale.
la source
a
ellec
doit être fusionnée et conservéeb
telle quelle.git checkout -b combine-last-two-commits "HEAD^2"
) dans la version 2.17 de git, j'obtiens une erreur:fatal: 'HEAD^2' is not a commit and a branch 'combine-last-two-commits' cannot be created from it
vous pouvez annuler le rebase avec
et lorsque vous exécutez à nouveau la commande interactive rebase, le 'squash; la validation doit être inférieure à la sélection de validation dans la liste
la source
J'utilise souvent git reset --mixed pour rétablir une version de base avant plusieurs validations que vous souhaitez fusionner, puis je fais un nouveau commit, de cette façon pourrait laisser votre commit le plus récent, assurez-vous que votre version est HEAD après avoir poussé sur le serveur.
Si je veux fusionner deux commits en un seul, j'utilise d'abord:
"249cf9392da197573a17c8426c282" était la troisième version, est également votre version de base avant de fusionner, après cela, je fais un nouveau commit:
C'est tout, l'espoir est une autre façon pour tout le monde.
Pour info, de
git reset --help
:la source
$ git rebase --abort
Exécutez ce code à tout moment si vous souhaitez annuler le rebase git
$ git rebase -i HEAD~2
Pour réappliquer les deux derniers commits. La commande ci-dessus ouvrira un éditeur de code
Après: wq vous serez en mode rebase actif
Remarque : vous obtiendrez un autre éditeur si aucun message d'avertissement / d'erreur, s'il y a une erreur ou un avertissement, un autre éditeur ne s'affichera pas, vous pouvez abandonner en exécutant
$ git rebase --abort
si vous voyez une erreur ou un avertissement, continuez simplement en exécutant$ git rebase --continue
Vous verrez votre 2 message de validation. Choisissez-en un ou écrivez votre propre message de validation, enregistrez et quittez [: wq]
Remarque 2: vous devrez peut-être forcer l'envoi de vos modifications au référentiel distant si vous exécutez la commande rebase
$ git push -f
$ git push -f origin master
la source
git push -f origin/master
c'est ce qui manque d'autres réponses. +1Depuis que j'utilise
git cherry-pick
pour à peu près tout, pour moi, il est naturel de le faire même ici.Étant donné que j'ai
branchX
vérifié et qu'il y a deux commits à la fin, dont je veux créer un commit combinant leur contenu, je fais ceci:Si je veux également mettre à jour
branchX
(et je suppose que c'est le côté négatif de cette méthode), je dois également:la source
Si votre branche principale
git log
ressemble à ceci:et vous souhaitez fusionner les deux premiers validations, procédez simplement comme suit:
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e
. (Résolvez les conflits le cas échéant)git commit --amend
.C'est ça. Vous pouvez pousser cette version fusionnée dans la branche "merged-commits" si vous le souhaitez.
De plus, vous pouvez maintenant ignorer les deux validations consécutives dans votre branche principale. Mettez simplement à jour votre branche principale en tant que:
la source
Si vous souhaitez combiner les deux validations les plus récentes et utiliser simplement le message de la validation la plus ancienne, vous pouvez automatiser le processus à l'aide de
expect
.Je suppose:
J'ai testé avec
git version 2.14.3 (Apple Git-98)
.la source
expect
non décrit.expect
.