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 à juste branch_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 vous git push
appelez une branche building_groups
, votre branche va d'abord vers origin/building_groups
, puis vers le référentiel distant. De même, si vous effectuez une git fetch building_groups
, le fichier récupéré est placé dans votre origin/building_groups
branche. Vous pouvez ensuite choisir de fusionner cette branche dans votre copie locale. Notre pratique est de toujours faire une git fetch
et une fusion manuelle plutôt que juste une git 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 fois fetch
édité, on peut git branch --remote
répertorier les branches de suivi et git 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 en git checkout master
basculant ensuite sur la master
branche git 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
de master
c'est aussi recommandé de faire git 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 cela git pull
. Si tel est le cas (maître modifié) il est conseillé de git checkout your_branch
puis rebase
à 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
et git 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):
# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '
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:
[alias]
co = checkout
cob = checkout -b
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!
git reset [filename(s)]
git checkout -b [name_for_a_new_branch]
git add [file(s)]
git commit -m "A useful message"
Voila! You've moved that 'master' commit to its own branch !
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
:
git reset --hard origin/master # You will need to be comfortable doing this!
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):
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
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:
git checkout your/directories/filename
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
ou rebase
: 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:
git rebase --abort # To abandon interactive rebase and merge issues
Ajoutez votre branche Git à votre PS1
invite (voir https://unix.stackexchange.com/a/127800/10043 ), par exemple
La branche est selenium_rspec_conversion
.