-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Custom merge drivers and proper gitattributes merge
handling
#3564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* - check - considering using merge driver for file | ||
* - apply - apply merge driver to the file | ||
* - cleanup - done with file | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block won't show up in the doc viewer, so the "as documented above" comment there will seem rather nonsensical. This should probably be part of the documentation for the struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'll fix that; I think we're similarly deficient in the filter code, I copied this pattern from that.
The rest of the PR is fine. I'm mostly worried about documenting when we call certain things, and about having a global registration which can be called from multiple threads at the same time. |
Hello everyone! I have a question: it's a bit unclear for me, but will this PR give an ability to configure and call external merge drivers (external executables for example)? See discussion at GitLab's issue #5902 for context and possible use cases. |
@Envek If I'm not mistaken, this does not "magically" add support for external merge drivers. But you could write a custom libgit2 merge driver that either calls out to your existing merge driver executable or reimplements similar functionality. |
This will give you the ability to intercept those external merge drivers and call them, but libgit2 does not execute programs. It does give you the information you need to execute them as your environment needs. |
Would love to see this PR merged soon. Anything I can do to help? |
2390766
to
227a9b8
Compare
Thanks, @ethomson! Awesome work. |
A dumb question (possibly in a inappropriate place): I can't use this custom merge driver as developer linking to libgit2 library, right? I want to do my own merging, so I was hoping I will just simply register my function as a default driver somehow, and then it would get called, it'd get reference to two conflicting files as parameter, it'd produce the merged version and return it (and it'd get written). But looking at the code, it looks buried deep in the library, for some internal purpose, not accessible to me at all ... right? |
Hi @MiroslavHoudek - you can wire this up as a developer, however it doesn't sound like this is quite what you're looking for. The purpose of this is to be able to wire up a custom merge driver so that you can specify But it will only invoke your custom code for those files that have those attributes, not for every file. If that's an acceptable limitation for you, then this will work fine. If not, we might need to think a bit more deeply about how to get you what you need. |
Hi, I think I know where my brain took a wrong turn - I thought that I can add the custom driver in my (e.g.) main.cpp, and there I will write my handler, and then register it in libgit2.dll by calling git_merge_driver_register() ... whereas in reality the intended use seems to be to develop the driver and compile/link it with libgit2.dll, and then specify its invocation in the |
The point of the custom drivers is that they don't live in this codebase. If you have a custom one, it should definitely be in your own code. This is why we publish registration, otherwise we'd hard-code it. |
Will this be looked at now #3597 has been merged? Is there anything I can do to help with this? |
That PR existed because this was looked at. We'll get back to this PR when we have time. |
That makes sense. Thanks for the swift reply and for working on libgit2! |
@carlosmn thank you for your response, it gave me the confidence to find the real problem and get things straight. I have a functional custom driver now, yay! |
227a9b8
to
af98dc8
Compare
3da3371
to
349ff1c
Compare
Thanks for the sage comments as always @carlosmn - I think that I've addressed your concerns. |
Consumers can now register custom merged drivers with `git_merge_driver_register`. This allows consumers to support the merge drivers, as configured in `.gitattributes`. Consumers will be asked to perform the file-level merge when a custom driver is configured.
When a `check` or `apply` callback function returns `GIT_PASSTHROUGH`, move on to the default merge driver.
When a `check` or `apply` callback function returns `GIT_EMERGECONFLICT` stop and product a conflict.
Allow merge users to configure a custom default merge driver via `git_merge_options`. Similarly, honor the `merge.default` configuration option.
Ensure that setting the merge attribute forces the built-in default `text` driver and does *not* honor the `merge.default` configuration option. Further ensure that unsetting the merge attribute forces a conflict (the `binary` driver).
Since the `apply` callback can defer, the `check` callback is not necessary. Removing the `check` callback further makes the `payload` unnecessary along with the `cleanup` callback.
I rebased this on master because some conflicts had crept in. @carlosmn - anything keeping us from 🚢 this? |
Custom merge drivers and proper gitattributes `merge` handling
Will this eventually change the behavior of merge conflict detection on Github pull requests? For certain generated files, I'm thinking of defaulting to union for rebases and merges since we can rebuild broken files. On the other hand, we don't want people pressing the big green button unless the merge is truly clean. |
This will not change the behavior of GitHub PR merges directly, no. If GitHub wants to change behavior, that's not something that libgit2 would impose upon them. |
Makes sense, thanks!
|
While #3497 added support for
merge=union
in.gitattributes
, I felt that we should have a more complete story for handling themerge
attribute. This PR:Adds a framework for adding custom merge drivers. This is heavily inspired by the custom filter framework, and a consumer can add one or more custom merge drivers by name (for example, you may add a new
custom
driver) or - probably more useful - can add a wildcard merge driver. This allows a consumer to be given the option to handle all configured merge drivers that are not built-in.For example, a consumer could register a custom merge driver for the wildcard (
*
). If there were amerge=custom
line in a.gitattributes
for a file, the configured merge driver would be given the information about the file changes and the.gitattributes
configuration. The driver could (for example) look for the correspondingcustom
merge driver and - if found - elect to accept responsibility for this change. It would then invoke thecustom
merge driver and provide the results back.The merge driver may also defer the check, at which point libgit2 will invoke the default built-in merge driver. This is equivalent to when a user has configured
merge=foobar
in their.gitattributes
but has not configured thefoobar
merge driver. The merge driver configuration is ignored, and git will simply behave as if it was not configured at all.Additional handling for the
merge
attribute. When set (eg,merge
) this will indicate that the file is mergeable and the default built-intext
driver should be used. When unset (eg,-merge
) this will indicate that the file is binary and should not be merged (ie, is simply a conflict). When unspecified (eg, no merge line) this indicates that the file is text but if amerge.default
configuration setting exists, that will specify the driver to be used (otherwise the built-intext
driver will be used). Finally, if it is set to a string (eg,merge=foobar
) then that indicates the driver to be used.Any of the built-in drivers (
text
,binary
orunion
) may be specified.Proper handling of the
merge.default
configuration setting. Query themerge.default
to get the default merge driver name and use it when themerge
attribute is not specified for a file.Fixes #3497
Fixes #2180