Je veux comprendre la différence entre une branche, une fourchette et un clone dans Git?
De même, qu'est-ce que cela signifie lorsque je fais un git fetch
par opposition à un git pull
?
Aussi, qu'est-ce que cela rebase
signifie par rapport à merge
?
Comment puis-je écraser des engagements individuels ensemble?
Comment sont-ils utilisés, pourquoi sont-ils utilisés et que représentent-ils?
Comment GitHub figure-t-il?
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 VCS centralisé comme Subversion et DVCS comme Git est que dans Git, lorsque vous clonez, vous copiez en fait le référentiel source entier, y compris tout l'historique et les branches. Vous avez maintenant un nouveau référentiel sur votre machine et toutes les validations que vous effectuez vont dans ce référentiel. Personne ne verra de modifications tant que vous n'aurez pas poussé ces validations vers un autre référentiel (ou l'original) ou jusqu'à ce que quelqu'un tire les validations 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, il représente un fil conducteur de développement. Vous avez généralement une branche principale, mais vous pouvez également avoir une branche où vous travaillez sur une fonctionnalité xyz et une autre pour corriger le bogue abc. Lorsque vous avez extrait une branche, toutes les validations que vous effectuez resteront sur cette branche et ne seront pas partagées avec d'autres branches jusqu'à ce que vous les fusionniez ou les rebasiez sur la branche en question. Bien sûr, Git semble un peu bizarre en ce qui concerne les 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, je pense), je vais faire un lien vers l'explication "informatique" de la façon dont Git modélise les branches et les commits, tirée du site Web de Git:
http://eagain.net/articles/git-for-computer-scientists/
Une fourchette n'est pas vraiment un concept Git, c'est plus une idée politique / sociale. Autrement dit, si certaines personnes ne sont pas satisfaites de la façon dont un projet se déroule, elles peuvent prendre le code source et y travailler elles-mêmes séparément des développeurs d'origine. Ce serait considéré comme une fourchette. Git facilite la création de fourches car tout le monde a déjà sa propre copie "principale" du code source, c'est donc aussi simple que de couper les liens avec les développeurs du projet d'origine et ne nécessite pas d'exporter l'historique à partir d'un référentiel partagé comme vous pourriez le faire avec 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, veuillez jeter un œil aux commentaires et aussi à la réponse de Michael Durrant ci-dessous la mienne pour plus d'informations.
la source
Git
Cette réponse inclut GitHub comme beaucoup de gens l'ont également demandé.
Dépôts locaux
Git (localement) a un répertoire (
.git
) dans lequel vous validez vos fichiers et c'est votre 'référentiel local'. Ceci est différent des systèmes comme SVN où vous ajoutez et vous engagez immédiatement dans le référentiel distant.Git stocke chaque version d'un fichier qui change en enregistrant l'intégralité du fichier. Il est également différent de SVN à cet égard, car vous pouvez accéder à n'importe quelle version individuelle sans la «recréer» via des modifications delta.
Git ne `` verrouille '' pas du tout les fichiers et évite ainsi la fonctionnalité de `` verrouillage exclusif '' pour un montage (les anciens systèmes comme les pvcs viennent à l'esprit), de sorte que tous les fichiers peuvent toujours être modifiés, même lorsqu'ils sont hors ligne. Il fait en fait un travail incroyable de fusionner les modifications de fichiers (dans le même fichier!) Ensemble pendant les tirages ou les récupérations / poussées vers un référentiel distant tel que GitHub. La seule fois où vous devez effectuer des modifications manuelles (modifier réellement un fichier) est si deux modifications 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 un certain temps ou que le maître reçoit beaucoup de mises à jour depuis la création de la branche, la fusion ou le rebasage (souvent préféré pour un meilleur historique et une résolution plus facile des conflits) contre la branche principale doit être effectué. Lorsque vous avez terminé, vous fusionnez les modifications apportées dans la branche dans le 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'un élément de corvée. D'autres organisations n'utilisent des succursales que pour les changements majeurs tels que les mises à niveau de version.
Fork: avec une branche, vous contrôlez et gérez la branche, tandis qu'avec une fourche, quelqu'un d'autre contrôle l'acceptation du code.
D'une manière générale, il existe deux approches principales pour créer des succursales. La première consiste à conserver la plupart des modifications sur la branche principale, en n'utilisant que des branches pour des choses plus grandes et plus longues comme les changements de version où vous voulez avoir deux branches disponibles pour des besoins différents. La seconde consiste à créer une branche pour chaque demande de fonctionnalité, correction de bogue ou tâche, puis à décider manuellement quand fusionner réellement ces branches dans la branche principale principale. Bien que cela semble fastidieux, c'est une approche courante et c'est celle que j'utilise actuellement et que je recommande car cela garde la branche principale plus propre et c'est le maître que nous promouvons en production, nous ne voulons donc que du code complet et testé, via le rebasage et fusion de succursales.
La manière standard d'amener une branche `` en '' à maîtriser est de faire a
merge
. Les succursales peuvent également être «rebasées» pour «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 êtes ramifié à partir d'un certain point (généralement du maître). Depuis que vous avez créé une branche, «maître» lui-même a depuis progressé à partir de ce point de branche. Il sera plus «propre» (plus facile à résoudre les problèmes et l'historique sera plus facile à comprendre) si toutes les modifications que vous avez effectuées dans une branche sont jouées par rapport à l'état actuel du maître avec toutes ses dernières modifications. Ainsi, le processus est le suivant: enregistrez les modifications; obtenir le «nouveau» maître, puis réappliquer (c'est la partie rebase) les modifications contre cela. Sachez que le rebase, tout comme la fusion, peut entraîner des conflits que vous devez résoudre manuellement (c'est-à-dire modifier et corriger).
Une ligne directrice à noter:
rebaser uniquement si la branche est locale et que vous ne l'avez pas encore poussée vers la télécommande!
Cela 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 qui sont nommées
origin/branch_name
(par opposition à justebranch_name
). Lorsque vous poussez et tirez le code vers / depuis des référentiels distants, c'est en fait le mécanisme par lequel cela se produit. Par exemple, lorsque vousgit push
appelez une branchebuilding_groups
, votre branche va d'abord versorigin/building_groups
, puis vers le référentiel distant. De même, si vous effectuez unegit fetch building_groups
, le fichier récupéré est placé dans votreorigin/building_groups
branche. Vous pouvez ensuite choisir de fusionner cette branche dans votre copie locale. Notre pratique est de toujours faire unegit fetch
et une fusion manuelle plutôt que juste unegit pull
(qui fait les deux ci-dessus en une seule étape).Récupération de nouvelles 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 retirer localement. Cela se 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,origin/
). Une foisfetch
édité, on peutgit branch --remote
répertorier les branches de suivi etgit checkout [branch]
passer à l'une quelconque.Fusion
La fusion est le processus de combinaison des modifications de code de différentes branches ou de différentes versions de la même branche (par exemple lorsqu'une branche locale et distante sont désynchronisées). Si l'on a développé du travail dans une branche et que le travail est terminé, prêt et testé, alors il peut être fusionné dans la
master
branche. Cela se fait engit checkout master
basculant ensuite sur lamaster
branchegit merge your_branch
. La fusion réunira tous les différents fichiers et même les différentes modifications apportées aux mêmes fichiers . Cela signifie qu'il va réellement changer le code dans les fichiers pour fusionner toutes les modifications.Quand vous faites le
checkout
demaster
c'est aussi recommandé de fairegit pull origin master
pour obtenir la toute 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 celagit pull
. Si tel est le cas (maître modifié) il est conseillé degit checkout your_branch
puisrebase
à maîtriser afin que vos modifications deviennent réellement « rejouées » au - dessus du maître « nouveau ». Ensuite, vous continuerez à mettre à jour le maître, comme indiqué dans le paragraphe suivant.S'il n'y a pas de conflits, alors master aura les nouvelles modifications ajoutées. 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 des conflits à résoudre. Vous les «résolvez» en modifiant 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 signalées par des séparateurs tels que========
et<<<<<<<<
.Une fois que vous avez résolu tous les conflits, vous devrez à nouveau
git add
etgit commit
ces modifications pour continuer la fusion (vous obtiendrez des commentaires de git pendant ce processus pour vous guider).Lorsque le processus ne fonctionne pas bien, vous constaterez que
git merge --abort
c'est très pratique pour réinitialiser les choses.Rebasement interactif et écrasement / réorganisation / suppression des commits
Si vous avez effectué un certain nombre de petites étapes, par exemple, si vous validez du code en tant que «travail en cours» tous les jours, vous souhaiterez peut-être «écraser» ces nombreuses petites validations en quelques validations plus importantes. 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 juste dire que voici l'effet final (diff) de toutes mes modifications pour ce travail en un seul commit.
Le facteur clé à évaluer lors de l'examen de l'opportunité est de savoir si les validations multiples sont contre le même fichier ou les fichiers plusieurs fois (mieux vaut écraser les validations dans ce cas). Cela se fait avec l'outil de rebasage interactif. Cet outil vous permet de supprimer les validations, de supprimer les validations, de reformuler les messages, etc. Par exemple,
git rebase -i HEAD~10
( remarque: c'est un~
, pas un-
) fait apparaître ce qui suit:Soyez prudent cependant et utilisez cet outil avec précaution. Effectuez un squash / suppression / réorganisation à la fois, quittez et enregistrez ce commit, puis entrez à nouveau l'outil. Si les validations ne sont pas contiguës, vous pouvez les réorganiser (puis les écraser si nécessaire). Vous pouvez également supprimer les validations ici, mais vous devez vraiment être sûr de ce que vous faites lorsque vous faites cela!
Fourches
Il existe deux approches principales de collaboration dans les référentiels Git. La première, détaillée ci-dessus, se fait directement via des branches que les gens tirent et poussent de / vers. Ces collaborateurs ont leurs clés SSH enregistrées dans le référentiel distant. Cela leur permettra de pousser directement vers ce référentiel. L'inconvénient est que vous devez maintenir la liste des utilisateurs. L'autre approche - bifurquer - permet à quiconque de «bifurquer» le référentiel, en faisant essentiellement une copie locale dans son propre compte de référentiel Git. Ils peuvent ensuite apporter des modifications et, une fois terminé, envoyer une «demande d'extraction» (en réalité, il s'agit plus d'une «poussée» de leur part et d'une demande «d'extraction» pour le responsable du référentiel) pour obtenir le code accepté.
Cette deuxième méthode, utilisant des fourches, ne nécessite pas que quelqu'un gère une liste d'utilisateurs pour le référentiel.
GitHub
GitHub (un référentiel distant) est une source distante vers laquelle vous poussez et tirez normalement ces 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
.git
structure de répertoires qui vit sur un serveur distant.Lorsque vous «fork» - dans l'interface graphique du navigateur Web GitHub, vous pouvez cliquer sur ce bouton - vous créez une copie («clone») du code dans votre compte GitHub. Cela peut être un peu subtil la première fois que vous le faites, alors assurez-vous de regarder dans le référentiel sous lequel une base de code est répertoriée - soit le propriétaire d'origine ou 'forked from' et vous, par exemple, comme ceci:
Une fois que vous avez la copie locale, vous pouvez apporter des modifications à votre guise (en les tirant et en les poussant vers une machine locale). Lorsque vous avez terminé, vous soumettez une `` demande de tirage '' au propriétaire / administrateur du référentiel d'origine (cela semble sophistiqué, mais en fait vous cliquez simplement sur ceci:) et ils le `` tirent ''.
Il est plus courant pour une équipe travaillant ensemble sur du code de «cloner» le référentiel (cliquez sur l'icône «copier» sur l'écran principal du référentiel). Ensuite, tapez
git clone
et collez localement . Cela vous configurera localement et vous pourrez également pousser et tirer vers l'emplacement 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 exécutez la
git clone
commande par rapport à son URL, puis 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 effectuez vos ajouts et vos validations, puis le référentiel distant lui-même est celui vers lequel vous envoyez ces validations. C'est ce concept local / distant qui fait de Git (et des systèmes similaires comme Mercurial) un DVCS ( système de contrôle de version distribué ) par opposition aux CVS plus traditionnels (systèmes de version de code) tels que SVN, PVCS, CVS, etc. où vous vous engagez directement dans le référentiel distant.Visualisation
La visualisation des concepts de base peut être vue sur
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 macOS) avec une interface graphique que j'appelle «la carte du métro» (en particulier le métro de Londres), 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!
Bien que gitg / gitx soit assez minime, le nombre d'outils GUI continue d'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 mais puissante:
Notez que même avec un outil GUI, vous effectuerez probablement beaucoup de commandes sur la ligne de commande.
Pour cela, j'ai les alias suivants dans mon
~/.bash_aliases
fichier (qui est appelé depuis mon~/.bashrc
fichier pour chaque session de terminal):ET j'ai les "alias git" suivants dans mon
~/.gitconfig
fichier - pourquoi les avoir?Pour que l'achèvement de la branche (avec la touche TAB) fonctionne!
Ce sont donc:
Exemple d'utilisation:
git co [branch]
<- la complétion de tabulation pour les branches fonctionnera.Outil d'apprentissage GUI
Https://learngitbranching.js.org/ peut être utile pour apprendre certains des concepts de base. Capture d'écran: Vidéo: https://youtu.be/23JqqcLPss0
Enfin, 7 sauveteurs clés!
Vous apportez des modifications, les ajoutez et les validez (mais ne poussez pas) et puis oh! vous vous rendez compte que vous êtes maître!
Vous gâchez certains fichiers tout en travaillant dans une branche locale et vous voulez simplement revenir à ce que vous aviez la dernière fois que vous avez fait un
git pull
:Vous commencez à faire des changements localement, vous éditez une demi-douzaine de fichiers puis, oh merde, vous êtes toujours dans la branche master (ou une autre):
Vous gâchez un fichier particulier dans votre branche actuelle et vous voulez essentiellement `` réinitialiser '' ce fichier (perdre les modifications) à ce qu'il était la dernière fois que vous l'avez retiré du référentiel distant:
Cela réinitialise en fait le fichier (comme beaucoup de commandes Git, il n'est pas bien nommé pour ce qu'il fait ici).
Vous apportez des modifications localement, vous voulez vous assurer de ne pas les perdre pendant que vous faites un
git reset
ourebase
: je fais souvent une copie manuelle de l'ensemble du projet (cp -r ../my_project ~/
) quand je ne suis pas sûr de pouvoir gâcher dans Git ou perdre des informations importantes changements.Vous rebasez mais les choses se gâchent:
Ajoutez votre branche Git à votre
PS1
invite (voir https://unix.stackexchange.com/a/127800/10043 ), par exempleLa branche est
selenium_rspec_conversion
.la source
Voici l'image d'Oliver Steele de la façon dont tout cela s'assemble:
la source
Fork Vs. Clone - deux mots qui signifient tous deux copie
Veuillez voir ce diagramme. (À l'origine de http://www.dataschool.io/content/images/2014/Mar/github1.png ).
Fourchette
Cloner
la source
anidea
directement à son repo et vous épargner les corvées de garder votre fork à jour. OTOH si vous n'arrivez pas à parvenir à un accord avec Joe, vous pouvez simplement continuer à développer et à utiliser votre fork (et voir si vous pouvez le faire changer d'avis plus tard).Juste pour ajouter aux autres, une note spécifique à la fourche.
Il est bon de réaliser que, techniquement, le clonage du repo et la fourche du repo sont la même chose. Faire:
et vous pouvez vous tapoter dans le dos --- vous venez de bifurquer un autre repo.
Git, en tant que VCS, est en fait tout sur le
clonage desfourches. Hormis la "simple navigation" à l'aide d'une interface utilisateur distante telle que cgit, il n'y a pas grand-chose à voir avec git repo qui n'implique pas deforder leclonage du repo à un moment donné.cependant,
quand quelqu'un dit que j'ai bifurqué le repo X , cela signifie qu'ils ont créé un clone du repo ailleurs avec l'intention de l' exposer à d'autres, par exemple pour montrer des expériences, ou pour appliquer un mécanisme de contrôle d'accès différent (par exemple pour permettre aux personnes sans Accès Github mais avec compte interne de l'entreprise pour collaborer).
Faits: le référentiel est très probablement créé avec une autre commande que
git clone
, qu'il est très probablement hébergé quelque part sur un serveur par opposition à l'ordinateur portable de quelqu'un, et a probablement un format légèrement différent (c'est un "référentiel nu", c'est-à-dire sans arborescence de travail) ne sont que des détails techniques.Le fait qu'il contiendra très probablement un ensemble différent de branches, de balises ou de validations est probablement la raison pour laquelle ils l'ont fait en premier lieu.
(Ce que fait Github lorsque vous cliquez sur "fork", c'est simplement du clonage avec du sucre ajouté: il clone le dépôt pour vous, le place sous votre compte, enregistre le "forked from" quelque part, ajoute une télécommande nommée "upstream", et plus important encore, joue la belle animation.)
Lorsque quelqu'un dit que j'ai cloné le référentiel X , cela signifie qu'il a créé un clone du référentiel localement sur son ordinateur portable ou de bureau avec l'intention de l'étudier, de jouer avec, d'y contribuer ou de construire quelque chose à partir du code source.
La beauté de Git est qu'il rend tout cela parfaitement compatible: tous ces référentiels partagent la partie commune de la chaîne de validation de
bloc, il est donc possible de fusionner en toute sécurité (voir la note ci-dessous) les modifications entre tous ces référentiels comme bon vous semble.Remarque: "en toute sécurité" tant que vous ne réécrivez pas la partie commune de la chaîne, et tant que les modifications ne sont pas en conflit.
la source