{"thread":{"id":"50316","subject":"Writing merge strategy?","startedAt":"2019-01-25T00:55:54Z","lastAt":"2019-01-25T21:33:13Z","messageCount":2,"participants":["Israel, Daniel M","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"367633","messageId":"244FE6CE-C045-4EC9-8C3F-8D16CF4D09EB@lanl.gov","threadId":"50316","inReplyTo":null,"subject":"Writing merge strategy?","fromName":"Israel, Daniel M","fromEmail":"dmi1@lanl.gov","sentAt":"2019-01-25T00:55:52Z","receivedAt":"2019-01-25T00:55:54Z","isPatch":false,"sender":{"key":"dmi1@lanl.gov","avatar":null},"body":"I need a custom merge strategy (not driver) for a tool I’m writing, and I’m wondering:\n\n1. Is there documentation for the API anywhere?\n\n2. Does git-merge actually do any magic, or could I just run the script that implements my merge directly?  In other words, is there really any difference between a merge strategy and a script that creates the tree I want and then commits it using git-commit-tree with multiple -p arguments.\n\n—\nDaniel M. Israel, Ph. D.\nPhysics Verification Lead\nXCP-4: Methods & Algorithms\nMailstop F644\nLos Alamos National Laboratory\n505 665 5664\n\n"},{"id":"367684","messageId":"xmqqimycfmnf.fsf@gitster-ct.c.googlers.com","threadId":"50316","inReplyTo":"244FE6CE-C045-4EC9-8C3F-8D16CF4D09EB@lanl.gov","subject":"Re: Writing merge strategy?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-01-25T21:33:08Z","receivedAt":"2019-01-25T21:33:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Israel, Daniel M\" <dmi1@lanl.gov> writes:\n\n> I need a custom merge strategy (not driver) for a tool I’m writing, and I’m wondering:\n>\n> 1. Is there documentation for the API anywhere?\n\nIt used to be far easier to figure out back when git-merge.sh was a\nscript before 1c7b76be (\"Build in merge\", 2008-07-07) and it got\neven harder to figure out after we removed contrib/examples/ at\n49eb8d39 (\"Remove contrib/examples/*\", 2018-03-25), but you can\nstill find in \"git show 1c7b76be^:git-merge.sh\" output the following\nsnippet that shows how your merge strategy is called by the caller:\n\n-- >8 -- snipsnap -- >8 --\n\n    git-merge-$strategy $common -- \"$head_arg\" \"$@\"\n    exit=$?\n    if test \"$no_commit\" = t && test \"$exit\" = 0\n    then\n        merge_was_ok=t\n\texit=1 ;# pretend it left conflicts.\n    fi\n\n    test \"$exit\" = 0 || {\n\n\t# The backend exits with 1 when conflicts are left to be resolved,\n\t# with 2 when it does not handle the given merge at all.\n\n\tif test \"$exit\" -eq 1\n\tthen\n\t    cnt=`{\n\t\tgit diff-files --name-only\n\t\tgit ls-files --unmerged\n\t    } | wc -l`\n\t    if test $best_cnt -le 0 -o $cnt -le $best_cnt\n\t    then\n\t\tbest_strategy=$strategy\n\t\tbest_cnt=$cnt\n\t    fi\n\tfi\n\tcontinue\n    }\n\n    # Automerge succeeded.\n    result_tree=$(git write-tree) && break\n\n-- 8< -- snipsnap -- 8< --\n\nYou'll be called with common ancestor commit(s), double-dash, HEAD\n(i.e. the commit the work by histories are being merged into), and\nthe commits being merged, on the command line.  You are expected to\n\n - update the index with the merge result and exit with 0, if you\n   auto-resolved the merge cleanly; or\n\n - update the index with the cleanly merged result at stage #0, and\n   for conflicted paths, place the common anestor version at stage\n   #1, the version from HEAD at stage #2 and the version(s) from\n   merged commit(s) at stage #3.  Signal that your automerge is\n   usable with manual resolution by exiting with 1; or\n\n - do nothing and exit with 2, to signal that you were not capable\n   of handling this particular merge.\n\nThe \"git merge\" command that called your strategy is responsible for\nmaking a commit out of the index you left, recording the parent\ncommits, reacting to \"merge --no-commit -S\" and other options.\n\n> 2. Does git-merge actually do any magic, or could I just run the\n> script that implements my merge directly?  In other words, is\n> there really any difference between a merge strategy and a script\n> that creates the tree I want and then commits it using\n> git-commit-tree with multiple -p arguments.\n\nOther \"magic\" we let \"git merge\" do are things like handling\nfast-forward, iterating over multiple strategies and use what works,\netc.\n\nIf you are not doing a strategy but a custom script, you'd be\nreinventing \"git merge\".  As long as your custom script produces a\ncommit object that records the resulting tree, parent commits and\nlog message correctly, nobody who examines that resulting merge\ncommit would not even know you did not use \"git merge\" to record it.\n\nAnd that is perfectly fine as long as the result suits your needs\n"}]}