J'ai une paire de commits qui ne devraient vraiment en être qu'un. Si j'utilisais git, j'utiliserais:
git rebase -i <some-commit-before>
puis écrasez-les.
Puis-je faire ça dans Mercurial? Si c'est le cas, comment?
J'ai une paire de commits qui ne devraient vraiment en être qu'un. Si j'utilisais git, j'utiliserais:
git rebase -i <some-commit-before>
puis écrasez-les.
Puis-je faire ça dans Mercurial? Si c'est le cas, comment?
Réponses:
Oui, vous pouvez le faire en utilisant mercurial sans aucune extension en concaténant les ensembles de modifications .
Alternativement, si vous souhaitez utiliser une extension, vous pouvez utiliser:
Mon préféré est la hg strip --keep
commande. Et puis je valide tous les changements en un seul commit.
C'est le moyen le plus rapide et le plus confortable pour moi, car j'aime faire de nombreux petits engagements au cours de mon travail quotidien;)
Remarque 1: strip
nécessite une extension intégrée mq
pour être activée.
Remarque 2: Mon client Git / Mercurial préféré (SmartGit / Hg) ajoute par défaut un --keep
paramètre pendant strip
. Et ce qui est encore plus pratique: il propose une option appelée join commits
:]
hg strip --keep --rev [rev]
Où rev
est le numéro de révision du premier commit que vous voulez écraser avec le dernier
--rev
est facultatif, la commande complète esthg strip --keep [rev]
hg help strip
donne hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...
, et omettre la révision me donne abort: empty revision set
.
hg strip
n'est pas la meilleure idée. Ce n'est pas vraiment sûr. Essayez hg histedit
, peut-être même essayez d'utiliser l'extension evolve.
L' extension Rebase a fonctionné comme un charme. Pour écraser 2 commits:
$ hg rebase --dest .~2 --base . --collapse
Le point est un raccourci pour la révision actuelle.
C'est encore plus facile lorsque vous avez quelques commits sur une branche et que vous souhaitez les réduire en un seul:
$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse
Comment ça marche:
(à partir de http://mercurial-scm.org/wiki/RebaseExtension#Collapsing )
Si vous lisez cette réponse, vous pouvez oublier toutes les autres options mentionnées dans cette réponse et utiliser la
fold
commande de l' extension evolve .
evolve
est une extension de mercurial qui nous aide à avoir une histoire mutable sûre, mais elle est encore expérimentale. Vous pouvez l'utiliser en le clonant à partir de son dépôt et en l'ajoutant dans votre .hgrc comme ceci.
[extensions]
evolve = ~/evolve/hgext/evolve.py
En supposant que vous avez cloné le dépôt évolutif dans votre répertoire personnel. Maintenant, vous êtes prêt à partir. Vous pouvez également rechercher de l'aide par hg help fold
.
Vous dites fold
d'écraser / plier une chaîne linéaire de commits qui n'est pas interrompue. Ce que fait fold, c'est qu'il crée un nouvel ensemble de modifications qui contient les modifications de tous les ensembles de modifications et marque toutes ces validations comme obsolètes. Vous pouvez avoir une vue plus approfondie de cela dans docs .
Supposons maintenant que vous ayez l'historique suivant.
a -> b -> c -> d -> e -> f -> g
Vous voulez écraser e
, f
et g
. Tu peux faire
hg up g
hg fold -r e
Le résultat sera
a -> b -> c -> d -> h
où h
est l'ensemble de modifications contenant les modifications des trois validations e
, f
et g
.
Vous pouvez également plier les changesets à partir du milieu de l'historique, c'est-à-dire que vous ne devez pas nécessairement choisir une chaîne qui inclut la pointe. Supposons que vous vouliez plier b
, c
et d
. Tu peux faire
hg up d
hg fold -r b
hg evolve --all
Cela entraînera
a -> i -> j
où i
est pliée de l' ensemble de modifications b
, c
, d
et j
est le même que ChangeSet h
.
Le guide de l'utilisateur Evolve est une lecture incontournable.
--keep
option de rebase couvre cela (suivi en marquant les révisions comme secrètes, ou en utilisant une bande dessus une fois que vous avez vérifié le résultat). Même déplacer des révisions entre d'autres révisions est possible avec une séquence de deux commandes de rebase.
Avec Mercurial 4.8 (novembre 2018, 9 ans plus tard), vous pouviez envisager la nouvelle commande hg absorb
(c'était une fonctionnalité expérimentale auparavant ).
Voir " Absorption des changements de validation dans Mercurial 4.8 "
L'extension absorber prendra chaque changement dans votre répertoire de travail, déterminera quels commits de votre série ont modifié cette ligne et modifieront automatiquement le changement de ce commit.
S'il y a une ambiguïté (c'est-à-dire que plusieurs commits ont été modifiés sur la même ligne), absorber ignorera simplement ce changement et le laissera dans votre répertoire de travail pour qu'il soit résolu manuellement.Au niveau technique,
hg absorb
trouve toutes les modifications non validées et tente de mapper chaque ligne modifiée à une validation antérieure sans ambiguïté.
Pour chaque modification qui peut être mappée proprement, les modifications non validées sont absorbées dans la validation antérieure appropriée. Les validations affectées par l'opération sont rebasées automatiquement.
Si une modification ne peut pas être mappée à une validation antérieure sans ambiguïté, elle n'est pas validée et les utilisateurs peuvent revenir à un flux de travail existant (par exemple en utilisanthg histedit
).La logique de réécriture automatique de
hg absorb
est implémentée en suivant l'historique des lignes: Ceci est fondamentalement différent de l'approche adoptée parhg histedit
ougit rebase
, qui a tendance à s'appuyer sur des stratégies de fusion basées sur la fusion à 3 voies pour dériver une nouvelle version d'un fichier avec plusieurs entrées versions.Cette approche combinée au fait que hg absorbe saute les changements avec un commit d'application ambigu signifie que hg absorbe ne rencontrera jamais de conflits de fusion!
Maintenant, vous pensez peut-être que si vous ignorez les lignes avec des cibles d'application ambiguës, le correctif s'appliquerait toujours proprement en utilisant une fusion à 3 voies classique. Cette déclaration semble logiquement correcte. Mais ce n'est pas le cas:
hg absorb
peut éviter les conflits de fusion lorsque la fusion est effectuéehg histedit
ougit rebase -i
échoue.
Je pense que chistedit
(intégré depuis Mercurial 2.3) est le plus proche de rebase -i
celui qui est purement Mercurial ( chistedit
est la version interactive de histedit
). Une fois dans histedit, la fold
commande correspond aux rebases squash
et les roll
commandes aux rebases fixup
. Consultez la documentation histedit pour plus d'informations.
Voici un exemple simple. Supposons que vous ayez les éléments suivants et que vous souhaitiez déplacer toutes les modifications de 1e21c4b1 dans la révision précédente tout en conservant le message de la révision précédente.
@ 1e21c4b1 drees tip
| A commit you want to squash
o b4a738a4 drees
| A commit
o 788aa028 drees
| Older stuff
Vous pouvez exécuter hg chistedit -r b4a738a4
pour modifier l'historique vers b4a738a4. Dans chistedit, vous passez ensuite le curseur sur 1e21c4b1 et appuyez sur r
pour indiquer que vous souhaitez lancer cette révision. Notez que l'ordre dans histedit (du plus ancien au plus récent) est inversé de hg log
(du plus récent au plus ancien).
#0 pick 160:b4a738a49916 A commit
#1 ^roll 161:1e21c4b1500c
Après avoir choisi vos modifications, vous choisissez c
de les valider. Le résultat est le suivant:
@ bfa4a3be drees pointe | Un engagement o 788aa028 drees | Trucs plus anciens
Si vous êtes relativement nouveau pour eux, alors histedit
peut être un meilleur choix que chistedit
parce qu'il fournit les descriptions de commande dans le fichier histedit pour référence. Il faut juste un peu plus d'édition pour définir les commandes en utilisant l'édition de texte normale (tout comme le rebase normal).
Remarque, pour utiliser l'un histedit
ou l' autre ou chistedit
vous devez ajouter histedit
à vos extensions dans votre ~ / .hgrc:
[extensions]
histedit =
J'ai suggéré chistedit
car il est le plus proche rebase -i
et fonctionne n'importe où dans l'histoire. Si vous voulez vraiment simplement subsumer / modifier la révision actuelle dans la précédente, alors @G. La strip
suggestion de Demecki peut être bonne car ce qui se passe est clair. Il est intégré depuis Mercuria 2.8. Pour obtenir les résultats équivalents ci-dessus, vous pouvez effectuer les opérations suivantes:
hg strip .
hg add
hg commit --amend
Remarque strip
, comme histedit, doit être activé dans votre ~ / .hgrc:
[extensions]
strip =
Supposons que vous vouliez écraser (unir) les 2 derniers commits.
Trouver un numéro de révision
hg log -G -l 3
sortie possible:
@ changeset: 156:a922d923cf6f
| branch: default
| tag: tip
| user: naXa!
| date: Thu Dec 13 15:45:58 2018 +0300
| summary: commit message 3
|
o changeset: 155:5feb73422486
| branch: default
| user: naXa!
| date: Thu Dec 13 15:22:15 2018 +0300
| summary: commit message 2
|
o changeset: 154:2e490482bd75
| branch: default
~ user: naXa!
date: Thu Dec 13 03:28:27 2018 +0300
summary: commit message 1
Branche de réinitialisation logicielle
hg strip --keep -r 155
Valider à nouveau les modifications
hg commit -m "new commit message"
strip
nécessite une extension intégrée pour être activée. Créez / modifiez le ~/.hgrc
fichier de configuration avec le contenu suivant:
[extensions]
strip =