Git pour les utilisateurs de Perforce

J’utilise Perforce depuis plusieurs années. Je voudrais passer à l’utilisation de git pour mon code personnel, mais tous les tutoriels git que j’ai vus supposent que vous êtes un contrôle de source complet n00b (ce qui les rend incroyablement fastidieux) ou que vous avez l’habitude svn (ce que je ne suis pas).

Je sais que p4, et je comprends également l’idée derrière un système de contrôle de source dissortingbué (donc je n’ai pas besoin d’un argument de vente, merci). Ce que je voudrais, c’est une table de traduction de la commande p4 aux commandes git équivalentes, ainsi que les commandes “ne peut pas vivre sans” sans équivalent p4.

Comme je soupçonne que chaque utilisateur de p4 utilise un sous-ensemble différent de p4, voici certaines des choses que je fais régulièrement dans p4 que je voudrais pouvoir faire dans git et qui ne sont pas évidentes dans les documents que j’ai consultés. :

  1. créer plusieurs listes de modifications en attente dans un seul client. ( p4 change )
  2. éditer une liste de modifications en attente. (aussi p4 change )
  3. voir une liste de toutes mes listes de p4 changes -s pending ( p4 changes -s pending )
  4. liste de tous les fichiers modifiés dans mon client ( p4 opened ) ou dans une liste de modifications en attente ( p4 describe )
  5. voir un diff d’une liste de modifications en attente (j’utilise un script wrapper pour cela qui utilise p4 diff et p4 describe )
  6. pour un fichier donné, voir quelles listes de modifications soumises ont affecté les lignes ( p4 annotate )
  7. pour un fichier donné, voir la liste des descriptions des listes de modifications qui ont affecté le fichier ( p4 log )
  8. soumettre une liste de modifications en attente ( p4 submit -c )
  9. annuler une liste de modifications en attente ( p4 revert )

Beaucoup d’entre eux tournent autour des “listes de modifications”. “liste de modifications” est la terminologie p4. Quel est le terme équivalent git?

Il semble que les twigs puissent être ce que les utilisateurs de git utilisent à la place de ce que p4 appelle les listes de modifications. Un peu déroutant, puisque p4 a aussi quelque chose qui s’appelle une twig mais qui ne semble être que des concepts vaguement liés. (Bien que j’ai toujours pensé que le concept de twig de p4 était assez étrange, il est encore différent du concept classique de RCS d’une twig.)

Quoi qu’il en soit … je ne sais pas comment accomplir ce que je fais normalement dans les listes de modifications p4 avec les twigs de git. En p4, je peux faire quelque chose comme ceci:

 $ p4 edit a.txt $ p4 change a.txt Change 12345 created. 

À ce stade, j’ai un changlist qui contient un fichier .txt. Je peux éditer la description et continuer à travailler sans soumettre la liste de modifications. Aussi, s’il s’avère que je dois apporter des modifications à d’autres fichiers, comme un correctif dans une autre couche du code, je peux le faire dans le même client:

 $ p4 edit z.txt $ p4 change z.txt Change 12346 created. 

Maintenant, j’ai deux listes de modifications distinctes dans le même client. Je peux travailler sur ceux-ci en même temps, et je n’ai rien à faire pour les “basculer”. Quand vient le temps de s’engager, je peux les soumettre séparément:

 $ p4 submit -c 12346 # this will submit the changes to z.txt $ p4 submit -c 12345 # this will submit the changes to a.txt 

Je n’arrive pas à comprendre comment reproduire cela en git. D’après mes expériences, il ne semble pas que git add soit associé à la twig en cours. Autant que je sache, quand je git commit il va commettre tous les fichiers que j’ai git add quelle que soit la twig dans laquelle j’étais à ce moment-là:

 $ git init Initialized empty Git repository in /home/laurence/git-playground/.git/ $ ls a.txt w.txt z.txt $ git add -A . $ git commit Initial commit. 3 files changed, 3 insertions(+), 0 deletions(-) create mode 100644 a.txt create mode 100644 w.txt create mode 100644 z.txt $ vi a.txt z.txt 2 files to edit $ git status # On branch master # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: a.txt # modified: z.txt # no changes added to commit (use "git add" and/or "git commit -a") $ git branch aardvark $ git checkout aardvark M a.txt M z.txt Switched to branch 'aardvark' $ git add a.txt $ git checkout master M a.txt M z.txt Switched to branch 'master' $ git branch zebra $ git checkout zebra M a.txt M z.txt Switched to branch 'zebra' $ git add z.txt $ git status # On branch zebra # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # modified: a.txt # modified: z.txt # $ git checkout aardvark M a.txt M z.txt Switched to branch 'aardvark' $ git status # On branch aardvark # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # modified: a.txt # modified: z.txt 

Dans cet exemple, les twigs aardvark et zebra semblent contenir exactement le même ensemble de modifications, et en fonction de la sortie du git status il semble que faire une validation dans l’un ou l’autre aura le même effet. Est-ce que je fais quelque chose de mal?

    Je n’ai pas trop utilisé perforce, donc ce n’est peut-être pas exactement une traduction 1: 1. Là encore, les systèmes de contrôle des sources dissortingbuées tels que git et mercurial ont un workflow différent de toute façon, donc il n’y en a pas vraiment (et il ne devrait pas y en avoir) une traduction 1: 1. En tout cas, voici:

    • Créez plusieurs listes de modifications en attente -> Utilisez plutôt des twigs. Dans git twigs sont légers et rapides, prend moins d’une seconde à créer et généralement moins de deux secondes pour fusionner. N’ayez pas peur de la ramification et de la rebase souvent.

       git branch new-branch-name git checkout new-branch-name 

      Ou tout faire en une seule ligne:

       git checkout -b new-branch-name 
    • Voir une liste de toutes les listes de modifications en attente -> L’équivalent de plusieurs listes de modifications en attente étant constitué de plusieurs twigs, affichez simplement les twigs:

       git branch 

      Si vous souhaitez également afficher les twigs distantes:

       git branch -a 

      Il est conseillé de supprimer immédiatement une twig après une fusion réussie afin de ne pas avoir à suivre la twig en attente de fusion et celles qui ont déjà été fusionnées.

    • Lister tous les fichiers modifiés -> Pour une seule “liste de modifications” en attente dans une twig spécifique, git a un concept d’index ou de cache. Pour commettre une modification, vous devez d’abord append des fichiers à cet index. Cela vous permet de sélectionner manuellement le groupe de fichiers représentant un seul changement ou d’ignorer les fichiers non pertinents. Pour voir le statut des fichiers ajoutés ou non à cet index, procédez comme suit:

       git status 
    • Voir un diff d’une liste de modifications en attente -> Il y a deux parties à cela. D’abord pour voir un diff entre le répertoire de travail et l’index:

       git diff 

      Mais si vous voulez connaître la différence entre ce que vous tapez maintenant et le dernier commit, vous demandez vraiment un diff entre le répertoire de travail + index et le HEAD:

       git diff HEAD 
    • Pour un fichier donné, voir les listes de modifications soumises qui ont affecté les lignes -> C’est facile:

       git blame filename 

      ou même mieux si vous êtes dans un environnement sinueux:

       git gui blame filename 

      Git gui prend plus de temps pour parsingr le fichier (il a été écrit en tcl au lieu de C) mais il a beaucoup de fonctionnalités intéressantes, y compris la possibilité de “voyager dans le temps” en cliquant sur un identifiant de validation. Je souhaite seulement qu’ils implémentent une fonctionnalité pour “voyager dans le temps” à l’avenir afin que je puisse découvrir comment un bug donné sera finalement résolu 😉

    • Pour un fichier donné, consultez la liste des descriptions des listes de modifications qui ont affecté le fichier -> aussi facile:

       git log filename 

      Mais git log est un outil beaucoup plus puissant que cela. En fait, la plupart de mes scripts personnels utilisent des journaux hors connexion pour lire le référentiel. Lisez la page de manuel.

    • Soumettre une liste de modifications en attente -> Aussi facile:

       git commit 

    Voir ma réponse à une question précédente pour voir mon stream de travail typique de git: Learning Git. Besoin de savoir si je suis sur la bonne voie

    Si vous suivez le workflow que j’ai décrit, vous trouverez que des outils tels que gitk ont ​​beaucoup plus de valeur, car ils vous permettent de voir clairement les groupes de modifications.


    Réponse supplémentaire:

    Git est très flexible et il y a plusieurs façons de faire ce que vous décrivez. La chose à retenir est de toujours démarrer une nouvelle twig pour chaque fonctionnalité sur laquelle vous travaillez. Cela signifie que la twig principale n’est pas touchée, vous pouvez donc toujours y revenir pour faire des corrections de bogues. Travailler dans git one devrait presque toujours commencer par:

     git checkout -b new-feature-a 

    Maintenant, vous pouvez éditer le fichier a.txt. Pour travailler simultanément sur une autre fonctionnalité:

     git checkout master git checkout -b new-feature-z 

    Vous pouvez maintenant modifier le fichier z.txt. Pour revenir à a.txt:

     git checkout new-feature-a 

    Mais attendez, il y a des changements à new-feature-z et git ne vous laissera pas changer de twig. À ce stade, vous avez deux choix. Le premier est le plus simple, commet toutes les modifications sur la twig en cours:

     git add . git commit git checkout new-feature-a 

    C’est ce que je recommande. Mais si vous n’êtes pas vraiment prêt à valider le code, vous pouvez le ranger temporairement:

     git stash 

    Maintenant, vous pouvez passer à la twig new-feature-a. Pour revenir au code sur lequel vous travailliez, ouvrez le cache:

     git checkout new-feature-z git stash pop 

    Lorsque tout est terminé, fusionnez toutes les modifications apscopes à master:

     git merge --no-ff new-feature-a git merge --no-ff new-feature-z 

    Parce que les fusions sont si simples et rapides (faciles parce que les conflits sont si rares et la résolution des conflits, quand cela arrive, pas trop difficile), nous utilisons des twigs dans git pour tout.

    Voici un autre exemple d’utilisation courante de twigs dans git que vous ne voyez pas dans d’autres outils de contrôle de source (sauf peut-être mercurial):

    Besoin de continuer à changer vos fichiers de configuration pour refléter votre environnement de développement? Ensuite, utilisez une twig:

     git checkout -b dev-config 

    Maintenant, éditez vos fichiers de configuration dans votre éditeur favori puis validez les modifications:

     git add . git commit 

    Maintenant, chaque nouvelle twig peut commencer à partir de la twig dev-config au lieu de master:

     git checkout dev-config git checkout -b new-feature-branch 

    Une fois que vous avez terminé, supprimez les modifications de dev-config de la twig nouveauté en utilisant le rebase interactif:

     git rebase -i master 

    Supprimez les commits que vous ne voulez pas, puis enregistrez. Maintenant, vous avez une twig propre sans modifications de configuration personnalisées. Temps de fusion pour maîsortingser:

     git checkout master git merge --no-ff new-feature-branch # because master have changed, it's a good idea to rebase dev-config: git checkout dev-config git rebase master 

    Il convient de noter que la suppression des modifications avec git rebase -i fonctionne même lorsque toutes les modifications se produisent dans le même fichier. Git se souvient des changements, pas du contenu des fichiers *.

    * note: en réalité, techniquement pas tout à fait vrai mais en tant qu’utilisateur, c’est ce que l’on ressent


    Plus de réponse supplémentaire:

    Donc, d’après vous, il semble que vous vouliez que deux twigs existent simultanément, vous pouvez donc tester le fonctionnement du code combiné. Eh bien, c’est un bon moyen d’illustrer la puissance et la flexibilité des twigs.

    Tout d’abord, un mot sur l’implication de l’historique de twigment et modifiable bon marché sur votre stream de travail. Lorsque j’utilisais CVS et SVN, j’étais toujours un peu réticent à s’engager. Cela est dû au fait que le fait d’engager un code instable entraînerait inévitablement une dégradation du code de travail des autres. Mais avec git j’ai perdu cette peur. C’est parce que d’autres personnes n’obtiendront pas mes modifications jusqu’à ce que je les fusionne pour les maîsortingser. Alors maintenant, je me retrouve à écrire du code toutes les 5 lignes que j’écris. Vous n’avez pas besoin de prévoyance parfaite pour vous engager. Vous avez juste besoin de changer votre état d’esprit: commit-to-branch == add-to-changeset, fusion-to-master == commit-changeset.

    Donc, retour aux exemples. Voici comment je le ferais. Disons que vous avez une twig new-feature-z et que vous voulez la tester avec new-feature-a . Je voudrais juste créer une nouvelle twig pour le tester:

     # assume we are currently in branch new-feature-z # branch off this branch for testing git checkout -b feature-z-and-feature-a # now temporarily merge new-feature-a git merge --no-ff new-feature-a 

    Maintenant, vous pouvez tester. Si vous devez modifier quelque chose pour que feature-z fonctionne avec feature-a, faites-le. Dans ce cas, vous pouvez fusionner les modifications apscopes à la twig concernée. Utilisez git rebase -i pour supprimer les modifications non pertinentes de la fusion.

    Alternativement, vous pouvez également utiliser git rebase pour changer temporairement la base de new-feature-z pour pointer vers new-feature-a:

     # assume we are currently in branch new-feature-z git rebase new-feature-a 

    Maintenant, l’historique des twigs est modifié pour que new-feature-z soit basé sur new-feature-a au lieu de master. Maintenant, vous pouvez tester. Toute modification commise dans cette twig appartiendra à la twig new-feature-z. Si vous avez besoin de modifier new-feature-a, il suffit de le modifier et de le rebaser pour obtenir les nouvelles modifications:

     git checkout new-feature-a # edit code, add, commit etc.. git checkout new-feature-z git rebase new-feature-a # now new-feature-z will contain new changes from new-feature-a 

    Une fois que vous avez terminé, il vous suffit de redéfinir le mode maître pour supprimer les modifications de la nouvelle fonctionnalité:

     # assume we are currently in branch new-feature-z git rebase master 

    N’ayez pas peur de créer une nouvelle succursale. N’ayez pas peur de créer une twig jetable. N’ayez pas peur de jeter des twigs. Et depuis la fusion == submit et commit == add-to-changeset, n’ayez pas peur de vous engager souvent. Rappelez-vous que commit est l’outil ultime de développement d’un développeur.

    Oh, et autre chose, dans git les twigs supprimées existent toujours dans votre repository. Donc, si vous avez accidentellement supprimé quelque chose que vous réalisez par la suite est utile après tout, vous pouvez toujours le récupérer en effectuant une recherche dans l’historique. Alors n’ayez pas peur de jeter des twigs.

    Je n’ai pas assez d’expérience en p4 pour produire une feuille de sortingche réelle, mais il y a au moins quelques similitudes sur lesquelles se baser. Un p4 “changeset” est un “commit” git.

    Les modifications apscopes à votre espace de travail local sont ajoutées à “index” avec git add , et l’index est ensuite activé avec git commit . Donc, l’index est votre liste de modifications en attente, à toutes fins utiles.

    Vous examinez les modifications avec git diff et git status , où git diff affiche généralement les changements entre l’espace de travail et l’index, mais git diff --cached affiche les changements entre l’index et le référentiel (= votre git diff --cached modifications en attente).

    Pour plus d’informations détaillées, je recommande http://progit.org/book/ . Comme vous connaissez le contrôle de version en général, vous pouvez probablement en parcourir beaucoup et extraire les informations spécifiques à git …

    Je souffre comme vous de l’absence du concept de “liste de modifications” qui n’est pas exactement le même que celui de git twigs.

    Je voudrais écrire un petit script qui va créer un fichier de liste de modifications avec la liste des fichiers de cette liste de modifications.

    Une autre commande pour ne soumettre qu’une liste de modifications en appelant simplement git commit -a @ change_list_contents.txt puis “git commit”

    Espérons que ça aide, Elias

    Il existe une alternative plus légère dans git qui pourrait faire partie de votre stream de travail; en utilisant la zone de transit git.

    Je fais souvent des modifications, puis soumets-les en plusieurs commits (par exemple, append des instructions de débogage, refactoriser, corriger un bogue). Plutôt que de configurer vos listes de modifications perforce, apportez des modifications, puis soumettez, vous pouvez simplement apporter vos modifications, puis choisir comment les soumettre (en utilisant éventuellement la zone de transit git).

    Vous pouvez valider des fichiers particuliers à partir de la ligne de commande avec:

     git commit a.txt git commit z.txt 

    Ou mettre en place explicitement les fichiers en premier:

     git add a.txt git commit git add z.txt git commit 

    git gui vous permettra de sélectionner des lignes ou des morceaux à partir de fichiers pour créer un commit dans la zone de transfert. Ceci est très utile si vous avez des modifications dans un fichier que vous souhaitez inclure dans différents commits. Je suis passé de git à perforce et c’est une chose qui me manque vraiment.

    Il y a une petite mise en garde à garder à l’esprit avec ce stream de travail. Si vous apportez des modifications à A et B dans un fichier, testez le fichier, puis validez A puis vous n’avez pas testé cette validation (indépendamment de B).

    Cela ne répond pas spécifiquement à votre question, mais je ne sais pas si vous savez que la version de perforce à 2 utilisateurs, 5 Workspace est téléchargeable et utilisable gratuitement à partir du site Web de perforce .

    De cette façon, vous pouvez utiliser perforce à la maison pour vos projets personnels si vous le souhaitez. Le seul inconvénient, ce sont les 5 espaces de travail, ce qui peut être un peu limitant, mais c’est vraiment incroyable d’avoir des forforce disponibles pour un usage domestique.

    Ayant utilisé à la fois Perforce et git de manière assez extensive, il n’y a qu’une seule façon de voir les listes de modifications de Perforce avec git.

    La première chose à comprendre est que l’implémentation correcte de cette fonctionnalité dans git de manière à ce qu’elle ne soit pas complète, par exemple en essayant de l’intégrer dans des twigs, nécessiterait la modification suivante: git nécessiterait plusieurs zones de transit pour une seule twig .

    Les listes de modifications Perforce permettent un stream de travail qui n’a simplement pas d’équivalent dans git. Envisagez le workflow suivant:

     Check out a branch Modify file A and add it to changelist 1 Modify file B and add it to changelist 2 

    Si vous essayez de le faire en utilisant des twigs dans git, vous vous retrouverez avec deux twigs, l’une contenant les modifications apscopes au fichier A , l’autre avec les modifications apscopes au fichier B , mais aucun endroit où afficher les modifications apscopes aux deux fichiers. A et B en même temps.

    L’approximation la plus proche que je puisse voir est d’utiliser git add . -p git add . -p puis utilisez les sous-commandes 'a' et 'd' pour sélectionner ou rejeter des fichiers entiers. Cependant, ce n’est pas tout à fait la même chose et la différence provient d’une disparité fondamentale dans le mode opératoire général des deux systèmes.

    Git (et la subversion, peu importe qu’il s’agisse de cette discussion) permettent à un fichier d’être modifié sans en informer personne à l’avance. Vous modifiez simplement un fichier, puis laissez git régler le tout lorsque vous validez les modifications. Perforce exige que vous vérifiiez activement un fichier avant que les modifications ne soient autorisées, et c’est pour cette raison que les listes de modifications doivent exister. Pour l’essentiel, Perforce exige que vous ajoutiez un fichier à l’index avant de le modifier. D’où la nécessité de multiples listes de modifications dans Perforce, et aussi la raison pour laquelle git n’a pas d’équivalent. Il n’en a tout simplement pas besoin.