Je suis un utilisateur de SVN et j'apprends maintenant Git.
Dans SVN, je commande généralement sur mon ordinateur local un dépôt, qui inclut toutes les branches de mon projet et je sélectionnais le dossier de ma branche qui m'intéresse et j'y travaille.
Je vois une différence en utilisant Git.
Actuellement, je clone un repo et clone une branche spécifique à l’aide de gitk.
Le dossier de projet ne contient que le contenu de cette branche et je ne peux pas voir toutes les branches comme dans SVN, ce qui est un peu déroutant pour moi.
Je ne trouve pas de moyen facile de voir toutes les branches de mon référentiel local à l'aide de Git.
Je voudrais savoir si le processus Git que j'ai décrit est "standard" et comment il est correct ou si quelque chose me manque.
Aussi, j'aimerais savoir comment gérer un processus où je dois travailler sur deux branches en même temps au cas où, par exemple, je devrais créer un correctif sur master tout en conservant le contenu d'une autre branche.
Quelles sont les conventions de nom recommandées pour créer, par exemple, les dossiers contenant la branche clonée à partir du référentiel dans Git
myproject-branchname
?
git clone
est plus commesvnadmin hotcopy
ousvnrdump
+svnadmin load
que c'est commesvn checkout
. Avecgit
, vous ne demandez pas des morceaux de la garde; vous copiez l' intégralité du référentiel et l'utilisez localement, en reportant les modifications dans le référentiel "source" quand et si vous le souhaitez. Git et Subversion utilisent deux modèles entièrement différents pour le contrôle de source.git-flow
Réponses:
Bienvenue dans le gang!
Rééducation SVN
Attends un instant. Bien que CVS et SVN ainsi que d’autres systèmes de contrôle de version traditionnels (c’est-à-dire centralisés) remplissent (principalement) les mêmes objectifs que les systèmes de contrôle de versions modernes (c.-à-d. Distribués) tels que mercurial et Git, vous serez bien mieux familiarisé avec Git au lieu de essayez de transférer votre flux de travail SVN vers Git.
http://hginit.com ( vue sur archive.org ) par Joel Spolsky ( l' un des fondateurs mêmes de Stack Exchange) est un tutoriel pour Mercurial, Git pas, mais il est zéro e chapitre, « Subversion Rééducation » est utile pour les personnes commutation loin de SVN à tout système de contrôle de version distribué, comme il vous dit quels concepts SVN vous devez (temporairement) un -apprendre (ou
stash
loin , car les utilisateurs Git pourraient dire) pour pouvoir envelopper votre tête autour de la distribution concepts de système de contrôle de version et les workflows idiomatiques établis pour fonctionner avec eux.Vous pouvez donc lire ce chapitre au-dessus de zéro et la plupart du temps simplement remplacer le mot "mercurial" par "Git" et ainsi vous préparer correctement ainsi que votre esprit à Git.
Les petits caractères
(Vous pouvez sauter ceci pour le moment.) Bien que mercurial et Git se ressemblent beaucoup plus que SVN, il existe certaines différences conceptuelles entre eux, de sorte que certains des énoncés et conseils de "Subversion Re-education" deviendront techniquement erronés. en remplaçant "mercurial" par "Git":
En SVN, tout est un répertoire (mais vous ne devez pas nécessairement le traiter comme tel)
Mais je t'ai interrompu. Tu disais?
Si, par là, vous voulez dire que vous avez extrait le dossier racine du référentiel SVN (ou tout autre dossier correspondant à plus d'une
trunk
ou à une seule branche, par exemple, dans la structure de référentiel SVN classique, lebranches
dossier contenant toutes les branches non liées au réseau), J'ose dire que vous avez probablement mal utilisé SVN (ish) avec SVN, ou du moins que vous avez un peu abusé du fait que le tronc, les branches et les balises sont tous repliés dans un seul espace de noms (bien que hiérarchique) avec des répertoires dans la base de révisions / code.Même s'il peut être tentant de modifier plusieurs branches de SVN en parallèle, AFAIK ne correspond pas à l'utilisation prévue de SVN. (Bien que je ne sache pas quels inconvénients spécifiques cela pourrait avoir.)
Dans Git, seuls les répertoires sont des répertoires
Chaque clone d'un référentiel Git est lui-même un référentiel Git: par défaut, il obtient une copie complète de l'historique du référentiel d'origine, y compris toutes les révisions, les branches et les balises. Mais il gardera tout ce que vous voulez: Git le stocke dans une base de données basée sur des fichiers, située dans le sous-dossier caché du dossier racine du référentiel
.git/
.Mais quels sont les fichiers non cachés que vous voyez dans le dossier du référentiel?
Lorsque vous êtes
git clone
un référentiel, Git fait plusieurs choses. Grossièrement:.git/
sous - dossier avec la "base de données"master
).Cette dernière étape signifie que Git recherche la révision pointée par cette branche et décompresse l'arborescence de fichiers qui y est stockée (la base de données utilise un moyen de compression et de déduplication) dans le dossier racine du référentiel. Ce dossier racine et tous ses sous-dossiers (à l'exception du
.git
sous-dossier spécial ) sont appelés "copie de travail" de votre référentiel. C'est là que vous interagissez avec le contenu de la révision / branche actuellement extraite. Ce ne sont que des dossiers et des fichiers normaux. Cependant, pour utiliser le référentiel proprement dit (la "base de données" des révisions et références), vous utilisez desgit
commandes.Voir les branches de Git et interagir avec les branches de Git
La version que
gitk
j'ai obtenue ne peut pas cloner de référentiels. Il ne peut afficher que l'historique des dépôts, créer des branches et extraire des branches. En outre, il n'y a pas de "clonage" d'une branche. Vous pouvez uniquement cloner des référentiels.Voulez-vous dire que vous clonez un repo en utilisant
git clone ...
, puis en utilisantgitk
, vérifiez une branche?Oui, c'est assez standard:
git clone ...
git checkout ...
ou en utilisant un outil graphique commegikt
Peut être:
git branch
git branch -r
toutes les branches avecgit branch -a
vous pouvez utiliser
gitk
pour afficher l'historique complet (toutes les balises de branche, etc. que votre référent local connaît) en l'invoquant avecComment travailler avec plusieurs branches en parallèle
Il y a différents scénarios ici:
Un nouveau changement (à créer) doit être appliqué à plusieurs branches
Utilisez ce flux de travail:
c
partir d'une révision qui est déjà dans l'ascendance de toutes ces branches (par exemple, la révision qui a introduit le bogue lorsque le changement sera une correction de bogue) ou d'une révision qui (avec tous ses ancêtres) est acceptable pour être introduite dans toutes ces branches.c
.Pour chaque branche
b
qui a besoin du changement:Départ
b
:Fusionner
c
dansb
:Supprimer la branche
c
:Un changement existant est nécessaire sur une autre branche
(... mais sans les autres modifications effectuées sur l'emplacement de ces modifications)
Sur une branche
a
, vous voulez changer un ou plusieurs fichiers à l’état exact qu’ils ont sur une autre brancheb
a
Obtenir le contenu du fichier de la branche
b
:(
git checkout
Sinon, les chemins demandés ne passeront pas à la brancheb
, ils obtiendront uniquement le contenu du fichier demandé. Ces fichiers peuvent exister ou ne pas déjà existera
. S'ils le font, ils sont écrasés avec leur contenub
.)Tout en travaillant sur une branche, vous voulez voir comment les choses se passent sur une autre branche
Découvrez la branche sur laquelle vous souhaitez travailler.
Ensuite, pour regarder l'autre branche,
gitk
essayez de faire passer les boutons radio de "patch" à "arborescence")git worktree
pour créer un répertoire de travail séparé du même référentiel (c.-à-d. en utilisant également la base de données dans le.git/
répertoire de votre référentiel local actuel) où vous pouvez extraire cette autre branchela source
stash
c'est idéal.git stash
C'est bien de déplacer les travaux inachevés, par exemple pour changer de branche et revenir plus tard.À moins que vous n'extrayiez le répertoire situé au-dessus du coffre, toutes les branches disponibles dans Subversion ne sont généralement pas disponibles localement. Dans Git, tout le contenu (commits, messages, branches, etc.) est toujours cloné sur chaque copie.
Pas possible, voir ci-dessus. Vous pouvez
git checkout branch-name
, mais vous ne pouvez pasgit clone something branch-name
. Dans Subversion, les branches sont des dossiers. Dans Git, les branches sont des pointeurs sur un commit.Courez
git branch
. Par défaut, seules les branches locales sont affichées. Utilisezgit branch --remote
pour voir les branches distantes.la source
--single-branch
(même seulement la pointe avec--depth 1
). La différence entre les branches locales et distantes connues de git est simplement une sorte d’étiquette. Les branches distantes sont préfixées avec le nom de la source distante (souventorigin
). Les branches locales n'ont pas ce préfixe. Mais au final, les données sont disponibles localement (à moins que vous ne l'ayez fait--single-branch
ou quelque chose de similaire). Lorsque vous utilisezgit checkout $branchname
une branche pour laquelle il n’existe pas de branche locale mais une branche distante, git configure automatiquement une branche locale "assurant le suivi" de la télécommande.Comme cela est étiqueté avec git, j'espère que mon manque de connaissances en SVN est négligeable.
Vous clonez l'ensemble du référentiel distant, pas seulement une branche spécifique.
Le référentiel est mieux imaginé en tant que base de données, vous créez donc un clone de l'état actuel de la base de données distante. Mais après cela, vous travaillez sur votre propre copie de cette base de données. si vous vous engagez, vous modifiez votre base de données locale.
Cette
fetch
commande permet de maintenir la base de données locale synchronisée avec la base de données distante.Généralement, à partir de cette base de données locale, vous extrayez une branche sur laquelle travailler. Ce n'est rien d'autre qu'un marqueur interne pour git, où votre travail actuel a commencé.
Disons que vous travaillez sur un référentiel simple, où il n'y a pas de branche en plus
master
, vous pouvez jeter un coup d'oeil dans le.git
dossier pour dévoiler le "magique":Supposons que votre dernier commit (on
master
) était182e8220b404437b9e43eb78149d31af79040c66
, vous le trouverez exactement souscat .git/refs/heads/master
.À partir de cette branche
git checkout -b mybranch
, vous retrouvez exactement le même pointeur dans le fichiercat .git/refs/heads/mybranch
.Les branches ne sont rien de plus que des "pointeurs". Le marqueur "de travail" est appelé un
HEAD
.Si vous voulez savoir où vous en êtes
HEAD
:cat .git/HEAD
qui dit, par exempleref: refs/heads/mybranch
, qui pointe (cat .git/refs/heads/mybranch
) à un hachage de commit78a8a6eb6f82eae21b156b68d553dd143c6d3e6f
Les commits réels sont stockés dans le
objects
dossier (le comment est un sujet à part).Ne confondez pas le
working directory
avec la "base de données git" dans son ensemble. Comme je l'ai dit plus haut, votre répertoire de travail n'est qu'un instantané de (peut-être) un sous-ensemble.Supposons que vous avez différentes branches, votre répertoire de travail est dédié au travail sur cette branche uniquement (bien que vous puissiez placer le travail ailleurs).
Généralement, si vous voulez voir quelles branches sont définies pour le projet, vous avez la possibilité de
git branch
pour les branches localesgit branch --remote
pour les branches éloignéesgit branch -a
pour les deux(ou
git branch -v
)Puisque git est un système de contrôle de version distribué, il est non seulement possible, mais également conseillé, de créer différentes branches localement / à distance.
Mon flux de travail typique est:
Lorsque la fonctionnalité est terminée:
WIP
branche (avec rebasage interactif) = faire un simple commit à partir de celui-ciWIP
branche dans la branche de fonctionnalités et proposez-la (si vous travaillez avec github, cette offre s'appelle une "demande d'extraction") à intégrer dans la branche stable (principale).Cela dépend de la structure de votre projet:
Disons que vous avez un maître stable. Et les fonctionnalités ne sont développées qu'à partir de cette branche stable - elle se trouve donc généralement derrière une branche de fonctionnalité. Ensuite, vous auriez un dernier commit sur master qui serait la racine de la branche de fonctionnalité.
Ensuite, vous feriez un commit sur la branche principale et pourriez décider de fusionner les deux branches ou de les rebaser (ce qui est une sorte de fusion pour les utilisateurs ayant des besoins avancés, pour ainsi dire).
Ou vous pouvez toujours modifier des branches (par exemple
master
) et les sélectionner à d’autres branches.C'est à toi de decider.
En règle générale, vous vous retrouvez avec le nom du référentiel.
Mais il y a des occasions, quand cela n'est pas voulu:
par exemple, vous clonez oh-my-zsh avec
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
Here.oh-my-zsh
est explicitement nommé comme cible.la source
Git clone
clone en fait tout le référentiel, mais définit votre répertoire de travail sur le répertoire par défaut (généralement maître).Vous pouvez voir les autres branches utiliser
git branch
pour voir les branches locales ougit branch -r
distantes, puisgit checkout
pour basculer vers une branche existante ou en créer une nouvelle basée sur la branche actuelle.Vous devriez lire la documentation de git pour plus de détails, et Atlassian a aussi de bons articles à ce sujet.
la source
Les branches dans git et svn sont des choses fondamentalement différentes.
Dans svn une branche (ou une balise) est un répertoire dans le référentiel.
Dans git une branche (ou une balise) est un pointeur sur une validation.
Avec svn, vous pouvez si vous souhaitez extraire la racine du référentiel. Cela signifie que chaque branche et étiquette sont extraites en même temps. Afaict ce n'est pas la façon normale d'utiliser svn.
Une branche git n'est pas un répertoire, il n'y a donc pas d'équivalent à "extraire la racine du référentiel". Plusieurs arborescences de travail étant supportées, je suppose que vous pouvez concocter un script pour extraire toutes les branches en même temps si vous le souhaitez vraiment, mais ce serait plutôt inhabituel de le penser.
De plus, avec SVN, il n'y a qu'un seul dépôt. Avec git chaque développeur a son propre repo. Cela signifie que les développeurs peuvent travailler hors ligne, mais que différents développeurs peuvent avoir une idée différente de ce qu'il y a sur chaque branche.
En tant que répertoires et en raison du modèle historique linéaire simple de svn, les branches de svn ont des historiques robustes. Si vous voulez savoir ce qui était sur la branche x à la date y, vous pouvez facilement poser cette question.
En revanche, les branches de git n'ont pas vraiment d'histoires. Il y a le "refog" mais il est plus destiné à être un mécanisme de reprise après sinistre qu'à un historique à long terme. En particulier, le reflog ne peut pas être lu à distance et est désactivé par défaut pour les pensions nues.
Les commits ont bien sûr des historiques, mais ceux-ci ne suffisent pas pour répondre à la question "ce qui était sur la branche x de la date du jour".
Vous pouvez lister toutes les branches locales en tapant "branche git".
Vous pouvez lister toutes les branches locales et distantes en utilisant "git branch -a"
Quelques options.
Vous pouvez valider vos modifications sur «l’autre branche», passer en mode maître, puis revenir en arrière.
Vous pouvez également créer un arbre de travail supplémentaire. Google "git-worktree" pour plus de détails sur la syntaxe.
Je ne pense pas qu'il y ait une convention établie. L'extraction de plusieurs arbres de travail à la fois est l'exception et non la règle.
la source