Question

Supposons que vous ayez un historique contenant les trois commits A, B et C :

A-B-C

Je souhaite combiner les deux commissions A et B en une validation AB :

AB-C

j'ai essayé

git rebase -i A

qui ouvre mon éditeur avec le contenu suivant:

pick e97a17b B
pick asd314f C

Je change ceci en

squash e97a17b B
pick asd314f C

Alors Git 1.6.0.4 dit:

Cannot 'squash' without a previous commit

Y at-il un moyen ou est-ce tout simplement impossible?

Était-ce utile?

La solution

Utilisez git rebase -i --root à partir de Git version 1.7.12 .

Dans le fichier de rebase interactif, remplacez la deuxième ligne de commit B par squash et laissez les autres lignes à pick :

pick f4202da A
squash bea708e B
pick a8c6abc C

Ceci combinera les deux commits A et B en un commit AB .

Trouvé dans cette réponse .

Autres conseils

Vous avez essayé:

git rebase -i A

Il est possible de commencer comme ça si vous continuez avec modifier plutôt que squash :

edit e97a17b B
pick asd314f C

puis exécutez

git reset --soft HEAD^
git commit --amend
git rebase --continue

Terminé.

Un était la validation initiale, mais vous souhaitez maintenant que B soit la validation initiale. Les commits git sont des arbres entiers, pas des diffs même s'ils sont normalement décrits et vus en fonction du diff qu'ils introduisent.

Cette recette fonctionne même s'il y a plusieurs validations entre A et B et entre B et C.

# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>

# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>

# amend the initial tree using the tree from 'B'
git commit --amend

# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>

# remove the temporary tag
git tag -d tmp

Dans le cas de rebase interactive, vous devez le faire avant A pour que la liste soit:

pick A
pick B
pick C

devenir:

pick A
squash B
pick C

Si A est le commit initial, vous devez avoir un commit initial différent avant que A. Git pense les différences, cela fonctionnera avec la différence entre (A et B) et (B et C). La courge ne fonctionne donc pas dans votre exemple.

Si vous avez des centaines ou des milliers de validations, utilisez la réponse de kostmo sur

.
git rebase -i --root

peut être peu pratique et lent, en raison du grand nombre de validations que le script de réabonnement doit traiter deux fois , une fois pour générer la liste interactive de l'éditeur de réabonnement (dans laquelle vous sélectionnez l'action à exécuter). chaque commit), et une fois pour exécuter réellement la nouvelle application des commits.

Voici une solution alternative qui vous évitera de perdre du temps à générer la liste des éditeurs de bases interactives en n'utilisant pas de base interactive . De cette manière, elle est similaire à la solution de Charles Bailey . Vous créez simplement une branche orpheline à partir du deuxième commit, puis vous rebasez tous les commits descendants:

git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master

Documentation

Dans une question connexe, j’ai réussi à proposer une approche différente en ce qui concerne la nécessité d’écraser le premier commit, c’est-à-dire en faire le deuxième.

Si cela vous intéresse: git: comment insérer un commit en premier, décalant tous les autres?

Commande Git pour l'équipe: git rebase -i HEAD ~ [nombre de commits]

Disons que vous avez ci-dessous l'historique des mises à jour de git:


pick 5152061 feat: Ajout du support pour l'enregistrement des images. (UNE)
pick 39c5a04 Fix: corrections de bugs. (B) Solution de réparation 839c6b3: résolution du conflit. (C)

Maintenant, vous voulez écraser A et B en AB, procédez comme suit:


pick 5152061 feat: Ajout du support pour l'enregistrement des images. (UNE)
s 39c5a04 Correctif: corrections de bugs. (B) Solution de réparation 839c6b3: résolution du conflit. (C)

Remarque: pour écraser les commandes, nous pouvons utiliser squash ou s. Le résultat final sera: Prise d'image 5152061: Ajout de la prise en charge de l'enregistrement des images. (UN B) Solution de réparation 839c6b3: résolution du conflit. (C)

Vous devez effectuer un peu de magie en ligne de commande.

git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a

Cela devrait vous laisser avec une branche qui a AB et C comme commits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top