web-dev-qa-db-fra.com

Quelle est la façon la plus simple de valider et de pousser un seul fichier tout en laissant les autres modifications seules?

Je suis relativement nouveau sur Mercurial et mon équipe est en train de l'essayer en remplacement de Subversion.

Comment puis-je valider et pousser un seul fichier vers un autre référentiel tout en laissant les autres modifications dans mon répertoire de travail non validées (ou du moins pas poussées vers l'autre référentiel)?

Cela se produit pour nous avec les migrations de bases de données. Nous voulons valider la migration vers le contrôle de source afin qu'un DBA puisse l'afficher et le modifier pendant que nous travaillons sur les modifications de code pour accompagner cette migration de la base de données. Les changements ne sont pas encore prêts à aller, nous ne voulons donc pas tous les repousser.

Dans Subversion, je ferais simplement:

svn add my_migration.sql  
# commit only the migration, but not the other files I'm working on
svn commit -m "migration notes" my_mygration.sql

et continuer à travailler localement.

Cela ne fonctionne pas avec Mercurial car lorsque je le transfère vers l'autre référentiel, s'il y a des modifications que je n'ai pas supprimées, il veut que je les supprime, les fusionne et valide cette fusion dans le référentiel. Les validations après une fusion ne vous permettent pas d'omettre des fichiers, ce qui vous oblige à tout valider dans votre référentiel local.

La chose la plus simple que je puisse comprendre est de valider le fichier dans mon référentiel local, de cloner mon référentiel local, de récupérer toutes les nouvelles modifications dans le référentiel réel, de les fusionner et de valider cette fusion, puis de les pousser sur mes modifications.

hg add my_migration.sql 
hg commit -m "migration notes" my_migration.sql 
cd ..
hg clone project project-clone
cd project-clone
hg fetch http://hg/project
hg Push  http://hg/project

Cela fonctionne, mais j'ai l'impression qu'il me manque quelque chose de plus facile, une façon de dire à Mercurial d'ignorer les fichiers déjà dans mon répertoire de travail, il suffit de faire la fusion et d'envoyer les fichiers. Je soupçonne que les files d'attente Mercurial peuvent le faire, mais je ne suis pas encore complètement mok.

72
Ted Naleid

Il existe une fonctionnalité Mercurial qui implémente les commandes de mise en veille et de retrait, qui vous offrent un moyen interactif de spécifier les modifications à stocker jusqu'à une date ultérieure: Shelve .

Ensuite vous pouvez hg shelve et hg unshelve pour stocker temporairement les modifications. Il vous permet de travailler au niveau du "morceau de patch" pour choisir les éléments à ranger. Il ne semblait pas y avoir un fichier répertorié pour l'ajout, seuls les fichiers déjà dans le dépôt avec des modifications.

Il est inclus avec Mercurial en tant qu '"extension" ce qui signifie simplement que vous devez l'activer dans votre fichier de configuration hg.


Notes pour les versions très anciennes de Mercurial (avant que la tablette ne soit incluse - ce n'est plus nécessaire):

Je n'ai pas vu de grandes instructions d'installation avec quelques recherches sur Google, alors voici les éléments combinés que j'ai utilisés pour le faire fonctionner:

Obtenez-le avec:

hg clone http://freehg.org/u/tksoh/hgshelve/ hgshelve

Le seul fichier (actuellement) dans le projet est le fichier hgshelve.py.

Modifiez votre ~/.hgrc pour ajouter l'extension Shelve, en indiquant l'endroit où vous avez cloné le référentiel:

[extensions] 
hgshelve=/Users/ted/Documents/workspace/hgshelve/hgshelve.py
31
Josh Matthews

Cela fait presque 2 ans que j'ai initialement posé cette question. Je le ferais différemment maintenant (comme je l'ai mentionné dans un commentaire au-dessus de la question ci-dessus). Ce que je ferais maintenant serait de valider à la place mes modifications dans le seul fichier de mon référentiel local (vous pouvez utiliser l'extension d'enregistrement hg pour ne valider que des parties d'un fichier):

hg commit -m "commit message" filename

Ensuite, poussez simplement.

hg Push

S'il y a un conflit parce que d'autres modifications ont été apportées au référentiel que je dois d'abord fusionner, je mettrais à jour la révision parent (vue avec "hg parents -r." Si vous ne savez pas ce que c'est), validez mes autres changements là-bas, donc j'ai 2 têtes. Revenez ensuite à la validation du fichier unique d'origine et tirez/fusionnez les modifications dans cette version. Poussez ensuite les modifications avec

hg Push --rev .

Pour pousser uniquement le fichier unique et la fusion de cette révision. Ensuite, vous pouvez fusionner les deux têtes que vous avez localement.

De cette façon, vous vous débarrassez de la substance mq et du potentiel de mecs rejetés et gardez tout suivi par le contrôle de source. Vous pouvez également "supprimer les révisions hg" si vous décidez plus tard que vous ne les voulez pas.

39
Ted Naleid

tl; dr: Mon explication d'origine semble compliquée, mais j'espère qu'elle explique pleinement comment utiliser une file d'attente de correctifs. Voici la version courte:

$ hg qnew -m "migration notes" -f migration my_migration.sql
$ hg qnew -f working-code
# make some changes to your code
$ hg qrefresh # update the patch with the changes you just made
$ hg qfinish -a # turn all the applied patches into normal hg commits

Mercurial Queues fait de ce genre de chose un jeu d'enfant et rend possible une manipulation plus complexe des changesets. Cela vaut la peine d'apprendre.

Dans cette situation, vous voudrez probablement d'abord enregistrer ce qui se trouve dans votre répertoire actuel avant de supprimer les modifications:

# create a patch called migration containing your migration
$ hg qnew -m "migration notes" -f migration.patch my_migration.sql
$ hg qseries -v # the current state of the patch queue, A means applied
0 A migration.patch
$ hg qnew -f working-code.patch # put the rest of the code in a patch
$ hg qseries -v
0 A migration.patch
1 A working-code.patch

Faisons maintenant un travail supplémentaire sur le code de travail. Je vais continuer à faire qseries juste pour être explicite, mais une fois que vous aurez construit un modèle mental de files d'attente de correctifs, vous n'aurez plus à regarder la liste.

$ hg qtop # show the patch we're currently editing
working-code.patch
$ ...hack, hack, hack...
$ hg diff # show the changes that have not been incorporated into the patch
blah, blah
$ hg qrefresh # update the patch with the changes you just made
$ hg qdiff # show the top patch's diff

Étant donné que tout votre travail est désormais enregistré dans la file d'attente des correctifs, vous pouvez annuler ces modifications et les restaurer après avoir récupéré les modifications à distance. Normalement, pour désappliquer tous les correctifs, faites simplement hg qpop -a. Juste pour montrer l'effet sur la file d'attente des correctifs, je les supprimerai un par un.

$ hg qpop # unapply the top patch, U means unapplied
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qtop
migration.patch
$ hg qpop
$ hg qseries -v
0 U migration.patch
1 U working-code.patch

À ce stade, c'est comme s'il n'y avait aucun changement dans votre répertoire. Faites le hg fetch. Vous pouvez maintenant repousser les modifications apportées à la file d'attente des correctifs et les fusionner en cas de conflit. Ceci est conceptuellement quelque peu similaire au rebase de git.

$ hg qpush # put the first patch back on
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qfinish -a # turn all the applied patches into normal hg commits
$ hg qseries -v
0 U working-code.patch
$ hg out
migration.patch commit info... blah, blah
$ hg Push # Push out your changes

À ce stade, vous avez repoussé la migration tout en conservant vos autres modifications locales. Vos autres modifications sont dans un patch dans la file d'attente. Je fais l'essentiel de mon développement personnel en utilisant une file d'attente de correctifs pour m'aider à mieux structurer mes modifications. Si vous voulez vous débarrasser de la file d'attente des correctifs et revenir à un style normal, vous devrez exporter vos modifications et les réimporter dans Mercurial "normal".

$ hg qpush
$ hg qseries -v
0 A working-code.patch
$ hg export qtip > temp.diff
$ rm -r .hg/patches # get rid of mq from the repository entirely
$ hg import --no-commit temp.diff # apply the changes to the working directory
$ rm temp.diff

Je suis extrêmement accro aux files d'attente de correctifs pour le développement et mq est l'une des plus belles implémentations du marché. La possibilité de créer plusieurs changements simultanément améliore vraiment la concentration et le nettoyage de vos commits. Il faut un certain temps pour s'y habituer, mais cela va incroyablement bien avec un flux de travail DVCS.

10
Kobold

Une autre option si vous ne voulez pas compter sur des extensions est de conserver localement un clone de votre référentiel en amont que vous n'utilisez que pour ce type de tâches d'intégration.

Dans votre exemple, vous pouvez simplement extraire/fusionner votre modification dans le référentiel d'intégration/amont et la pousser directement vers le serveur distant.

3
Derek Slager

Ce que j'utilise généralement, c'est de valider un seul fichier:

 hg commit -m "commit message" filename

Si, plus tard, j'ai un conflit de fusion et que je ne suis toujours pas prêt à valider mes modifications, procédez comme suit:

1) Créez un fichier patch.

hg diff > changes.patch

2) Annulez toutes vos modifications non validées en attente, uniquement après avoir vérifié votre fichier de correctif.

hg revert --all

3) Tirez, mettez à jour et fusionnez avec la dernière révision

hg pull -u
hg merge
hg commit -m "local merge"

4) Maintenant, importez simplement votre patch et obtenez vos modifications.

hg import --no-commit changes.patch

N'oubliez pas d'utiliser l'indicateur -no-commit de la validation automatique des modifications.

2
Shweta

Puisque vous avez dit plus simple, j'utilise souvent hg commit -i (--interactive) même lors de la validation de fichiers entiers. Avec --interactive vous pouvez simplement sélectionner le (s) fichier (s) souhaité (s) au lieu de taper leur chemin d'accès complet sur la ligne de commande. En prime, vous pouvez même sélectivement inclure/exclure des morceaux dans les fichiers.

Et puis juste hg Push pour pousser ce commit nouvellement créé.

Je mets plus de détails sur l'utilisation de hg commit --interactive dans cette réponse: https://stackoverflow.com/a/47931672/255961

1
studgeek