Utiliser git comme référentiel central

12

J'ai configuré git pour mon propre usage - afin que je puisse accéder à un projet de `` n'importe où '', et garder la sécurité de la version s'il se trouve que je travaille sur la partie X ici et la partie Y ici, et peut fusionner si nécessaire.

Cependant, une seule de mes machines de développement a une adresse IP statique. Mon cerveau est bloqué en mode CVS, j'ai donc essayé de configurer git pour que cette machine soit le serveur «central», dont tous les autres tirent.

Ce genre de travaux. J'ai un tas de machines AC qui font un git-pull du 'master' M. Ils font des git push pour renvoyer les données.

Le problème vient si je fais du développement sur le maître. Tout d'abord, je ne peux pas comprendre comment obtenir le référentiel central pour fournir la dernière version sans faire

git reset --hard HEAD

ce qui semble un peu excessif. Et si je fais du développement sur la machine centrale avant de réinitialiser, je ne sais pas comment le fusionner avec des changements qui ont déjà été poussés.

Quelque chose au sujet de mon modèle mental est loin. Aidez-moi?

Alex Feinman
la source
Lorsque vous dites "maître", parlez-vous du référentiel maître ou de la branche maître?
innaM
référentiel maître
Alex Feinman
1
"master" dans le contexte git est généralement le nom de la branche par défaut.
innaM
cela appartient probablement à SO
Ken Liu

Réponses:

30

Vous souhaitez que votre référentiel central soit nu. Supposons que la machine sur laquelle elle vit s'appelle static:

$ ssh static git init --bare /git/myproject.git

Ce référentiel nu est un point de rendez-vous central: il sert à pousser et à tirer, pas à développer.

Faites votre développement sur les clones du référentiel central:

$ cd ~/src
$ git clone static:/git/myproject.git

Même si vous êtes sur static, travaillez en clone:

$ git clone /git/myproject.git

Bien que vous soyez le seul à travailler sur ce référentiel, prenez l'habitude de faire votre travail sur ce que la documentation de git appelle les branches de rubrique . Un avantage immédiat de ceci est qu'il garde un maître propre , c'est-à-dire que vous pouvez toujours tirer de votre branche principale centrale dans le maître de votre référentiel local actuel sans fusion.

Par exemple:

$ git checkout -b fix-bug-in-foo
$ hack
$ git add file.c file.h
$ git commit -m "Fix ..."

Cela peut ne pas sembler être un gros problème, mais cela vous donne la liberté de laisser le projet tel que représenté sur cette branche dans un état partiellement cuit, ou si votre idée cool se révèle être un flop, vous pouvez facilement jeter cette branche sans casser quoi que ce soit d'autre dans votre projet qui travaille déjà sur d'autres branches. Des mulligans gratuits à l'infini!

Peut-être que vous rentrez chez vous ce soir-là et ajouté une nouvelle fonctionnalité. Le lendemain matin, vous

$ git checkout master
$ git pull

pour mettre à jour votre maître local pour refléter ce qui se trouve dans le référentiel central.

Mais maintenant, dites que vous avez corrigé le bogue foo et êtes prêt à l'inclure dans votre branche principale. Vous voulez d'abord l'intégrer aux changements de la nuit dernière:

$ git checkout fix-bug-in-foo
$ git rebase master

La rebasecommande donne à votre référentiel l'impression que vous avez corrigé le bogue foo en plus de la nouvelle fonctionnalité de la nuit dernière. (C'est un peu comme svn update, mais plus flexible et puissant.)

Maintenant, pour l'obtenir dans votre maître central:

$ git checkout master
$ git merge fix-bug-in-foo
$ git push origin master

Nous traitons le maître comme spécial, mais ce n'est que conventionnel. Vous pouvez partager le travail sur différentes branches de différents référentiels via le référentiel git statictout aussi facilement.

Greg Bacon
la source
1
Réponse impressionnante, résout tous les problèmes à portée de main.
Dan Loewenherz
Mon installation de git n'accepte pas --bare comme option pour git init (ancienne version ??), mais j'ai contourné ce problème en clonant --bare mon référentiel existant, puis en éditant un peu manuellement les fichiers de configuration.
Alex Feinman
Si vous utilisez git 1.6.4.x, c'est git init --baresans aucun autre argument. Il utilisera le répertoire de travail actuel ou le paramètre d'environnement GIT_DIR s'il est défini. Je crois que vous avez besoin de git 1.6.5.x pour qu'il prenne un argument de répertoire.
Darren Hall,
4
C'est la meilleure explication de flux de travail git que j'ai vue jusqu'à présent pour le travail que je fais.
Greg Graham
8

Si vous avez un serveur central avec un référentiel git central, ce référentiel doit être un bareréférentiel. Les référentiels nus ne contiennent pas de copies de travail des fichiers. Par conséquent, si vous travaillez sur cette machine centrale, vous ne travaillez pas directement avec le référentiel central, mais avec un clone local.

innaM
la source
6

Cette réponse est similaire à la réponse de gbacon , mais adopte une approche selon laquelle vous avez déjà une configuration de référentiel local et que vous souhaitez créer un maître distant qui est traité comme un référentiel central. Il s'agit simplement d'ajouter des détails d'une approche différente.

J'utilise git pour stocker mes fichiers dot-config. Je pousse et tire de ce que je considère comme un «repo central». Il est très pratique de réinitialiser tous mes fichiers dot via plusieurs ordinateurs.

$ ssh example.com
$ mkdir dotconf.git && cd dotconf.git
$ git init --bare
$ exit

Cela a créé un dépôt nu vide sur le site de dépôt.

Maintenant, si j'ai déjà un dépôt local, je peux le pousser vers le site distant.

$ cd ~/src/dotconf

chdir dans le répertoire local.

$ git remote add origin ssh://example.com/~/dotconf.git

Ajoutez le référentiel distant comme origine, afin que push / pull agisse sur ce référentiel.

$ git push origin master

Poussez mon maître à l'origine (comme précédemment étiqueté via la télécommande git). Maintenant que le dépôt à distance est traité comme mon «dépôt central». Tous mes git push / pull interagiront avec l'origine.

Si je vais sur un autre hôte, je peux facilement tirer via un clone ce dépôt vers un nouvel emplacement.

$ git clone ssh://example.com/~/dotconf.git

Si je veux faire du développement sur le serveur distant, je clone d'abord, puis repousse / tire dans le référentiel nu.

$ cd ~/src
$ git clone ~/dotconf.git
$ cd ~/src/dotconf
  * do coding *
$ git push
  * check in from another location *
$ git pull

Vous devrez probablement régler votre git config --add branch.master.remote origindonc git pullne vous plaignez pas que vous n'êtes pas assez précis. L'autre alternative consiste à définir votre branche principale sur --trackl'origine distante. Utile si vous avez plusieurs succursales.

Darren Hall
la source
1

Je faisais juste des recherches sur ce même problème aujourd'hui. Ce blog post a beaucoup de discussions sur la question, mais l'opinion majoritaire est de faire ce que dit Manni. Regardez un commentaire sur le post de David French pour d'autres possibilités, y compris ce qu'il faut faire si vous finissez par pousser par erreur vers un référentiel qui a du travail non engagé dans l'index ou l'arborescence de travail. "git reset –soft HEAD ^" annulera le changement poussé sans perturber votre travail.

Greg Graham
la source
2
Un problème avec ce billet de blog est de sauter l'utilité de l'index. Voici un bon article pour expliquer comment travailler avec git au lieu de malgré git - osteele.com/archives/2008/05/my-git-workflow - des diagrammes de workflow sont inclus.
Darren Hall