64 votes

En quoi les greffes et remplacements Git diffèrent-ils? (Les greffons sont-ils désormais obsolètes?)

Il y a très peu de Q&A sur git grafts contre replace. La recherche [git] +greffes +remplacer seulement trouvé deux qui se sentait pertinentes de la 5. qu'est-ce-sont-git-info-greffes-pour et git-ce que-est-un-graftcommit-ou-un-greffon-id. Il y a aussi une note sur git.wiki.le noyau.org:GraftPoint

Sont des greffes maintenant complètement dépassé par l' replace et filter-branch, ou sont-ils encore nécessaires pour certains cas particuliers (et compatibilité) ?

En général, comment sont-ils différents (par exemple, qui sont transportés entre les pensions de titres), et comment sont-ils de façon générique les mêmes? J'ai vu que Lunus ne semble pas de soins sur les greffes à l'heure actuelle dans la discussion lors de la validation de la génération de nombres (de la max les parents à toutes les racines de la variété) "Greffons sont déjà pas fiables."

EDIT: plus d'info.
Une recherche de www.kernel.org/pub/software/scm/git/docs pour graft seulement trouvé 3 résultats:

  1. git-filter-branch(1),
  2. v1.5.4.7/git-filter-branch(1),
  3. v1.5.0.7/git-svn(1).

Un peu plus vaste recherche a trouvé RelNotes/1.6.5.txt qui contient:

  • refs/remplacer/ hiérarchie est conçu pour être utilisable comme un remplacement des "greffes" mécanisme, avec l'avantage supplémentaire qu'il peut être transféré à travers les référentiels.

Malheureusement, la gitrepository-mise en page(5) n'est pas encore à jour avec les refs/remplacer/ référentiel de mise en page info (et les notes), ni aucune dépréciation note d'info/greffes.

Cela se rapproche plus de l'appui de ce que je pensais mais j'avais bienvenue toute confirmation ou de clarification.

20voto

VonC Points 414372

Dans la même discussion à propos de Commettre un Numéro de Génération que vous évoquez, Jakub Narębski confirme que les greffons sont plus aproblem qu'une solution:

les greffes sont tellement horribles hack que je ne serait pas contre la désactivation de numéros de génération si elles sont utilisées.
Dans le cas de remplacer les objets dont vous avez besoin à la fois de la non-remplacé et remplacé DAG génération des nombres.
[...] Les greffes ne sont pas transférables, et si vous les utilisez pour le choisir plutôt que d'en ajouter de l'histoire, ils sont dangereux à l'encontre de la collecte des ordures... je pense.

(la publication a toujours été pris en charge avec le git filter-branch, comme le montre cette 2008 thread sur les greffes de flux de travail.)

La différence entre les greffes et git remplacer est le mieux illustré par ce DONC, la question "Configuration de git parent pointeur vers un autre parent", et les commentaires de (Jakub est encore) de réponse.

Il inclut la référence à Git1.6.5

Ce que je comprends (à partir de GraftPoints), git replace a remplacé git grafts (en supposant que vous avez git 1.6.5 ou plus tard)

(Jakub:)

  • si vous voulez réécrire l'histoire alors grafts + git-filter-branch (ou rebase interactif, rapide ou à l'exportation + par exemple reposurgeon) est la manière de le faire.
  • Si vous voulez/besoin de préserver l'histoire, alors git-replace est de loin supérieure à la greffe

14voto

Adrian Macneil Points 5339

Si vous avez besoin de réécrire un parent valider à l'aide de git replace, c'est la façon de le faire.

Philip Oakley mentionné, git remplacer remplace simplement un commit avec l'autre. Pour les greffer sur un parent à un commit, vous devez d'abord créer un faux engager avec le bon parent.

Disons que vous avez deux branches git vous voulez greffe:

(a)-(b)-(c) (d)-(e)-(f)

Maintenant, nous voulons (d) à être le parent de (c). Nous avons donc créer un remplacement pour (c) avec le parent correcte (appelons cette c1), alors git replace (c) avec (c1). Dans ces étapes, chacune des lettres désigne le hash SHA1 représentant qui s'engagent.

Pour créer le nouveau commit:

git checkout d
git rm -rf * # remove all files from working direcotry
git checkout c -- . # commit everything from c over top of it
GIT_AUTHOR_DATE="..." GIT_COMMITTER_DATE="..." git commit -m "..." # create replacement commit with date author

Maintenant, vous avez commit (c1) qui a le bon parent (d). Donc, tout ce que nous devons faire est de remplacer l'existant (c) avec (c1):

git replace c c1

Maintenant, votre histoire ressemble à ceci:

(a)-(b)-(c1)-(d)-(e)-(f)

Bingo!

9voto

Esko Luontola Points 53877

Autant que je sache, il y a un cas d'utilisation qui grafts pouvez manipuler, mais replace ne peut pas: ajout ou suppression de parents. C'est un puissant outil de refactoring des histoires.

Par exemple, si vous importez l'histoire d'un ancien dépôt SVN vers Git, il n'y a pas de fusion d'informations. Ce que vous pouvez faire (et j'en ai fait des tas de fois) est à lire par le biais de la validation des messages pour savoir où un SVN "fusion" a été fait, et ensuite utiliser Git greffes pour ajouter un parent à la fusion de la validation.

Autant que je me souvienne, j'ai aussi eu quelques cas où j'ai enlevé le parent d'un commit, dans le but d'en faire le premier commit dans l'histoire. La création d'un propre histoire basée sur de multiples chaotique héritage dépôts nécessite parfois des mesures drastiques (il y a des expériences de la migration de projets Git sur mon blog).

Puis, après que vous avez nettoyé l'ensemble de l'histoire, vous feriez un git filter-branch avant la publication du nouveau dépôt Git.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X