git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: "Israel\, Daniel M" <dmi1@lanl.gov>
Cc: "git\@vger.kernel.org" <git@vger.kernel.org>
Subject: Re: Writing merge strategy?
Date: Fri, 25 Jan 2019 13:33:08 -0800	[thread overview]
Message-ID: <xmqqimycfmnf.fsf@gitster-ct.c.googlers.com> (raw)
In-Reply-To: <244FE6CE-C045-4EC9-8C3F-8D16CF4D09EB@lanl.gov> (Daniel M. Israel's message of "Fri, 25 Jan 2019 00:55:52 +0000")

"Israel, Daniel M" <dmi1@lanl.gov> writes:

> I need a custom merge strategy (not driver) for a tool I’m writing, and I’m wondering:
>
> 1. Is there documentation for the API anywhere?

It used to be far easier to figure out back when git-merge.sh was a
script before 1c7b76be ("Build in merge", 2008-07-07) and it got
even harder to figure out after we removed contrib/examples/ at
49eb8d39 ("Remove contrib/examples/*", 2018-03-25), but you can
still find in "git show 1c7b76be^:git-merge.sh" output the following
snippet that shows how your merge strategy is called by the caller:

-- >8 -- snipsnap -- >8 --

    git-merge-$strategy $common -- "$head_arg" "$@"
    exit=$?
    if test "$no_commit" = t && test "$exit" = 0
    then
        merge_was_ok=t
	exit=1 ;# pretend it left conflicts.
    fi

    test "$exit" = 0 || {

	# The backend exits with 1 when conflicts are left to be resolved,
	# with 2 when it does not handle the given merge at all.

	if test "$exit" -eq 1
	then
	    cnt=`{
		git diff-files --name-only
		git ls-files --unmerged
	    } | wc -l`
	    if test $best_cnt -le 0 -o $cnt -le $best_cnt
	    then
		best_strategy=$strategy
		best_cnt=$cnt
	    fi
	fi
	continue
    }

    # Automerge succeeded.
    result_tree=$(git write-tree) && break

-- 8< -- snipsnap -- 8< --

You'll be called with common ancestor commit(s), double-dash, HEAD
(i.e. the commit the work by histories are being merged into), and
the commits being merged, on the command line.  You are expected to

 - update the index with the merge result and exit with 0, if you
   auto-resolved the merge cleanly; or

 - update the index with the cleanly merged result at stage #0, and
   for conflicted paths, place the common anestor version at stage
   #1, the version from HEAD at stage #2 and the version(s) from
   merged commit(s) at stage #3.  Signal that your automerge is
   usable with manual resolution by exiting with 1; or

 - do nothing and exit with 2, to signal that you were not capable
   of handling this particular merge.

The "git merge" command that called your strategy is responsible for
making a commit out of the index you left, recording the parent
commits, reacting to "merge --no-commit -S" and other options.

> 2. 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.

Other "magic" we let "git merge" do are things like handling
fast-forward, iterating over multiple strategies and use what works,
etc.

If you are not doing a strategy but a custom script, you'd be
reinventing "git merge".  As long as your custom script produces a
commit object that records the resulting tree, parent commits and
log message correctly, nobody who examines that resulting merge
commit would not even know you did not use "git merge" to record it.

And that is perfectly fine as long as the result suits your needs

      reply	other threads:[~2019-01-25 21:33 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-25  0:55 Writing merge strategy? Israel, Daniel M
2019-01-25 21:33 ` Junio C Hamano [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqimycfmnf.fsf@gitster-ct.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=dmi1@lanl.gov \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).