Existe-t-il une version «la leur» de «git merge -s ours»?


876

Lors de la fusion de la branche de rubrique "B" dans "A" à l'aide de git merge, j'obtiens des conflits. Je sais que tous les conflits peuvent être résolus en utilisant la version en "B".

J'en suis conscient git merge -s ours. Mais ce que je veux, c'est quelque chose git merge -s theirs.

Pourquoi ça n'existe pas? Comment puis-je obtenir le même résultat après la fusion conflictuelle avec les gitcommandes existantes ? ( git checkoutchaque fichier non fusionné de B)

MISE À JOUR: La "solution" consistant à simplement supprimer quoi que ce soit de la branche A (le point de validation de fusion vers la version B de l'arborescence) n'est pas ce que je recherche.


1
Voir également cette réponse: stackoverflow.com/questions/928646/… - il est trivial de changer l'exemple pour utiliser la version B au lieu de A.
Robie Basak

8
Voir la commande SO answer git pour créer une branche comme une autre pour toutes les façons possibles de simulergit merge -s their .
VonC

4
Donc, vous ne cherchez pas vraiment un git merge -s theirs(qui peut être réalisé facilement avec git merge -s oursune branche temporaire), car la nôtre ignore complètement les changements de la branche de fusion ...
Nicolò Martini

21
@Torek - ne le Git devs vraiment trouvent que l' offensive de fournir theirsen plus ours??? Il s'agit d'un symptôme d'un des problèmes d'ingénierie et de conception de haut niveau dans Git: l'incohérence.
jww

3
@jww Le problème ici n'est pas que "git merge -s ours" soit offensant, mais qu'il soit contre-intuitif. Vous pouvez voir dans la question de l'OP que si une telle fonctionnalité était ajoutée, il l'utiliserait par erreur alors que ce qu'il veut réellement faire est un "git merge -s récursif -X leur". Il est courant de vouloir fusionner une autre branche en remplaçant les conflits avec la version de l'autre branche, mais le remplacement complet de la branche actuelle par une autre branche rejetant complètement les modifications de celle-ci est vraiment un cas d'exception.
ThomazMoura

Réponses:


1020

Ajoutez l' -Xoption à theirs. Par exemple:

git checkout branchA
git merge -X theirs branchB

Tout fusionnera de la manière souhaitée.

La seule chose que j'ai vue causer des problèmes est si les fichiers ont été supprimés de branchB. Ils apparaissent comme des conflits si autre chose que git a fait la suppression.

La solution est simple. Exécutez simplement git rmavec le nom des fichiers supprimés:

git rm {DELETED-FILE-NAME}

Après cela, le -X theirsdevrait fonctionner comme prévu.

Bien sûr, effectuer la suppression réelle avec la git rmcommande empêchera le conflit de se produire en premier lieu.


Remarque : une option de formulaire plus longue existe également.

Pour l'utiliser, remplacez:

-X theirs

avec:

--strategy-option=theirs

6
Voir l'autre réponse ci-dessous pour une meilleure solution (Paul Pladijs) à la question d'origine.
Malcolm

204
Il convient de noter que ce n'est pas la même chose que la «stratégie de fusion theirs». -Xtheirs est l' option stratégique appliquée à la stratégie récursive . Cela signifie que la stratégie récursive fusionnera toujours tout ce qu'elle peut et ne retombera dans "leur" logique qu'en cas de conflit. Bien que ce soit ce dont on a besoin dans la plupart des cas comme ci-dessus, ce n'est pas la même chose que "tout prendre tel quel de la branche B". De toute façon, il fait la fusion réelle.
Timur

2
Il fonctionne également avec d'autres commandes. Je viens de faire un 'git cherry-pick sha1 -X leur'. Merci!
Max Hohenegger

48
C'est une réponse terrible, car elle semble correcte, mais elle est en fait fausse. "git merge -X leur" ne fait pas ce que "git merge -s leur" ferait. Il ne remplace pas la branche actuelle par le contenu de la branche fusionnée. Il préfère «leurs» changements, mais uniquement en cas de conflit. Par conséquent, la validation résultante peut être très différente de la branche "leur". Ce n'est pas ce que l'affiche de la question avait en tête.
Ivan Krivyakov

7
@ user3338098: oui, vous avez raison. J'ai relu la question, et elle n'est pas non plus aussi bonne. Malheureusement, la cause profonde de la confusion n'est pas la réponse ni même la question. C'est le choix de conception des auteurs de git de donner le même nom «nôtre» à une stratégie de fusion et à une option de stratégie de fusion «récursive». La confusion dans ce cas est pratiquement inévitable.
Ivan Krivyakov le

218

Une solution possible et testée pour fusionner la brancheB dans notre branche extraiteA:

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

Pour l'automatiser, vous pouvez l'encapsuler dans un script en utilisant branchA et branchB comme arguments.

Cette solution préserve le premier et le deuxième parent du commit de fusion, comme vous pouvez vous y attendre git merge -s theirs branchB.


Q: Pourquoi avez-vous besoin de branchTEMP? Pourriez-vous pas juste git reset --soft branchA?
cdunn2001

4
@ cdunn2001: D'une certaine manière, je pensais la même chose, mais non. Notez que les git reset --hardchangements qui valident branchApointent vers.
Tsuyoshi Ito

5
désolé de poser une question stupide, mais pourquoi cette méthode est-elle meilleure pour les héritiers? quels sont les avantages / inconvénients
chrispepper1989

9
@ chrispepper1989 -x le leur n'affecte que les conflits , si un de nos morceaux peut être appliqué proprement, il parviendra à la fusion résultante. Dans ce cas, comme le montre la dernière commande, nous obtenons une fusion parfaitement identique à branchB, qu'il y ait eu ou non des conflits.
UncleZeiv

2
@UncleZeiv merci pour l'explication, donc en gros faire un "leur" garderait les modifications et les fichiers non conflictuels résultant du code int qui n'est pas identique au code extrait.
chrispepper1989

89

Les versions plus anciennes de git vous permettaient d'utiliser la stratégie de fusion "leur":

git pull --strategy=theirs remote_branch

Mais cela a depuis été supprimé, comme expliqué dans ce message par Junio ​​Hamano (le responsable de Git). Comme indiqué dans le lien, vous feriez plutôt ceci:

git fetch origin
git reset --hard origin

Attention, cependant, c'est différent d'une fusion réelle. Votre solution est probablement l'option que vous recherchez vraiment.


7
Je ne comprends vraiment pas du tout l'explication de Junio ​​Hamano. Comment git reset --hard originune solution pour une fusion de leur style? Si je voulais fusionner BranchB dans BranchA (comme dans la réponse d'Alan W. Smith), comment le ferais-je en utilisant la resetméthode?
James McMahon

3
@James McMahon: le point de Junio ​​C Hamano n'est pas git reset --hardune fusion de style «le leur». Bien sûr, git reset --hardne crée aucun commit de fusion, ni aucun commit d'ailleurs. Son argument est que nous ne devons pas utiliser une fusion pour remplacer quoi que ce soit dans HEAD par autre chose. Cependant, je ne suis pas nécessairement d'accord.
Tsuyoshi Ito

11
Il est dommage que le ait theirsété supprimé car la justification était incomplète. Il n'a pas permis les cas où le code est bon, c'est juste que l'amont est maintenu sur une base philosophique différente, donc en ce sens est `` mauvais '', donc on veut à la fois se tenir à jour avec l'amont, mais en même temps conserver les bons «correctifs» de code [git & msysgit ont certains de ces «conflits» à cause des philosophies de leur plate-forme cible différente]
Philip Oakley

1
Il manque également le cas d'utilisation avec lequel je suis coincé en ce moment, où je partage une branche avec quelqu'un d'autre et que nous avons tous les deux poussé des modifications (sur des fichiers différents) en même temps. Je veux donc encombrer toutes les anciennes versions que j'ai localement et utiliser ses plus récentes à la place. Il veut faire de même pour les fichiers que j'ai mis à jour. Il n'y a rien à «réinitialiser». Et la solution pour extraire chaque fichier individuel n'est pas pratique quand il s'agit de ~ 20 fichiers.
szeitlin

2
Je ne comprends vraiment pas la philosophie. Je viens de l'utiliser theirsparce que j'avais accidentellement modifié certains fichiers dans deux branches distinctes et que je voulais annuler les modifications d'une seule sans avoir à le faire manuellement pour chaque fichier.
sudo

65

Il n'est pas tout à fait clair quel est votre résultat souhaité, il y a donc une certaine confusion sur la façon "correcte" de le faire dans les réponses et leurs commentaires. J'essaie de donner un aperçu et de voir les trois options suivantes:

Essayez de fusionner et utilisez B pour les conflits

Ce n'est pas la "leur version pour git merge -s ours" mais la "leur version pour git merge -X ours" (qui est l'abréviation de git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

C'est ce que fait par exemple la réponse d'Alan W. Smith .

Utiliser uniquement le contenu de B

Cela crée un commit de fusion pour les deux branches mais rejette toutes les modifications branchAet ne conserve que le contenu branchB.

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

Notez que la fusion valide maintenant le premier parent est celle de branchBet que le second est de branchA. C'est ce que fait par exemple la réponse de Gandalf458 .

Utilisez le contenu de B uniquement et conservez l'ordre parent correct

Ceci est la vraie "leur version pour git merge -s ours". Il a le même contenu que dans l'option précédente (c'est-à-dire seulement celui de branchB) mais l'ordre des parents est correct, c'est-à-dire que le premier parent vient branchAet le second de branchB.

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

C'est ce que fait la réponse de Paul Pladijs (sans nécessiter de succursale temporaire).


Une version plus propre de l' option 3:git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commit
jthill

@jthill: Bien que votre version soit plus concise, elle utilise également la commande de bas niveau ("plomberie") à read-treelaquelle l'utilisateur Git moyen n'est peut-être pas habitué (du moins je ne le suis pas ;-)). Les solutions de la réponse utilisent uniquement les commandes de haut niveau ("porcelaine") que la plupart des utilisateurs de git doivent connaître. Je les préfère mais merci pour ta version quand même!
siegi

Pouvez-vous expliquer l'avant-dernière étape (branche de paiement A)? Il semble que cela ne devrait pas être là.
Patrick

@Patrick, cette étape est obligatoire. Si vous l'ignorez, vous obtiendrez le même commit mais vous n'auriez pas de branche pointant vers ce commit. Donc, dès que vous passez à une autre commit / branche, la commit que vous avez faite avec la dernière commande ( …commit --amend…) serait "perdue". Je prévois d'ajouter quelques explications graphiques à cette réponse dès que j'aurai le temps de les faire… ;-)
siegi

62

J'ai utilisé la réponse de Paul Pladijs depuis maintenant. J'ai découvert que vous pouvez effectuer une fusion "normale", des conflits se produisent,

git checkout --theirs <file>

pour résoudre le conflit en utilisant la révision de l'autre branche. Si vous procédez ainsi pour chaque fichier, vous avez le même comportement que vous attendez de

git merge <branch> -s theirs

Quoi qu'il en soit, l'effort est plus qu'il ne le serait avec la stratégie de fusion! (Ceci a été testé avec git version 1.8.0)


1
serait formidable si la liste des fichiers pouvait être récupérée. Par exemple, git ls-files --modified | xargs git addje voulais le faire pour l'ajout de la fusion des deux côtés: /
andho

En fait, git renvoie les fichiers ajoutés des deux côtés avec git ls-files --modifieddonc je suppose que c'est également une solution viable.
andho

1
Merci d'avoir ajouté cela aussi. Plus souvent, ce n'est pas nécessaire sur une base fichier par fichier. En outre, l'état git affiche "Chemins non fusionnés" tout en bas. Pour obtenir la liste des chemins non résolus, j'utilise cet alias:git config --global alias.unresolved '!git status --short|egrep "^([DAU])\1"'
Melvyn

Quelle est la signification de -Xet quelle est la différence entre -Xet -s? ne trouve aucun document.
Lei Yang

21

J'ai résolu mon problème en utilisant

git checkout -m old
git checkout -b new B
git merge -s ours old

une branche "B" de la "vieille" branche
elmarco

13

Lors de la fusion de la branche de rubrique "B" dans "A" à l'aide de git merge, j'obtiens des conflits. Je> sais que tous les conflits peuvent être résolus en utilisant la version en "B".

Je suis au courant de la fusion de git - nôtre. Mais ce que je veux, c'est quelque chose comme git merge> -s leur.

Je suppose que vous avez créé une branche hors de master et que vous souhaitez maintenant fusionner à nouveau dans master, en remplaçant les anciens éléments de master. C'est exactement ce que je voulais faire quand je suis tombé sur ce post.

Faites exactement ce que vous voulez faire, sauf d'abord fusionner une branche dans l'autre. Je viens de le faire et cela a très bien fonctionné.

git checkout Branch
git merge master -s ours

Ensuite, passez en caisse maître et fusionnez votre branche en elle (ça se passera bien maintenant):

git checkout master
git merge Branch

1
Merci. Cela devrait être la réponse acceptée, de loin la plus simple et la plus correcte. Si votre branche est en retard / en conflit avec le maître, alors c'est la tâche de la branche à fusionner et à tout faire fonctionner avant de fusionner tout à nouveau au maître.
StackHola

Cela a très bien fonctionné, merci.
Kodie Grantham

12

Si vous êtes sur la branche A, faites:

git merge -s recursive -X theirs B

Testé sur git version 1.7.8


8

Pour faire vraiment correctement une fusion qui ne prend que les entrées de la branche que vous fusionnez, vous pouvez le faire

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

Il n'y aura aucun conflit dans les scénarios que je connaisse, vous n'avez pas à créer de branches supplémentaires, et cela agit comme un commit de fusion normal.

Cependant, cela ne fonctionne pas bien avec les sous-modules.


Que fait le -R ici?
P. Myer Nore

De cette façon, vous perdez l'historique des fichiers "déplacés et modifiés". Ai-je raison?
elysch

1
Le -R est --reverse, j'ai mis à jour la réponse avec cela pour être plus auto-documenté.
Elijah Lynn

Cela ne semble pas fonctionner si les fichiers que vous essayez de fusionner sont supprimés dans la branche entrante.
resolutionJ

7

Pourquoi ça n'existe pas?

Alors que je mentionne dans " git command pour faire une branche comme une autre " comment simuler git merge -s theirs, notez que Git 2.15 (Q4 2017) est maintenant plus clair:

La documentation pour « -X<option>» pour les fusions a été rédigée à tort pour suggérer que « -s theirs» existe, ce qui n'est pas le cas.

Voir commit c25d98b (25 sept. 2017) de Junio ​​C Hamano ( gitster) .
(Fusionné par Junio ​​C Hamano - gitster- en commit 4da3e23 , 28 sept. 2017)

fusion-stratégies: éviter de laisser entendre que " -s theirs" existe

La description de l' -Xoursoption de fusion a une note entre parenthèses qui indique aux lecteurs qu'elle est très différente de -s ours, ce qui est correct, mais la description -Xtheirsqui suit la dit négligemment "c'est le contraire de ours", donnant une fausse impression que les lecteurs ont également besoin être averti qu'il est très différent de -s theirs, qui en réalité n'existe même pas.

-Xtheirsest une option de stratégie appliquée à la stratégie récursive. Cela signifie que la stratégie récursive fusionnera tout ce qu'elle peut et ne retombera sur la " theirs" logique qu'en cas de conflit.

Ce débat sur la pertinence ou non d'une theirsstratégie de fusion a été ramené récemment dans ce fil de septembre 2017 .
Il reconnaît les anciens threads (2008)

En bref, la discussion précédente peut se résumer à «nous ne voulons pas -s theirs» car elle encourage le mauvais flux de travail ».

Il mentionne l'alias:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

Yaroslav Halchenko essaie à nouveau de plaider pour cette stratégie, mais Junio ​​C. Hamano ajoute :

La raison pour laquelle la nôtre et la leur n'est pas symétrique est parce que vous êtes vous et non eux --- le contrôle et la propriété de notre histoire et de leur histoire ne sont pas symétriques.

Une fois que vous avez décidé que leur historique est la ligne principale, vous préférez traiter votre ligne de développement comme une branche latérale et effectuer une fusion dans cette direction, c'est-à-dire que le premier parent de la fusion résultante est un commit sur leur histoire et le second le parent est le dernier mauvais de votre histoire. Vous finirez donc par utiliser " checkout their-history && merge -s ours your-history" pour garder la première parenté raisonnable.

Et à ce stade, l'utilisation de " -s ours" n'est plus une solution de contournement faute de " -s theirs".
C'est une partie appropriée de la sémantique souhaitée, c'est-à-dire que du point de vue de la ligne d'histoire canonique survivante, vous voulez préserver ce qu'elle a fait, annulant ce que l'autre ligne d'histoire a fait .

Junio ​​ajoute, comme l'a commenté Mike Beaton :

git merge -s ours <their-ref>dit effectivement «marquer les commissions faites <their-ref>sur leur branche comme des commissions à ignorer en permanence»;
et cela est important parce que, si vous fusionnez par la suite à partir des états ultérieurs de leur branche, leurs modifications ultérieures seront apportées sans que les modifications ignorées soient apportées .


1
C'est une réponse utile, mais elle ne mentionne pas un point clé que je viens de comprendre de la réponse de Junio ​​C. Hamano: git merge -s ours <their-ref>dit effectivement 'marquer les commits constitués jusqu'à <their-ref> sur leur branche comme commits à ignorer de façon permanente » et cela est important parce que, si vous fusionnez par la suite à partir d'états ultérieurs de leur branche, leurs modifications ultérieures seront apportées sans que les modifications ignorées soient apportées.
MikeBeaton

1
@MikeBeaton Merci. J'ai inclus votre commentaire dans la réponse pour plus de visibilité.
VonC

5

Voir la réponse largement citée de Junio ​​Hamano : si vous souhaitez supprimer le contenu validé, supprimez simplement les validations ou, en tout cas, conservez-le hors de l'historique principal. Pourquoi déranger tout le monde à l'avenir en lisant les messages de validation des validations qui n'ont rien à offrir?

Mais parfois, il y a des exigences administratives, ou peut-être une autre raison. Pour les situations où vous devez vraiment enregistrer des commits qui ne contribuent à rien, vous voulez:

(edit: wow, ai-je réussi à me tromper avant. Celui-ci fonctionne.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard

3

Celui-ci utilise un arbre de lecture de commande de plomberie git, mais permet un flux de travail global plus court.

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>

0

Cela fusionnera votre newBranch dans la baseBranch existante

git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch

Je suggérerais d'ajouter git commit --amendà la fin de votre exemple, ou les utilisateurs peuvent voir la fusion avec git loget supposer que l'opération est terminée.
Michael R

0

Je pense que ce que vous voulez réellement c'est:

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

Cela semble maladroit, mais cela devrait fonctionner. La seule chose que je n'aime vraiment pas dans cette solution est que l'historique de git sera déroutant ... Mais au moins, l'historique sera complètement préservé et vous n'aurez pas besoin de faire quelque chose de spécial pour les fichiers supprimés.


0

L'équivalent (qui garde l'ordre parent) de 'git merge -s theirs branchB'

Avant la fusion:entrez la description de l'image ici

!!! Assurez-vous que vous êtes dans un état propre !!!

Faites la fusion:

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command

Ce que nous avons fait ? Nous avons créé un nouveau commit dont deux parents, le nôtre et le leur, et le contnet du commit est branchB - le leur

Après la fusion:entrez la description de l'image ici

Plus précisément:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'

0

Cette réponse a été donnée par Paul Pladijs. J'ai juste pris ses commandes et fait un alias git pour plus de commodité.

Modifiez votre .gitconfig et ajoutez ce qui suit:

[alias]
    mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"

Ensuite, vous pouvez "git merge -s theirs A" en exécutant:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

-1

J'ai récemment eu besoin de le faire pour deux référentiels distincts qui partagent une histoire commune. J'ai commencé avec:

  • Org/repository1 master
  • Org/repository2 master

Je voulais que toutes les modifications repository2 mastersoient appliquées à repository1 master, en acceptant toutes les modifications que repository2 apporterait. En termes de git, cela devrait être une stratégie appelée -s theirsMAIS elle n'existe pas. Soyez prudent car il -X theirsest nommé comme il serait ce que vous voulez, mais ce n'est PAS le même (il le dit même dans la page de manuel).

La façon dont j'ai résolu cela était d'aller repository2et de créer une nouvelle branche repo1-merge. Dans cette branche, j'ai couru git pull git@gitlab.com:Org/repository1 -s ourset ça fusionne bien sans aucun problème. Je le pousse ensuite vers la télécommande.

Ensuite, je retourne repository1et crée une nouvelle branche repo2-merge. Dans cette branche, je coursgit pull git@gitlab.com:Org/repository2 repo1-merge ce qui se terminera par des problèmes.

Enfin, vous devrez soit émettre une demande de fusion repository1pour en faire le nouveau maître, soit simplement la conserver en tant que branche.


-2

Une façon simple et intuitive (à mon avis) de le faire en deux étapes est

git checkout branchB .
git commit -m "Picked up the content from branchB"

suivi par

git merge -s ours branchB

(qui marque la fusion des deux branches)

Le seul inconvénient est qu'il ne supprime pas les fichiers qui ont été supprimés dans branchB de votre branche actuelle. Un simple diff entre les deux branches montrera ensuite s'il existe de tels fichiers.

Cette approche montre également clairement à partir du journal de révision ce qui a été fait - et ce qui était prévu.


cela peut être correct pour la question d'origine, mais le PO a mis à jour la question en 2008 de telle manière que cette réponse est incorrecte.
user3338098

1
@ user3338098 Ouais, vraiment dommage qu'ils ont quitté le titre trompeur et juste giflé une mise à jour pas si visible à la fin du corps de question .... parce que cette réponse ne répond pas correctement à la question du titre.
RomainValeri

Je suis entièrement d'accord avec @RomainValeri
AppleCiderGuy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.