From: Junio C Hamano Date: Sat, 15 Sep 2012 04:39:56 +0000 (-0700) Subject: Merge branch 'jc/ll-merge-binary-ours' X-Git-Tag: v1.8.0-rc0~49 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e6d29a4b47cf476e18658609033bdee4c42db3b8?ds=inline;hp=-c Merge branch 'jc/ll-merge-binary-ours' "git merge -Xtheirs" did not help content-level merge of binary files; it should just take their version. Also "*.jpg binary" in the attributes did not imply they should use the binary ll-merge driver. * jc/ll-merge-binary-ours: ll-merge: warn about inability to merge binary files only when we can't attr: "binary" attribute should choose built-in "binary" merge driver merge: teach -Xours/-Xtheirs to binary ll-merge driver --- e6d29a4b47cf476e18658609033bdee4c42db3b8 diff --combined Documentation/gitattributes.txt index e16f3e175b,ead7254922..462b79c120 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@@ -75,8 -75,6 +75,8 @@@ repositories (i.e., attributes of inter `.gitattributes` files. Attributes that should affect all repositories for a single user should be placed in a file specified by the `core.attributesfile` configuration option (see linkgit:git-config[1]). +Its default value is $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME +is either not set or empty, $HOME/.config/git/attributes is used instead. Attributes for all users on a system should be placed in the `$(prefix)/etc/gitattributes` file. @@@ -296,27 -294,16 +296,27 @@@ output is used to update the worktree f `clean` command is used to convert the contents of worktree file upon checkin. -A missing filter driver definition in the config is not an error -but makes the filter a no-op passthru. +One use of the content filtering is to massage the content into a shape +that is more convenient for the platform, filesystem, and the user to use. +For this mode of operation, the key phrase here is "more convenient" and +not "turning something unusable into usable". In other words, the intent +is that if someone unsets the filter driver definition, or does not have +the appropriate filter program, the project should still be usable. -The content filtering is done to massage the content into a -shape that is more convenient for the platform, filesystem, and -the user to use. The key phrase here is "more convenient" and not -"turning something unusable into usable". In other words, the -intent is that if someone unsets the filter driver definition, -or does not have the appropriate filter program, the project -should still be usable. +Another use of the content filtering is to store the content that cannot +be directly used in the repository (e.g. a UUID that refers to the true +content stored outside git, or an encrypted content) and turn it into a +usable form upon checkout (e.g. download the external content, or decrypt +the encrypted content). + +These two filters behave differently, and by default, a filter is taken as +the former, massaging the contents into more convenient shape. A missing +filter driver definition in the config, or a filter driver that exits with +a non-zero status, is not an error but makes the filter a no-op passthru. + +You can declare that a filter turns a content that by itself is unusable +into a usable content by setting the filter..required configuration +variable to `true`. For example, in .gitattributes, you would assign the `filter` attribute for paths. @@@ -348,16 -335,6 +348,16 @@@ input that is already correctly indente smudge filter means that the clean filter _must_ accept its own output without modifying it. +If a filter _must_ succeed in order to make the stored contents usable, +you can declare that the filter is `required`, in the configuration: + +------------------------ +[filter "crypt"] + clean = openssl enc ... + smudge = openssl enc -d ... + required +------------------------ + Sequence "%f" on the filter command line is replaced with the name of the file the filter is working on. A filter might use this in keyword substitution. For example: @@@ -927,7 -904,7 +927,7 @@@ file at the toplevel (i.e. not in any s macro attribute "binary" is equivalent to: ------------ - [attr]binary -diff -text + [attr]binary -diff -merge -text ------------ diff --combined attr.c index f12c83f80a,3f581b3cec..3430faf2cc --- a/attr.c +++ b/attr.c @@@ -306,7 -306,7 +306,7 @@@ static void free_attr_elem(struct attr_ } static const char *builtin_attr[] = { - "[attr]binary -diff -text", + "[attr]binary -diff -merge -text", NULL, }; @@@ -352,11 -352,8 +352,11 @@@ static struct attr_stack *read_attr_fro char buf[2048]; int lineno = 0; - if (!fp) + if (!fp) { + if (errno != ENOENT) + warn_on_inaccessible(path); return NULL; + } res = xcalloc(1, sizeof(*res)); while (fgets(buf, sizeof(buf), fp)) handle_attr_line(res, buf, path, ++lineno, macro_ok); @@@ -500,7 -497,6 +500,7 @@@ static int git_attr_system(void static void bootstrap_attr_stack(void) { struct attr_stack *elem; + char *xdg_attributes_file; if (attr_stack) return; @@@ -519,10 -515,6 +519,10 @@@ } } + if (!git_attributes_file) { + home_config_paths(NULL, &xdg_attributes_file, "attributes"); + git_attributes_file = xdg_attributes_file; + } if (git_attributes_file) { elem = read_attr_from_file(git_attributes_file, 1); if (elem) { diff --combined ll-merge.c index f3f7692158,307315b788..acea33bf1b --- a/ll-merge.c +++ b/ll-merge.c @@@ -35,7 -35,7 +35,7 @@@ struct ll_merge_driver */ static int ll_binary_merge(const struct ll_merge_driver *drv_unused, mmbuffer_t *result, - const char *path_unused, + const char *path, mmfile_t *orig, const char *orig_name, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, @@@ -46,16 -46,34 +46,34 @@@ assert(opts); /* - * The tentative merge result is "ours" for the final round, - * or common ancestor for an internal merge. Still return - * "conflicted merge" status. + * The tentative merge result is the or common ancestor for an internal merge. */ - stolen = opts->virtual_ancestor ? orig : src1; + if (opts->virtual_ancestor) { + stolen = orig; + } else { + switch (opts->variant) { + default: - warning("Cannot merge binary files: %s (%s vs. %s)\n", ++ warning("Cannot merge binary files: %s (%s vs. %s)", + path, name1, name2); + /* fallthru */ + case XDL_MERGE_FAVOR_OURS: + stolen = src1; + break; + case XDL_MERGE_FAVOR_THEIRS: + stolen = src2; + break; + } + } result->ptr = stolen->ptr; result->size = stolen->size; stolen->ptr = NULL; - return 1; + + /* + * With -Xtheirs or -Xours, we have cleanly merged; + * otherwise we got a conflict. + */ + return (opts->variant ? 0 : 1); } static int ll_xdl_merge(const struct ll_merge_driver *drv_unused, @@@ -73,8 -91,6 +91,6 @@@ if (buffer_is_binary(orig->ptr, orig->size) || buffer_is_binary(src1->ptr, src1->size) || buffer_is_binary(src2->ptr, src2->size)) { - warning("Cannot merge binary files: %s (%s vs. %s)", - path, name1, name2); return ll_binary_merge(drv_unused, result, path, orig, orig_name,