Comment créer la branche à partir d'un commit spécifique dans une branche différente

102

J'ai fait plusieurs commits dans la branche master, puis les ai fusionnés dans la branche dev.

Je veux créer une branche à partir d'un commit spécifique dans la branche dev, qui a d'abord été commis dans la branche master.

J'ai utilisé les commandes:

git checkout dev
git branch  <branch name> <commit id>

Cependant, cela crée la branche à partir de la branche master, pas la branche de développement que je m'attendais. L'ID de validation est le même dans la branche master et la branche dev. Alors, comment puis-je distinguer le même identifiant de validation dans une branche différente?

PS: j'ai fait un exemple dans github ici https://github.com/RolandXu/test_for_branch

J'ai utilisé les commandes:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Ce que j'attends, c'est que la branche de test contienne aa.txt bb.txt cc.txt. Cependant, la branche test ne contient que aa.txt et cc.txt. Il a très probablement créé la branche à partir de la branche principale.

RolandXu
la source

Réponses:

145

Si vous utilisez cette forme de branchcommande (avec point de départ), peu importe où vous vous trouvez HEAD.

Que fais tu:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Tout d'abord, vous définissez votre HEADsur la branche dev,

  • Deuxièmement, vous démarrez une nouvelle branche lors de la validation 07aeec98. Il n'y a pas de bb.txt à ce commit (selon votre dépôt github).

Si vous souhaitez démarrer une nouvelle branche à l'emplacement que vous venez d'extraire, vous pouvez exécuter une branche sans point de départ:

git branch test

ou comme d'autres ont répondu, branchez-vous et passez à la caisse en une seule opération:

git checkout -b test

Je pense que vous pourriez être dérouté par ce fait qui 07aeec98fait partie de la branche dev. Il est vrai que ce commit est un ancêtre de dev, ses changements sont nécessaires pour atteindre le dernier commit dans dev. Cependant, ce sont d'autres engagements qui sont nécessaires pour atteindre le dernier dev, et ceux-ci ne sont pas nécessairement dans l'histoire de 07aeec98.

8480e8ae(où vous avez ajouté bb.txt) n'est par exemple pas dans l'historique de 07aeec98. Si vous effectuez une branche depuis 07aeec98, vous n'obtiendrez pas les modifications apportées par 8480e8ae.

En d'autres termes: si vous fusionnez la branche A et la branche B dans la branche C, puis créez une nouvelle branche sur un commit de A, vous n'obtiendrez pas les changements introduits dans B.

Pareil ici, vous aviez deux branches parallèles master et dev, que vous avez fusionnées en dev. La dérivation d'un commit de master (plus ancien que la fusion) ne vous fournira pas les changements de dev.


Si vous souhaitez intégrer de manière permanente les nouvelles modifications du maître dans vos branches de fonctionnalités, vous devez les fusionner masteret continuer. Cela créera cependant des validations de fusion dans vos branches de fonctionnalités.

Si vous ne publiez pas vos branches de fonction, vous pouvez aussi les rebasage sur le maître mise à jour: git rebase master featureA. Soyez prêt à résoudre d'éventuels conflits.

Si vous voulez un flux de travail où vous pouvez travailler sur des branches de fonctionnalités sans commits de fusion et toujours intégrer avec les modifications plus récentes dans master, je recommande ce qui suit:

  • baser chaque nouvelle branche de fonctionnalité sur un commit de master
  • créer une devbranche sur un commit de master
  • lorsque vous avez besoin de voir comment votre branche d'entités s'intègre aux nouvelles modifications dans le maître, fusionnez à la fois le maître et la branche d'entités dans dev.

Ne vous engagez pas devdirectement, utilisez-le uniquement pour fusionner d'autres branches.

Par exemple, si vous travaillez sur les fonctionnalités A et B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Fusionnez les branches dans une devbranche pour vérifier si elles fonctionnent bien avec le nouveau maître:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Vous pouvez continuer à travailler sur vos branches de fonctionnalités et continuer à fusionner devrégulièrement les nouvelles modifications des branches principales et des branches de fonctionnalités .

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Quand il est temps d'intégrer les nouvelles fonctionnalités, fusionnez les branches de fonctionnalités (pas dev!) Dans master.

Gauthier
la source
Merci. Vous répondez à ma question. Je me trompe dans la compréhension du mode de branche git. Et avez-vous des suggestions pour mon problème. J'ai la branche principale qui a de nombreux commits en temps opportun par d'autres (synchronisation avec forcément). J'ai une branche de développement et je fais un travail personnel. Je veux une branche qui contient tous les commits de la branche principale et de la branche de développement, puis je peux facilement créer une branche basée sur cette branche, puis commencer un travail spécifique.
RolandXu
Je n'ai pas pu répondre dans un commentaire, je mets donc à jour ma réponse avec les workflows suggérés.
Gauthier
Hé - merci pour la réponse brillante et approfondie! Juste curieux: En fin de compte, pourquoi devrait-on merge the feature branches (not dev!) into master?
cassi.lup
Il n'y a pas de véritable nouveau développement dans la devbranche. Vous devriez garder vos branches spécifiques. devcontient uniquement des validations de fusion. Il est plus logique de fusionner directement toutes les nouvelles fonctionnalités masterque de fusionner les fonctionnalités puis de fusionner le résultat dans master.
Gauthier
@Gauthier Vous n'avez pas abordé la question de savoir pourquoi. Pour moi, cela ressemble à fusionner un devavec juste des fonctionnalités A Bet à le Cfusionner en masterest identique à la fusion individuelle A Bet Cdans master. Sinon, cela remet en question ma compréhension du fonctionnement de git et je serais très curieux de savoir pourquoi!
Steven Lu
53

Vous avez les arguments dans le mauvais ordre:

git branch <branch-name> <commit>

et pour cela, peu importe quelle branche est extraite; ça fera ce que vous dites. (Si vous omettez l'argument de validation, il crée par défaut une branche au même endroit que la branche actuelle.)

Si vous souhaitez vérifier la nouvelle branche au fur et à mesure que vous la créez:

git checkout -b <branch> <commit>

avec le même comportement si vous omettez l'argument de validation.

Cascabel
la source
22

Vous pouvez le faire localement comme tout le monde l'a mentionné en utilisant

git checkout -b <branch-name> <sha1-of-commit>

Alternativement, vous pouvez le faire dans github lui-même, suivez les étapes:

1- Dans le référentiel, cliquez sur le Commits.

2- sur le commit à partir duquel vous souhaitez créer une branche, cliquez sur <>pour parcourir le référentiel à ce stade de l'historique.

commet l'histoire

3- Cliquez sur le tree: xxxxxxen haut à gauche. Tapez simplement un nouveau nom de branche ici, cliquez Create branch xxxcomme indiqué ci-dessous.

créer une nouvelle branche

Vous pouvez maintenant récupérer les modifications de cette branche localement et continuer à partir de là.

Muhammad Soliman
la source
C'est ce dont j'avais besoin .. Comment le faire sur le site web
eharo2
Je ne l'ai jamais su. Ça y est. Le truc GUI est tout simplement génial et je voulais être loin de CLI.
Rohit Gupta
10

Essayer

git checkout <commit hash>
git checkout -b new_branch

Le commit ne devrait exister qu'une seule fois dans votre arbre, pas dans deux branches séparées.

Cela vous permet de vérifier ce commit spécifique et de le nommer comme vous le souhaitez.

ZMorek
la source
salut j'essaye le git log dev et git log master, j'ai trouvé que l'ID de hachage de commit est le même pour le commit que je fusionne avec la branche dev de la branche master
RolandXu
il peut être utile d'utiliser quelque chose comme gitkpour visualiser votre journal
ZMorek
J'ai récemment ajouté un exemple dans github. Et Gauthier répond déjà à ma question que je comprends mal le mode git branch. Merci :)
RolandXu
C'est vraiment la réponse, je pense. Merci
virusss8
9

Tu dois faire:

git branch <branch_name> <commit>

(vous étiez en train d'échanger le nom de la branche et le commit)

Ou vous pouvez faire:

git checkout -b <branch_name> <commit>

Si à la place de vous utilisez le nom de la branche, vous obtenez une branche de la pointe de la branche.

manojlds
la source
Ce n'est pas ce que cela HEADveut dire. Vous pouvez dire «la pointe de la branche» ou «le commit vers lequel pointe la branche» à la place.
Cascabel
@Jefromi - Pour être puristes, nous pouvons dire que la branche uniquement, car la branche elle-même est un pointeur vers, eh bien, la pointe de la branche.
manojlds