1016 votes

Est-il possible d'extraire un commit d'un autre dépôt git ?

Je travaille avec un dépôt git qui a besoin d'un commit d'un autre dépôt git qui ne sait rien du premier.

En général, je fais un tri sélectif en utilisant la méthode HEAD@{x} dans le reflog, mais parce que cette .git ne sait rien de cette entrée reflog (répertoire physique différent), comment puis-je extraire ceci, ou puis-je le faire ?

J'utilise git-svn . Ma première branche utilise git-svn de la trunk d'un repo Subversion, et la branche suivante utilise git-svn sur une branche de Subversion.

2 votes

C'est la raison donnée par Ben Lee pour avoir ouvert une prime sur cette question : " Je vais attribuer le bounty à la bonne réponse, plutôt à la réponse acceptée. Je dois juste attendre 24 [heures] pour le faire". Cependant, je ne comprends pas laquelle de ces réponses est censée être "la bonne réponse", et pourquoi la réponse acceptée n'est pas "bonne".

2 votes

La nature du problème n'est pas claire. Comment ces différents dépôts sont-ils liés, si tant est qu'ils le soient ? L'un est-il un fork d'un autre ? Ou bien s'agit-il en fait de deux projets complètement séparés et non liés ?

0 votes

@Cupcake, la réponse acceptée est bonne, et a clairement aidé le PO, donc elle devrait être acceptée. Par "bonne", je voulais simplement dire "bonne pour moi" (et à en juger par les commentaires, bonne pour plusieurs autres personnes aussi). J'ai simplement pensé que la réponse à laquelle j'ai donné la prime méritait autant de reconnaissance que la réponse acceptée.

1051voto

Robert Wahler Points 2320

La réponse, telle qu'elle a été donnée, est d'utiliser format-patch, mais puisque la question portait sur la façon d'extraire des informations d'un autre dossier, voici un morceau de code pour le faire :

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k

Explication du Cong Ma commentaire 28 août '14

La commande git format-patch crée un patch à partir du commit de some_other_repo. spécifié par son SHA (-1 pour un seul commit). Ce patch est pipé vers git am, qui applique le patch localement (-3 signifie qu'il faut tenter la fusion à trois si le patch ne s'applique pas proprement).

0 votes

@BenLee merci pour le Rep ! Je l'apprécie. J'utilise ma méthode plutôt que la réponse acceptée pour les forks connexes lorsqu'il y a un mélange de licences impliquées. Je contrôle le fait de garder le code propre.

37 votes

C'est tout à fait exact, mais ce serait formidable si quelqu'un pouvait développer ce point - une ventilation de ce qui se passe exactement (surtout avec ces drapeaux) serait incroyablement utile.

66 votes

@NickF, le git format-patch La commande crée un patch à partir de some_other_repo Le commit de l'utilisateur est spécifié par son SHA ( -1 pour un seul engagement). Ce patch est envoyé à git am qui applique le patch localement ( -3 signifie essayer la fusion à trois si le patch ne s'applique pas proprement). J'espère que cela explique tout.

907voto

CharlesB Points 27070

Vous devrez ajouter l'autre dépôt en tant que dépôt distant, puis récupérer ses changements. De là, vous verrez le commit et vous pourrez le sélectionner.

Comme ça :

git remote add other https://example.link/repository.git
git fetch other

Maintenant vous avez toutes les informations pour faire simplement git cherry-pick .

Une fois terminé, vous pouvez retirer la télécommande, si vous n'en avez plus besoin, avec

git remote remove other

Plus d'informations sur le travail avec les télécommandes ici : https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes

1 votes

Et si j'utilise git-svn ? Ma première branche utilise git-svn du tronc et la suivante utilise git-svn sur une branche (merci pour la réponse rapide).

0 votes

@gitcoder182 : pas sûr puisque je n'ai jamais utilisé git-svn, mais ça devrait fonctionner.

1 votes

Lorsque vous clonez pour la première fois le dépôt Subversion, assurez-vous de cloner le fichier tout le site et pas seulement le tronc. Assurez-vous également d'utiliser l'option --stdlayout de git-svn si vous utilisez la disposition standard trunk/branches/tags dans Subversion. Alors la branche Subversion sera une simple branche git distante.

197voto

Brian Points 563

Voici un exemple de remote-fetch-merge.

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB

Alors vous pouvez :

git cherry-pick <first_commit>..<last_commit>

ou vous pourriez même fusionner la branche entière (seulement si vous avez vraiment besoin de tout fusionner)

git merge projectB/master

72 votes

git merge projectB/master est très, très mal car vous n'appliquez pas les changements d'une seule livraison (comme le ferait un cherry-pick), vous fusionnez en fait dans tous les changements en projectB/master qui ne sont pas contenues dans votre propre master branche.

6 votes

J'ai supposé que c'était l'intention de l'affiche originale. Sinon, oui, ce n'est pas la bonne option pour eux.

8 votes

Cela fonctionne parfaitement lorsque les deux référentiels sont liés.

184voto

The Doctor What Points 4454

Vous pouvez le faire, mais cela nécessite deux étapes. Voici comment :

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

Remplacer <remote-git-url> avec l'url ou le chemin d'accès au dépôt dont vous voulez extraire des informations.

Remplacer <branch> avec le nom de la branche ou de l'étiquette que vous voulez extraire du dépôt distant.

Vous pouvez remplacer FETCH_HEAD avec un git SHA de la branche.

Mis à jour : modifié sur la base des commentaires de @pkalinow.

13 votes

Cela fonctionne avec un nom de branche, mais pas avec SHA. Si vous voulez choisir un commit désigné par son hash, utilisez ceci à la place : git fetch <repo-url> <branch> && git cherry-pick <sha> .

0 votes

Merci. C'est exactement ce dont j'avais besoin pour insérer un certain nombre de commits d'un dépôt à un autre, que j'ai créé à cet effet.

0 votes

C'est exactement ce dont j'avais besoin avec de nombreuses implémentations personnalisées de notre code pour différents clients (qui ont chacun leurs propres dépôts/forks), nous avions besoin d'un moyen d'obtenir des commits spécifiques dans notre base/trunk. MERCI !

67voto

jaredwilli Points 2215

Voici les étapes pour ajouter une télécommande, récupérer des branches, et extraire un commit.

# Cloning our fork
$ git clone git@github.com:ifad/rest-client.git

# Adding (as "endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git

# Fetch their branches
$ git fetch endel

# List their commits
$ git log endel/master

# Cherry-pick the commit we need
$ git cherry-pick 97fedac

Source : https://coderwall.com/p/sgpksw

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