Y a-t-il une version "à eux" de "git merge-ours"?

en fusionnant la branche de sujet " B "en" A "en utilisant git merge , j'obtiens quelques conflits. Je sais que tous les conflits peuvent être résolus en utilisant la version en "B".

je suis au courant de git merge -s ours . Mais ce que je veux, c'est quelque chose comme git merge -s theirs .

pourquoi n'existe-t-il pas? Comment obtenir le même résultat après la fusion conflictuelle avec les commandes git existantes? ( git checkout chaque désinstallé le fichier à partir de B)

mise à jour: le "solution" de simplement jeter n'importe quoi de la branche A (la commit point de fusion à la version B de l'arbre) n'est pas ce que je cherche.

688
demandé sur elmarco 2008-10-06 15:16:43
la source

18 ответов

ajouter l'option -X à theirs . Par exemple:

git checkout branchA
git merge -X theirs branchB

tout se fondra de la manière désirée.

la seule chose que j'ai vu 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 le déplacement.

le fix est facile. Il suffit d'exécuter git rm avec le nom de tous les fichiers qui ont été supprimés:

git rm {DELETED-FILE-NAME}

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

bien sûr, le fait de procéder au retrait réel avec la commande git rm empêchera le conflit de se produire en premier lieu.


Note : une option plus longue existe également. Pour l'utiliser, remplacer:

-X theirs

avec:

--strategy-option=theirs
801
répondu Alan W. Smith 2018-03-02 01:08:21
la source

une solution possible et éprouvée pour fusionner branchB dans notre branchA:

# 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'envelopper dans un script en utilisant branchA et branchB comme arguments.

cette solution préserve le premier et le second parent de la commit de fusion, comme vous vous y attendiez de git merge -s theirs branchB .

184
répondu Paul Pladijs 2014-07-25 07:22:44
la source

les anciennes versions de git vous ont permis d'utiliser la stratégie de fusion "la leur":

git pull --strategy=theirs remote_branch

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

git fetch origin
git reset --hard origin

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

79
répondu Pat Notz 2018-10-06 04:53:03
la source

j'ai utilisé la réponse de Paul Pladijs depuis maintenant. J'ai trouvé, vous pouvez faire un "normal" de fusion, les conflits se produisent, de sorte que vous ne

git checkout --theirs <file>

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

git merge <branch> -s theirs

de toute façon, l'effort est plus qu'il ne le serait avec la fusion-stratégie! (Cela a été testé avec la version 1.8.0 de git)

53
répondu musicmatze 2012-11-03 16:51:12
la source

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

Essayer de fusion et l'utilisation de B de conflits", 1519180920"

c'est pas la" leur version pour git merge -s ours "mais la" leur version pour git merge -X ours " git merge -s recursive -X ours ):

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

c'est ce que fait p. ex. la réponse D'Alan W. Smith .

utiliser le contenu de B seulement

"

cela crée une commit de fusion pour les deux branches mais écarte toutes les modifications de branchA et garde seulement le contenu de 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 engage le premier parent maintenant est celui de branchB et seulement la seconde est de branchA . C'est ce que fait par exemple la réponse de Gandalf458 .

utiliser le contenu de B seulement et conserver l'ordre parent correct

C'est la vraie "leur version pour git merge -s ours ". Il a le même contenu que dans l'option précédente (i.e. seulement celui de branchB ) mais l'ordre des parents est correct, i.e. le premier parent vient de branchA et 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 la réponse de Paul Pladijs fait (sans exiger une branche temporaire).

47
répondu siegi 2017-05-23 14:33:26
la source

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

git checkout -m old
git checkout -b new B
git merge -s ours old
21
répondu elmarco 2008-10-06 15:34:59
la source

si vous êtes sur la branche a faire:

git merge -s recursive -X theirs B

testé sur Git version 1.7.8

13
répondu rafalmag 2012-04-12 23:17:23
la source

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

je suis au courant de git merge-ours. Mais ce que je veux, c'est quelque chose comme git merge.

je suis en supposant que vous avez créé une branche de master et vous souhaitez fusionner en maître, ignorant tout de l'ancien maître. C'est exactement ce que je voulais à faire quand je suis tombé sur ce post.

faites exactement ce que vous voulez faire, sauf fusionner d'abord l'une des branches dans l'autre. J'ai juste fait ça, et ça a très bien fonctionné.

git checkout Branch
git merge master -s ours

puis, le maître de caisse et fusionner votre branche dans elle (il va se passer en douceur maintenant):

git checkout master
git merge Branch
8
répondu Gandalf458 2015-08-27 11:36:53
la source

pour vraiment faire correctement une fusion qui prend seulement entrée de la branche que vous fusionnez vous pouvez 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 n'importe quel scénario que je connais, vous n'avez pas à faire des branches supplémentaires, et il agit comme une commit normale de fusion.

cela ne joue pas bien avec les sous-modules cependant.

6
répondu thoutbeckers 2017-07-21 02:16:59
la source

Voir Junio Hamano est largement cité réponse : si vous allez jeter commis de contenu, juste jeter la commet, ou en tout cas de le garder hors de la main de l'histoire. Pourquoi déranger tout le monde à l'avenir lire commettre des messages de commits qui n'ont rien à offrir?

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

(edit: wow, j'ai réussi à obtenir cette erreur 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
4
répondu jthill 2015-02-15 17:47:08
la source

celui-ci utilise un arbre de lecture de la 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>
1
répondu Michael R 2015-04-22 22:18:40
la source

pourquoi n'existe-t-il pas?

tandis que je mentionne dans la commande git 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 était trompeuse écrit pour suggérer que " -s theirs " existe, ce qui n'est pas le cas.

Voir commettre c25d98b (25 septembre 2017) par Junio C Hamano ( gitster ) .

(fusionné par Junio CA Hamano -- gitster -- in commit 4da3e23 , 28 Sep 2017)

merge-strategies: Evite d'insinuer que " -s theirs "existe

la description de -Xours option de fusion a une incidente cela dit aux lecteurs qu'il est très différent de -s ours , ce qui est correct, mais la description de -Xtheirs qui le suit dit imprudemment "c'est le contraire de ours ", donnant un faux impression que les lecteurs doivent également être avertis qu'il est très différent de -s theirs , qui en réalité n'existe même pas.

-Xtheirs est un stratégie de l'option appliquée à la stratégie récursive. Cela signifie que la stratégie récursive fusionnera toujours tout ce qu'elle peut, et ne reviendra qu'à la logique " theirs " en cas de conflit.

que le débat pour la pertinence ou non d'une stratégie de fusion theirs a été ramené récemment dans ce Sept. 2017 fil .

Il reconnaît plus vieux (2008) fils

en bref, la discussion précédente peut être résumée à "nous ne voulons pas " -s theirs "car il encourage le mauvais flux de travail".

il mentionne l'alias:

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

Yaroslav Halchenko tente de plaider une fois de plus pour cette stratégie, mais Junio C. Hamano ajoute :

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

une fois que vous décidez que leur histoire est la ligne principale, vous préférez traiter votre ligne de développement comme une branche latérale et faire une fusion dans cette direction, i.e. le premier parent de la fusion résultante est un commit sur leur histoire et le second parent est le dernier mauvais de votre histoire. Donc vous finiriez par utiliser " checkout their-history && merge -s ours your-history " pour garde la paternité raisonnable.

et à ce point, l'utilisation de " -s ours " n'est plus une solution pour le manque de " -s theirs ".

C'est une partie de la sémantique désirée, c'est-à-dire du point de vue de la ligne survivante de l'histoire canonique, vous voulez préserver ce qu'elle a fait, annulant ce que l'autre ligne de l'histoire a fait .

1
répondu VonC 2017-10-14 09:19:37
la source

cela va fusionner votre nouvelle branche dans la branche de base 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
0
répondu Pawan Maheshwari 2013-01-28 16:35:03
la source

je pense que ce que vous voulez réellement est:

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

ça semble maladroit, mais ça devrait marcher. La seule chose que je n'aime pas vraiment à propos de cette solution est l'histoire de git sera déroutante... Mais au moins, l'histoire sera totalement préservée et vous n'aurez pas besoin de faire quelque chose de spécial pour les fichiers supprimés.

0
répondu briemers 2016-08-31 16:41:17
la source

UPDATE

bien que la deuxième réponse réponde à la question initiale de L'OP, elle ne reflète pas l'intention mise à jour de la question de l'OP.


ce que vous cherchez n'est pas le contraire de la commande git merge -s ours vous cherchez le contraire de la commande git merge -s recursive -X ours , qui est git merge -s recursive -X theirs


Réponse Originale À Cette Question

compte tenu de branches d'origine

*    0123456 (HEAD->A, origin/A)
| *  1234556 (origin/B, B)
|/
*    ??????? (common root)

pour fusionner la branche B en A tout en ignorant l'état de la branche A, puis d'abord faire une fusion régulière

git merge -s ours B    (this is the opposite of what we want)

il en résulte

*    2345678 (HEAD->A) Merge branch 'B' into A    (all wrong)
|\
* |  0123456 (origin/A)
| *  1234567 (origin/B, B)
|/
*    ??????? (common root)

ne poussez pas cette fusion car l'ID de propagation va changer (et c'est mal de toute façon) maintenant, nous pouvons changer, après les faits, la stratégie ours en une theirs stratégie

n'oubliez pas d'écrire en bas de la validation de l'id de la fusion comme il ne sera pas disponible après la prochaine réinitialisation matérielle. (Si vous oubliez qu'aucun dommage ne sera fait, mais vous devrez faire une réinitialisation dure de nouveau à A et tout recommencer).

git reset --hard B    (this is what we want the merge to look like (the merge can now only be referenced by the commit id `2345678`))
git reset --soft 2345678    (without changing any files go back to the merge)
git commit --amend    (branch B is now the final version of the merge)

maintenant, nous avons

*    3456789 (HEAD->A) Merge branch 'B' into A    (correctly ignores changes from 0123456)
|\
* |  0123456 (origin/A)
| *  1234567 (origin/B, B)
|/
*    ??????? (common root)

$ diff HEAD B
[... no changes ...]
git push

fait

j'avais besoin de faire ceci quand un collaborateur a appliqué mes modifications A à sa branche indépendante B sans fusionner, ceci permet moi d'accepter ses modifications sur ma branche.

0
répondu user3338098 2017-09-02 01:56:21
la source

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

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

suivi de

git merge -s ours branchB

(qui marque les deux branches fusionnées)

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

cette approche également indique clairement dans le journal de révision ce qui a été fait et ce qui était prévu.

0
répondu Ruben 2018-10-05 10:17:11
la source

j'ai récemment eu besoin de faire ceci pour deux dépôts distincts qui partagent une histoire commune. J'ai commencé par:

  • Org/repository1 master
  • Org/repository2 master

je voulais que toutes les modifications de repository2 master soient appliquées à repository1 master , en acceptant toutes les modifications que repository2 apporterait. En termes de git, ce devrait être une stratégie appelée -s theirs mais il ne ne pas exister. Soyez prudent parce que -X theirs est nommé comme il serait ce que vous voulez, mais il est pas le même (il est même dit dans la page de manuel).

la façon dont j'ai résolu cela était d'aller à repository2 et de faire une nouvelle branche repo1-merge . Dans cette branche, j'ai couru git pull [email protected]:Org/repository1 -s ours et il fusionne très bien sans problèmes. Je le pousse ensuite à la télécommande.

puis je retourne à repository1 et je fais une nouvelle branche repo2-merge . Dans ce branch, je lance git pull [email protected]:Org/repository2 repo1-merge qui se terminera avec les problèmes.

enfin, vous devrez soit émettre une demande de fusion dans repository1 pour en faire le nouveau master, ou tout simplement le garder comme une branche.

-1
répondu Trann 2017-03-27 17:31:26
la source

L'équivalent(garder les parents) afin de 'git merge -s leur branchB'

avant la fusion: enter image description here

!!! Assurez-vous que vous êtes en état de propreté !!!

Faire de 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

Qu'avons-nous fait ? Nous avons créé un nouveau comité dont nos deux parents et les leurs et le contnet du Comité est branchB-le leur

après la fusion: enter image description here

plus précisément:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
-1
répondu Boaz Nahum 2018-05-29 09:21:36
la source

Autres questions sur git git-merge