Je ne veux pas d'outil de fusion visuel, et je ne veux pas non plus avoir à vi le fichier en conflit et choisir manuellement entre HEAD (le mien) et le changement importé (le leur). La plupart du temps, je veux soit tous leurs changements, soit tous les miens. Généralement, cela est dû au fait que ma modification est arrivée en amont et me revient par un pull, mais peut être légèrement modifiée à divers endroits.
Existe-t-il un outil en ligne de commande qui permettra de se débarrasser des marqueurs de conflit et de choisir d'une manière ou d'une autre en fonction de mon choix? Ou un ensemble de commandes git que je peux alias moi-même pour faire chacune.
# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"
Faire cela est plutôt ennuyeux. Pour «accepter le mien», j'ai essayé:
randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.
randy@sabotage ~/linus $ git checkout Makefile
error: path 'Makefile' is unmerged
andy@sabotage ~/linus $ git reset --hard HEAD Makefile
fatal: Cannot do hard reset with paths.
Comment suis-je censé me débarrasser de ces marqueurs de changement?
Je peux faire:
git reset HEAD Makefile; rm Makefile; git checkout Makefile
Mais cela semble plutôt rond, il doit y avoir un meilleur moyen. Et à ce stade, je ne sais pas si git pense même que la fusion a eu lieu, donc je ne pense pas que cela fonctionne même nécessairement.
Dans l'autre sens, faire «accepter le leur» est tout aussi compliqué. La seule façon de le comprendre est de faire:
git show test-branch:Makefile > Makefile; git add Makefile;
Cela me donne également un message de validation foiré, qui contient deux fois Conflits: Makefile.
Quelqu'un peut-il indiquer comment effectuer les deux actions ci-dessus de manière plus simple? Merci
Réponses:
La solution est très simple.
git checkout <filename>
tente d'extraire le fichier de l'index et échoue donc lors de la fusion.Ce que vous devez faire (c'est-à-dire extraire un commit ):
Pour commander votre propre version, vous pouvez utiliser l' un des éléments suivants:
ou
ou
Pour commander l'autre version, vous pouvez utiliser l' une des options suivantes :
ou
ou
Vous devrez également exécuter «ajouter» pour le marquer comme résolu:
la source
--ours
et cela--theirs
signifie exactement le contraire de ce que je pensais intuitivement en essayant cette commande ...git show
- cela saute la normalisation de la nouvelle ligne.--
est utilisé par Git pour séparer les révisions (noms de branches, etc.) des noms de chemin (noms de fichiers, répertoires). Il est important que Git ne puisse pas décider si un nom est le nom de la branche ou le nom du fichier. Cela suit la convention POSIX (ou GNU) d'utiliser un double tiret pour séparer les options des arguments (noms de fichiers).theirs
/ours
peut apparaître inversé si vous résolvez des conflits dans le contexte d'une opération de rebase. Parce que le rebase fonctionne en extrayant la branche cible, puis la sélection de cerises de "votre" branche sur la cible, la modification entrante ("la leur") vient de "votre" branche, et la branche actuelle est la branche cible ("la nôtre") ).Essaye ça:
Pour accepter leurs modifications:
git merge --strategy-option theirs
Pour accepter le vôtre:
git merge --strategy-option ours
la source
Sur la base de la réponse de Jakub, vous pouvez configurer les alias git suivants pour plus de commodité:
Ils peuvent éventuellement prendre un ou plusieurs chemins de fichiers à résoudre et par défaut tout résoudre sous le répertoire actuel si aucun n'est indiqué.
Ajoutez-les au
[alias]
section de votre~/.gitconfig
ou exécutezla source
[alias]
section de votre~.gitconfig
ou utilisezgit config --global accept-ours "..."
. J'ai édité ma réponse.~/.gitconfig
.!f() { git checkout --ours -- "${@:-.}" git add -u "${@:-.}; }; f
Sur la base de la réponse de kynan, voici les mêmes alias, modifiés afin qu'ils puissent gérer les espaces et les tirets initiaux dans les noms de fichiers:
la source
La situation idéale pour résoudre les conflits est quand vous savez à l' avance de quelle façon vous voulez les résoudre et peut passer les
-Xours
ou-Xtheirs
fusion récursives options de stratégie. En dehors de cela, je peux voir trois scénarios:Pour répondre à ces trois scénarios, vous pouvez ajouter les lignes suivantes à votre
.gitconfig
fichier (ou équivalent):le
get(ours|theirs)
outil conserve simplement la version respective du fichier et supprime toutes les modifications de l'autre version (donc aucune fusion ne se produit).L'
merge(ours|theirs)
outil refait la fusion à trois à partir des versions locale, de base et distante du fichier, en choisissant de résoudre les conflits dans la direction donnée. Cela a quelques mises en garde, en particulier: il ignore les options de diff qui ont été passées à la commande de fusion (telles que l'algorithme et la gestion des espaces); effectue la fusion proprement à partir des fichiers d'origine (donc toutes les modifications manuelles apportées au fichier sont supprimées, ce qui pourrait être bon ou mauvais); et a l'avantage de ne pas pouvoir être confondu par les marqueurs de différence qui sont censés être dans le fichier.le
keep(ours|theirs)
outil édite simplement les marqueurs de différence et les sections fermées, les détectant par expression régulière. Cela a l'avantage de conserver les options de diff de la commande de fusion et vous permet de résoudre certains conflits à la main, puis de résoudre automatiquement le reste. Il présente l'inconvénient que s'il y a d'autres marqueurs de conflit dans le fichier, il peut être confondu.Ils sont tous utilisés en exécutant
git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]
où, s'il<filename>
n'est pas fourni, il traite tous les fichiers en conflit.D'une manière générale, en supposant que vous savez qu'il n'y a pas de marqueurs diff pour confondre l'expression régulière, les
keep*
variantes de la commande sont les plus puissantes. Si vous laissez l'mergetool.keepBackup
option non définie ou vraie, après la fusion, vous pouvez différencier le*.orig
fichier du résultat de la fusion pour vérifier que cela a du sens. Par exemple, j'exécute ce qui suitmergetool
juste après pour inspecter les modifications avant de valider:Remarque : Si ce
merge.conflictstyle
n'est pasdiff3
le cas/^|||||||/
, le modèle de lased
règle doit l'être à la/^=======/
place.la source