git pull -X theirs local master still have conflicts -


i make pull accepting remote (theirs) modifications, without manual conflict solving. still conflicts without auto solution:

$ git merge -s recursive -x theirs local/master  conflict (rename/delete): rcs.d/s08kmod deleted in head , renamed in local/master. version local/master of rcs.d/s08kmod left in tree. auto-merging php5/cli/conf.d/20-xdebug.ini conflict (add/add): merge conflict in php5/cli/conf.d/20-xdebug.ini auto-merging apt/sources.list conflict (rename/rename): rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf.conf" in branch "head" rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf" in "local/master" 

using pull:

$ git pull local master ssh://192.168.1.101/etc  * branch            master     -> fetch_head warning: cannot merge binary files: console-setup/cached_utf-8_del.kmap.gz (head vs. ada82813d27e5bef846ee086d07a87a82cfbb020) conflict (rename/delete): rcs.d/s08kmod deleted in head , renamed in ada82813d27e5bef846ee086d07a87a82cfbb020. version ada82813d27e5bef846ee086d07a87a82cfbb020 of rcs.d/s08kmod left in tree. conflict (add/add): merge conflict in php5/cli/conf.d/20-xdebug.ini conflict (rename/rename): rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf.conf" in branch "head" rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf" in "ada82813d27e5bef846ee086d07a87a82cfbb020" 

i tried:

git merge --allow-unrelated-histories --strategy-option theirs local/master 

but same conflicts.

was using git v2.8.1 on first example. upgraded git v2.9.2 before 2nd example.

my use case: i follow debian upgrade changes in /etc git (more precisely etckeeper). after upgrade done changes, accept changes done debian. of course trust in changes done debian upgrade, overwrite (merge) changes done, without interaction.

any idea how solve modification conflicts automatically?

you're expecting more of -x theirs git can deliver.

remember first git merge usual (recursive) strategy:

  • finds merge base;1
  • diffs merge base vs current tip commit "our" changes; and
  • diffs merge base vs commit name—usually tip of other branch, can name commit—to "their" changes.

the 2 diffs have series of diff hunks showing "what did" , "what did", , git attempt combine them 1 copy of each change. means if fixed spelling of word on line 49 of file, , didn't, our fix. if fixed spelling , didn't, fix. if both made same spelling fix, fix once, not twice, in spite of fact "fix spelling" represented as:

      "first, delete old line. then, insert new, different line."

and overly naive application of "take each change" try delete line twice, and/or insert 2 copies of new line. git (or decent version control system's merge) notice these 2 changes the same, , keeps 1 copy.

if 2 diff hunks in 2 different diffs make different changes same original source area, though, git declares merge conflict. goes on whatever else can, remembers conflict, , stops @ end of merge, leaving conflict present in both work-tree (in familiar <<<<<<< ... >>>>>>> form) , in index.

also known "staging area" or "cache", index has 1 entry per work-tree file,2 during conflicted merge, has, instead, three entries each such file: 1 merge base, 1 "ours", , 1 "theirs". "normal" (no conflict) entry goes in "staging slot zero" slot not used file, time. instead, merge-base version of file goes in staging slot 1, , other 2 versions in slots 2 , 3 (we can use --ours , --theirs them, rather memorizing these slot numbers, documented in gitrevisions if want them @ time). must resolve conflict—often, editing file in work-tree—and tell git replace 3 copies in "unmerged" slots in index single copy in normal, "ready go next commit" stage-zero slot.


1this assumes there single merge-base commit. if there multiple merge-bases, action depends on strategy. default "recursive" strategy finds all merge bases, , merges them produce single "virtual merge base". "resolve" strategy picks 1 merge base @ (apparently) random. "octopus" strategy declares merge failure.

2more precisely, there 1 entry per tracked file, special white-out entry file in head commit scheduled removal because of git rm. untracked files have no index staging slots @ all.


-x ours , -x theirs

what -x means is: instead declaring conflict in particular case (conflicting diff hunks), take either our change (-x ours) or change (-x theirs), discarding other diff hunk.

a simple example fixed spelling of first word on line while fixed spelling of fifth word on same line. here -x ours keep our fix , discard theirs, , -x theirs keep fix , discard ours.

in more complex cases, might have added or removed line(s) added or removed different line(s), conflicts harder think about. git diff can incorrectly synchronize on blank lines or lines consisting of single close-brace, instance, resulting in conflicts or understands material merged, able merge successfully. again, -x discards either diff hunk or ours, taking whichever 1 told to.

file conflicts

that's fine far goes, handles diff hunk differences. conflicts seeing incompatible file changes:

conflict (rename/delete): rcs.d/s08kmod deleted in head , renamed  in local/master. version local/master of rcs.d/s08kmod left in tree. 

in case, 1 git diff (to find "our" changes) found (head) deleted rcs.d/s08kmod entirely, while (local/master) renamed file. in delete-file-vs-rename-file conflict, git keeps file under new name, since it's easier delete (git rm newname) figure out new name , retrieve ours-or-theirs version of file.

auto-merging php5/cli/conf.d/20-xdebug.ini 

(this 1 went well, perhaps using -x theirs resolve diff hunk conflicts)

conflict (add/add): merge conflict in php5/cli/conf.d/20-xdebug.ini 

here, merge base had no file named php5/cli/conf.d/20-xdebug.ini. git leaves both versions in index; can use git checkout --ours put ours in work-tree, , git checkout --theirs put theirs in work tree. still have merge , resolve file manually, unfortunately. have not checked on git version 2.8 here (add/add conflict resolution has been getting work done on recently).

auto-merging apt/sources.list 

(another automatic merge went well, again perhaps using -x)

conflict (rename/rename): rename "apache2/sites-available/default-ssl"-> "apache2/sites-available/default-ssl.conf.conf" in branch "head" rename "apache2/sites-available/default-ssl"-> "apache2/sites-available/default-ssl.conf" in "local/master" 

in case, file in merge base (under name apache2/sites-available/default-ssl.conf.conf) appears, 2 diffs, have been renamed differently in our changes vs changes. i'm again not sure what, if anything, git changes within file, though logically, -x theirs should apply , take "their" diff hunks @ point ours , theirs conflict. however, git not know final name use file, declares conflict.

after declaring these conflicts, git stops , makes user manually resolve remaining issues usual. may git add or git rm whichever version(s) of each file want, , git commit result. of course, time use -x theirs or -x ours, it's wise test work-tree in way (by eyeballing diffs, or running manual or automated tests, or whatever) before committing.


Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -