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
Post a Comment