Question Git branche, fourche, chercher, fusionner, rebaser et cloner, quelles sont les différences?


Quelqu'un peut-il m'aider à comprendre la différence entre une branche, une fourche et un clone dans Git?

De même, qu'est-ce que cela signifie quand je fais un git fetch par opposition à un git pull?

Aussi, qu'est-ce que rebase moyenne par rapport à merge?

Comment puis-je écraser les commits individuels ensemble?

Comment sont-ils utilisés, pourquoi sont-ils utilisés et que représentent-ils?

Comment intervient GitHub?


470
2017-07-25 16:14


origine


Réponses:


Un clone est simplement une copie d'un référentiel. En surface, son résultat est équivalent à svn checkout, où vous téléchargez le code source à partir d'un autre référentiel. La différence entre les VCS centralisés comme Subversion et les DVCS comme Git est que dans Git, lorsque vous clonez, vous copiez en fait tout le référentiel source, y compris l'historique et les branches. Vous avez maintenant un nouveau référentiel sur votre machine et tous les commits que vous faites vont dans ce dépôt. Personne ne verra de changement tant que vous n’aurez pas poussé ces commits vers un autre référentiel (ou l’original) ou jusqu’à ce que quelqu'un s’en tire de votre référentiel, s’il est accessible au public.

Une branche est quelque chose qui se trouve dans un référentiel. Conceptuellement, cela représente un fil de développement. Vous avez généralement une branche principale, mais vous pouvez également avoir une branche sur laquelle vous travaillez sur certaines fonctionnalités xyz, et une autre pour corriger le bogue abc. Lorsque vous avez extrait une branche, tous les commits que vous effectuez restent sur cette branche et ne sont pas partagés avec d’autres branches tant que vous ne les avez pas fusionnées ou ne les avez pas rebaptisées sur la branche en question. Bien sûr, Git semble un peu bizarre quand il s'agit de branches jusqu'à ce que vous regardiez le modèle sous-jacent de la façon dont les branches sont implémentées. Plutôt que de l'expliquer moi-même (j'en ai déjà trop dit, il me semble), je vais faire un lien vers l'explication "informatique" de la façon dont les modèles Git branchent et commettent, tirés du site internet de Git:

http://eagain.net/articles/git-for-computer-scientists/

Une fourchette n'est pas vraiment un concept Git, c'est plutôt une idée politique / sociale. Autrement dit, si certaines personnes ne sont pas satisfaites de la manière dont un projet se déroule, elles peuvent prendre le code source et travailler elles-mêmes séparément des développeurs d'origine. Cela serait considéré comme une fourchette. Git simplifie le forking car tout le monde possède déjà sa propre copie "maîtresse" du code source, il est donc aussi simple que de couper les liens avec les développeurs du projet original et n'exige pas d'exporter l'historique d'un référentiel partagé comme SVN .

EDIT: comme je n’étais pas au courant de la définition moderne de "fork" telle qu’utilisée par des sites tels que GitHub, jetez un oeil aux commentaires et aussi La réponse de Michael Durrant ci-dessous le mien pour plus d'informations.


353
2017-07-25 16:27



Git

Ma réponse inclut github comme beaucoup de gens ont demandé à ce sujet aussi.

Référentiels locaux

git (localement) a un répertoire (.git) dans lequel vous validez vos fichiers et c'est votre 'repository local'. Ceci est différent des systèmes comme svn où vous ajoutez et commettez immédiatement le dépôt distant.

git stocke chaque version d'un fichier qui change en sauvegardant le fichier entier. Il est également différent de svn à cet égard car vous pouvez aller à n'importe quelle version individuelle sans "le recréer" à travers des changements de delta.

git ne «verrouille» aucun fichier et évite ainsi la fonctionnalité de «verrouillage exclusif» pour une modification (les systèmes plus anciens comme les pvcs viennent à l'esprit), de sorte que tous les fichiers peuvent toujours être modifiés, même hors ligne. Il fait vraiment un travail incroyable de fusionner les modifications de fichiers (dans le même fichier!) Ensemble pendant les tractions ou les extractions / poussées vers un dépôt distant tel que github. La seule fois où vous devez faire des modifications manuelles (en fait éditer un fichier) est si deux changements impliquent la même ligne (s) de code.


Branches

Les branches vous permettent de conserver le code principal (la branche «maître»), de faire une copie (une nouvelle branche), puis de travailler dans cette nouvelle branche. Si le travail prend du temps ou que le maître reçoit beaucoup de mises à jour depuis que la branche a été créée, la fusion ou le rebasage (souvent préféré pour un meilleur historique et plus facile à résoudre) contre la branche master doit être fait. Lorsque vous avez terminé, vous fusionnez les modifications apportées dans la branche au référentiel maître. De nombreuses organisations utilisent des branches pour chaque travail, qu’il s’agisse d’une fonctionnalité, d’un bug ou d’une tâche. D'autres organisations utilisent uniquement des branches pour les modifications majeures telles que les mises à niveau de version. Fourche: Avec une branche, vous contrôlez et gérez la branche, alors que quelqu'un d'autre contrôle avec une fourchette l'acceptation du code.
En gros, il y a deux approches principales pour faire des branches. La première consiste à conserver la plupart des modifications sur la branche principale, en n’utilisant que des branches pour des tâches plus importantes et plus longues, telles que les modifications de version lorsque vous souhaitez disposer de deux branches pour des besoins différents. La seconde est que vous créez une branche pour chaque demande de fonctionnalité, correction de bogue ou tâche, puis décidez manuellement quand fusionner réellement ces branches dans la branche principale. Bien que cela semble fastidieux, c'est une approche courante et c'est celle que j'utilise et recommande actuellement parce que cela préserve la branche master et c'est le master que nous promouvons en production, donc nous voulons seulement du code testé, via le rebasing et fusion de branches.

La façon standard de maîtriser une branche est de faire un merge. Les branches peuvent également être rebased «nettoyer» l'histoire. Cela n'affecte pas l'état actuel et est fait pour donner une histoire «plus propre». Fondamentalement, l’idée est que vous vous branchez à partir d’un certain point (généralement du maître). Puisque vous avez ramifié le «maître» lui-même a avancé. Donc, ce serait plus propre si tous les changements que vous avez effectués dans une branche sont joués contre le maître le plus récent avec tous ses changements. Le processus est donc le suivant: enregistrer les modifications; obtenir le "nouveau" maître, puis réappliquer les changements à nouveau contre cela. Sachez que rebase, tout comme la fusion, peut entraîner des conflits que vous devez résoudre manuellement (modifier).

Une «ligne directrice» à noter: Ne rebassez que si la branche est locale et que vous ne l'avez pas encore poussée à distance!Ceci est principalement dû au fait que le rebasage peut modifier l’histoire que d’autres personnes voient et qui peut inclure leurs propres commits.

Suivi des branches

Ce sont les branches nommées origin / branch_name (par opposition à simplement branch_name). Lorsque vous poussez le code vers / depuis des référentiels distants, c'est en fait le mécanisme par lequel cela se produit. Par exemple quand vous git push une branche appelée "building_groups", votre branche passe d'abord à origin / building_groups, puis cela va au dépôt distant (en fait, c'est une simplification excessive, mais assez bon pour le moment). De même si vous faites un git fetch building_groups le fichier récupéré est placé dans votre branche origin / building_groups. Vous pouvez ensuite choisir de fusionner cette branche dans votre copie locale. Notre pratique est de toujours faire un git fetch et une fusion manuelle plutôt que juste un git pull (qui fait les deux ci-dessus en une seule étape).

Fetchnouvelles branches.

Obtenir de nouvelles branches: Au point initial d'un clone, vous aurez toutes les branches. Cependant, si d'autres développeurs ajoutent des branches et les poussent vers la télécommande, il doit y avoir un moyen de «connaître» ces branches et leurs noms afin de pouvoir les localiser localement. Ceci est fait via un git fetch qui obtiendra toutes les branches nouvelles et modifiées dans le référentiel local en utilisant les branches de suivi (par exemple, origine /). Une fois que fetched, on peut git branch --remote lister les branches de suivi et git checkout [branch] pour passer réellement à un donné.

Fusionner

La fusion est le processus de combinaison de modifications de code provenant de différentes branches ou de différentes versions de la même branche (par exemple, lorsqu'une branche locale et une télécommande sont désynchronisées). Si l’on a développé un travail dans une branche et que le travail est terminé, prêt et testé, on peut le fusionner dans le master branche. Ceci est fait par git checkout master pour passer à la master branche, puis git merge your_branch. La fusion va apporter tous les différents fichiers et même différents changements aux mêmes fichiers ensemble. Cela signifie qu'il va réellement changer le code dans les fichiers pour fusionner tous les changements. En faisant le checkout de master il est également recommandé de faire un git pull origin master pour obtenir la dernière version du maître à distance fusionné dans votre maître local. Si le maître distant a changé, c'est-à-dire moved forward, vous verrez des informations qui reflètent cela pendant cette git pull. Si tel est le cas (master modifié), il est conseillé de git checkout your_branch et alors rebase à maîtriser afin que vos changements soient réellement «rejoués» au-dessus du «nouveau» maître. Ensuite, vous continuez à mettre le maître à jour comme indiqué dans le paragraphe suivant.

S'il n'y a pas de conflit, le maître aura ajouté les nouveaux changements. S'il y a des conflits, cela signifie que les mêmes fichiers ont des changements autour de lignes de code similaires qu'il ne peut pas fusionner automatiquement. Dans ce cas git merge new_branch signalera qu'il y a un conflit à résoudre. Vous les "résolvez" en éditant les fichiers (qui comporteront les deux modifications), en sélectionnant les modifications souhaitées, en supprimant littéralement les lignes des modifications que vous ne souhaitez pas, puis en enregistrant le fichier. Les modifications sont marquées par des séparateurs tels que ========et <<<<<<<< 

Une fois que vous avez résolu tous les conflits, vous le ferez à nouveau git addet git commit ces changements pour continuer la fusion (vous recevrez des commentaires de git pendant ce processus pour vous guider). Lorsque le processus ne fonctionne pas bien, vous trouverez que git merge --abort est très pratique pour réinitialiser les choses.

Réorganisation interactive et écrasement / réorganisation / suppression des commits

Si vous avez fait du travail dans de nombreuses petites étapes, par ex. vous engagez du code en tant que "work-in-progress" chaque jour, vous pouvez "écraser" ces nombreuses petites commits dans des commits plus importants. Cela peut être particulièrement utile lorsque vous souhaitez effectuer des révisions de code avec des collègues. Vous ne voulez pas rejouer toutes les 'étapes' que vous avez prises (via les commits), vous voulez simplement dire ici l'effet final (diff) de tous mes changements pour ce travail dans un commit. Le facteur clé à évaluer pour déterminer s'il convient de procéder est de savoir si les validations multiples sont effectuées sur le même fichier ou sur plusieurs fichiers (mieux vaut écraser les commits dans ce cas). Ceci est fait avec l'outil de rebasage interactif. Cet outil vous permet d’écraser des commits, de supprimer des commits, de reformuler des messages, etc. Par exemple git rebase -i HEAD~10  Notez que c'est un ~ PAS un - apporte ce qui suit:
interactive rebasing in Git Soyez prudent et utilisez cet outil avec précaution. Faites un squash / delete / reorder à la fois, quittez et enregistrez ce commit, puis entrez à nouveau dans l'outil. Si les commits ne sont pas contigus, vous pouvez les réorganiser (et ensuite les écraser si nécessaire). Vous pouvez réellement supprimer les commits ici aussi, mais vous devez vraiment être sûr de ce que vous faites quand vous faites cela!

Fourches

Il existe deux approches principales de la collaboration dans les référentiels git. La première, détaillée ci-dessus, est directement via les branches que les gens tirent et poussent depuis / vers. Ces collaborateurs ont leurs clés ssh enregistrées avec le référentiel distant. Cela leur permettra de passer directement à ce référentiel. L'inconvénient est que vous devez maintenir la liste des utilisateurs. L'autre approche - forking - permet à quiconque de «faire un saut» du dépôt, en faisant essentiellement une copie locale dans son propre compte de dépôt git. Ils peuvent alors faire des changements et quand ils ont fini, ils envoient une 'pull request' (en fait c'est plus une 'push' d'eux et une 'pull' demande pour le mainteneur réel du repository) pour obtenir le code accepté.
Cette seconde méthode, utilisant des fourches, ne ne pas exiger que quelqu'un conserve une liste d'utilisateurs pour le référentiel.


Github

github (un référentiel distant) est une source distante que vous avez l'habitude de pousser et d'extraire avec les modifications validées si vous avez (ou êtes ajouté à) un tel référentiel, donc local et distant sont en fait assez distincts. Une autre façon de penser à un référentiel distant est qu'il s'agit d'une structure de répertoire .git qui réside sur un serveur distant.

Lorsque vous "fourchette" - dans l'interface Web du navigateur Web github, vous pouvez cliquer sur enter image description here - vous créez une copie ('clone') du code dans votre compte github. La première fois que vous le faites, il peut être un peu subtil, alors assurez-vous de regarder sous quel référentiel une base de code est répertoriée - soit le propriétaire d'origine, soit "forked from" et vous, par exemple,enter image description here
Une fois que vous avez la copie locale, vous pouvez effectuer les modifications que vous souhaitez (en les tirant et en les poussant sur une machine locale). Lorsque vous avez terminé, vous soumettez une demande d’achat au propriétaire / administrateur du référentiel d’origine (ça sonne bien, mais en fait, il vous suffit de cliquer dessus: - enter image description here) et ils le "tirent"
Il est plus courant pour une équipe travaillant ensemble sur le code de «cloner» le référentiel (cliquez sur l’icône «copie» dans l’écran principal du référentiel). Ensuite, tapez localement git clone [paste] Ceci vous mettra en place localement et vous pourrez également pousser et tirer vers l'emplacement de github (partagé).

Clones

Comme indiqué dans la section sur github, un clone est une copie d'un référentiel. Lorsque vous avez un référentiel distant, vous émettez la commande git clone par rapport à son URL et vous vous retrouvez avec une copie locale ou un clone du référentiel. Ce clone a tout, les fichiers, la branche master, les autres branches, tous les commits existants, tout le shebang. C'est ce clone que vous ajoutez et que vous validez, puis le dépôt distant lui-même est ce à quoi vous vous engagez. C'est ce concept local / distant qui fait de git (et des systèmes similaires à celui-ci comme Mercurial) un DVCS (Distribué Version Control System) par opposition aux CVS plus classiques (Code Versioning Systems) tels que SVN, PVCS, CVS, etc. où vous vous engagez directement dans le référentiel distant.

Visualisation

Visualisation des concepts de base peut être vu à
http://marklodato.github.com/visual-git-guide/index-en.html et
http://ndpsoftware.com/git-cheatsheet.html#loc=index 

Si vous voulez un affichage visuel de la façon dont les changements fonctionnent, vous ne pouvez pas battre l'outil visuel gitg (gitx pour mac) avec un gui que j'appelle "la carte du métro" (en particulier Londres Underground), idéal pour montrer qui a fait quoi, comment les choses changent, divergent et fusionnent, etc.

Vous pouvez également l'utiliser pour ajouter, valider et gérer vos modifications!

gitg/gitx interface

Bien que le gitg / gitx soit relativement minimal, au cours des 2-3 dernières années (2009-2012), le nombre d'outils gui continue à augmenter. De nombreux utilisateurs de Mac utilisent le fork de gitx de brotherbard et pour Linux une excellente option est smart-git avec une interface intuitive et puissante:

smart-git GUI

Notez que même avec un outil graphique, vous allez probablement faire beaucoup de commandes sur la ligne de commande.
Pour cela, j'ai les alias suivants dans mon fichier ~ / .bash_aliases (qui est appelé depuis mon fichier ~ / .bashrc pour chaque session de terminal:

# git
alias gst='git status' # Warning: gst conflicts with gnu-smalltalk (when used).
alias gb='git branch'
alias gco='git checkout'
alias gcob='git checkout -b '
alias ga='git add '
alias gc='git commit'
alias gg='git grep ' #  A great very FAST search option, easier then `find`

Enfin, 6 sauveteurs clés:

1) Vous dérangez votre branche locale et vous voulez simplement revenir à ce que vous avez fait la dernière fois que vous avez fait un git pull:

git reset --hard origin/master  # You will need to be comfortable doing this!

2) Vous commencez à faire des changements localement, vous éditez une demi-douzaine de fichiers et puis, oh merde, vous êtes toujours dans la branche maître (ou une autre):

git checkout -b new_branch_name  # just create a new branch
git add .                      # add the changes files
git commit -m"your message"    # and commit them

3) Vous dérangez un fichier particulier dans votre branche actuelle et vous voulez essentiellement 'réinitialiser' ce fichier (perdre les modifications) à la façon dont c'était la dernière fois que vous l'avez extrait du dépôt distant: git checkout your/directories/filename  Cela réinitialise réellement le fichier (comme beaucoup de commandes git, il n'est pas bien nommé pour ce qu'il fait ici).

4) Vous apportez des modifications localement, vous voulez vous assurer de ne pas les perdre pendant que vous effectuez une réinitialisation ou une réinitialisation de git: je fais souvent une copie manuelle de l’ensemble du projet (cp -r ../my_project ~/) quand je ne suis pas sûr si je pourrais gâcher dans git ou perdre des changements importants.

5) Vous rebasez mais les choses se gâchent:

git rebase --abort # To abandon interactive rebase and merge issues

6) Ajoutez votre branche git à votre invite PS1 (voir https://unix.stackexchange.com/a/127800/10043), par exemple. enter image description here
La branche est selenium_rspec_conversion


512
2018-01-22 17:12



Voici l'image d'Oliver Steele de comment tout cela s'accorde:

enter image description here


139
2017-07-23 16:51



Juste pour ajouter aux autres, une note spécifique au forking.

Il est bon de se rendre compte que techniquement, le clonage du repo et l'abandon du repo sont la même chose. Faire:

git clone $some_other_repo

et vous pouvez vous appuyer sur le dos --- vous avez juste fourchu un autre repo.

Git, en tant que VCS, est en fait tout à propos de clonage forking. En dehors de la simple navigation via une interface utilisateur distante telle que cgit, il n’ya pas grand chose à voir avec le repo git qui n’implique pas forking cloner le repo à un moment donné.

cependant,

  • quand quelqu'un dit J'ai fourré repo X, ils signifient qu'ils ont créé un clone du repo ailleurs avec l'intention de exposer à d'autres, par exemple pour montrer des expériences, ou pour appliquer différentes mécanisme de contrôle d'accès (par exemple pour permettre aux personnes sans accès Github mais avec compte interne de l'entreprise pour collaborer).

    Faits que: le repo est très probablement créé avec d'autres commandes que git clone, qu'il est très probablement hébergé quelque part sur un serveur opposé à l'ordinateur portable de quelqu'un, et a probablement légèrement différent format (c'est un "repo nu", c'est-à-dire sans arbre de travail) sont tous détails techniques.

    Le fait qu'il contiendra très probablement un ensemble différent de branches, tags ou commits est très probablement la raison pour laquelle ils l'ont fait dans le premier endroit.

    (Ce que fait Github quand vous cliquez sur "fork", c'est juste le clonage avec ajouté sucre: il clone le repo pour vous, le met sous votre compte, enregistre le "forked" quelque part, ajoute à distance nommé "en amont", et la plupart surtout, joue la belle animation.)

  • Quand quelqu'un dit J'ai cloné repo X, ils signifient qu'ils ont créé un clone du repo localement sur leur ordinateur portable ou de bureau avec l'intention l'étudier, jouer avec, y contribuer ou construire quelque chose à partir de la source code dedans.

La beauté de Git, c'est que tout cela est parfaitement intégré: tous ces repos partagent la partie commune de bloc engagez la chaîne de sorte qu'il soit possible de fusionner en toute sécurité (voir note ci-dessous) les changements de va-et-vient entre toutes ces mises en pension, comme vous le souhaitez.


Remarque: "en toute sécurité" tant que vous ne réécrivez pas la partie commune de la chaîne et que les modifications ne sont pas contradictoires.


6
2017-09-02 19:08



Fourche vs. Clone - deux mots qui signifient tous les deux copie

S'il vous plaît voir ceci diagramme.  (Originaire de http://www.dataschool.io/content/images/2014/Mar/github1.png).


5