git reset
est une question de déménagement HEAD
, et généralement la branche ref .
Question: qu'en est-il de l'arbre de travail et de l'index?
Lorsqu'il est employé avec --soft
, se déplace HEAD
, le plus souvent en mettant à jour la référence de la branche, et seulement leHEAD
.
Cela diffère de commit --amend
:
- cela ne crée pas de nouveau commit.
- il peut en fait déplacer HEAD vers n'importe quel commit (comme il
commit --amend
ne s'agit que de ne pas déplacer HEAD, tout en permettant de refaire le commit actuel)
Je viens de trouver cet exemple de combinaison:
- une fusion classique
- une fusion de sous-arbres
tout en un (octopus, car il y a plus de deux branches fusionnées) commit merge.
Tomas "wereHamster" explique Carnecky dans son article "Subtree Octopus merge" :
- La stratégie de fusion de sous-arborescence peut être utilisée si vous souhaitez fusionner un projet dans un sous-répertoire d'un autre projet, puis maintenir le sous-projet à jour. C'est une alternative aux sous-modules git.
- La stratégie de fusion octopus peut être utilisée pour fusionner trois branches ou plus. La stratégie normale ne peut fusionner que deux branches et si vous essayez de fusionner plus que cela, git revient automatiquement à la stratégie octopus.
Le problème est que vous ne pouvez choisir qu'une seule stratégie. Mais je voulais combiner les deux afin d'obtenir un historique propre dans lequel tout le référentiel est mis à jour de manière atomique vers une nouvelle version.
J'ai un superprojet, appelons-le projectA
, et un sous-projet projectB
, que j'ai fusionné dans un sous-répertoire de projectA
.
(c'est la partie de fusion de sous-arborescence)
Je maintiens également quelques commits locaux.
ProjectA
est régulièrement mis à jour, projectB
a une nouvelle version tous les deux jours ou semaines et dépend généralement d'une version particulière de projectA
.
Lorsque je décide de mettre à jour les deux projets, je ne me contente pas de tirer sur projectA
et projectB
car cela créerait deux commits pour ce qui devrait être une mise à jour atomique de l'ensemble du projet .
Au lieu de cela, je crée un seul commit de fusion qui combine projectA
, projectB
et mes commits locaux .
La partie délicate ici est qu'il s'agit d'une fusion de poulpe (trois têtes), mais projectB
doit être fusionnée avec la stratégie de sous-arbre . Alors voici ce que je fais:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Ici, l'auteur a utilisé a reset --hard
, puis read-tree
pour restaurer ce que les deux premières fusions avaient fait à l'arbre de travail et à l'index, mais c'est là que cela reset --soft
peut aider:
Comment refaire ces deux fusions , qui ont fonctionné, c'est-à-dire que mon arbre de travail et mon index sont bien, mais sans avoir à enregistrer ces deux commits?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Maintenant, nous pouvons reprendre la solution de Tomas:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Donc, à chaque fois:
- vous êtes satisfait de ce que vous obtenez (en terme d'arborescence de travail et d'index)
- vous n'êtes pas satisfait de tous les commits qui vous ont amenés à y arriver:
git reset --soft
Est la réponse.
git reset --soft
: stackoverflow.com/questions/6869705