Subject: Re: [PATCH v3 3/3] correct ce_compare_data() in a middle of a merge

From: Junio C Hamano <[email-masked]>
Date: Mon, 11 Jul 2016 13:07:52 -0700

Junio C Hamano <[email-masked]> writes:

> Subject: [PATCH] merge: avoid "safer crlf" during recording of merge results
> ...
> We can work this around by not refreshing the new cache entry in
> make_cache_entry() called by add_cacheinfo().  After add_cacheinfo()
> adds the new entry, we can call refresh_cache_entry() on that,
> knowing that addition of this new cache entry would have removed the
> stale cache entries that had CRLF in stage #2 that were carried over
> before the renormalizing merge started and will not interfere with
> the correct recording of the result.
>
> The test update was taken from a series by Torsten Bögershausen
> that attempted to fix this with a different approach (which was a
> lot more intrusive).
>
> Signed-off-by: Junio C Hamano <[email-masked]>
> ---

How do things look at this point?  This version is what I ended up
queuing in 'pu', but I took your "Thanks" in $gmane/299120 to only
mean "Thanks for feeding some ideas to help me move forward", not
necessarily "Tnanks that looks like the right approach." yet, so
right now both topics are stalled and waiting for an action from
you.

Thanks.

>  cache.h                    |  1 +
>  merge-recursive.c          | 17 ++++++++++++----
>  read-cache.c               |  5 +----
>  t/t6038-merge-text-auto.sh | 51 +++++++++++++++++++++++++---------------------
>  4 files changed, 43 insertions(+), 31 deletions(-)

[no comment below this line; the contents kept as reference]

> diff --git a/cache.h b/cache.h
> index b829410..b33cb54 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -632,6 +632,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
>  #define REFRESH_IGNORE_SUBMODULES	0x0010	/* ignore submodules */
>  #define REFRESH_IN_PORCELAIN	0x0020	/* user friendly output, not "needs update" */
>  extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
> +extern struct cache_entry *refresh_cache_entry(struct cache_entry *, unsigned int);
>  
>  extern void update_index_if_able(struct index_state *, struct lock_file *);
>  
> diff --git a/merge-recursive.c b/merge-recursive.c
> index b880ae5..de37e51 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c
> @@ -202,12 +202,21 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
>  		const char *path, int stage, int refresh, int options)
>  {
>  	struct cache_entry *ce;
> -	ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage,
> -			      (refresh ? (CE_MATCH_REFRESH |
> -					  CE_MATCH_IGNORE_MISSING) : 0 ));
> +	int ret;
> +
> +	ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 0);
>  	if (!ce)
>  		return error(_("addinfo_cache failed for path '%s'"), path);
> -	return add_cache_entry(ce, options);
> +
> +	ret = add_cache_entry(ce, options);
> +	if (refresh) {
> +		struct cache_entry *nce;
> +
> +		nce = refresh_cache_entry(ce, CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
> +		if (nce != ce)
> +			ret = add_cache_entry(nce, options);
> +	}
> +	return ret;
>  }
>  
>  static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)
> diff --git a/read-cache.c b/read-cache.c
> index d9fb78b..6af409a 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -19,9 +19,6 @@
>  #include "split-index.h"
>  #include "utf8.h"
>  
> -static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
> -					       unsigned int options);
> -
>  /* Mask for the name length in ce_flags in the on-disk index */
>  
>  #define CE_NAMEMASK  (0x0fff)
> @@ -1254,7 +1251,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
>  	return has_errors;
>  }
>  
> -static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
> +struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
>  					       unsigned int options)
>  {
>  	return refresh_cache_ent(&the_index, ce, options, NULL, NULL);
> diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh
> index 33b77ee..5e8d5fa 100755
> --- a/t/t6038-merge-text-auto.sh
> +++ b/t/t6038-merge-text-auto.sh
> @@ -91,16 +91,13 @@ test_expect_success 'Merge after setting text=auto' '
>  	compare_files expected file
>  '
>  
> -test_expect_success 'Merge addition of text=auto' '
> +test_expect_success 'Merge addition of text=auto eol=LF' '
> +	git config core.eol lf &&
>  	cat <<-\EOF >expected &&
>  	first line
>  	same line
>  	EOF
>  
> -	if test_have_prereq NATIVE_CRLF; then
> -		append_cr <expected >expected.temp &&
> -		mv expected.temp expected
> -	fi &&
>  	git config merge.renormalize true &&
>  	git rm -fr . &&
>  	rm -f .gitattributes &&
> @@ -109,17 +106,31 @@ test_expect_success 'Merge addition of text=auto' '
>  	compare_files  expected file
>  '
>  
> +test_expect_success 'Merge addition of text=auto eol=CRLF' '
> +	git config core.eol crlf &&
> +	cat <<-\EOF >expected &&
> +	first line
> +	same line
> +	EOF
> +
> +	append_cr <expected >expected.temp &&
> +	mv expected.temp expected &&
> +	git config merge.renormalize true &&
> +	git rm -fr . &&
> +	rm -f .gitattributes &&
> +	git reset --hard b &&
> +	echo >&2 "After git reset --hard b" &&
> +	git ls-files -s --eol >&2 &&
> +	git merge a &&
> +	compare_files  expected file
> +'
> +
>  test_expect_success 'Detect CRLF/LF conflict after setting text=auto' '
> +	git config core.eol native &&
>  	echo "<<<<<<<" >expected &&
> -	if test_have_prereq NATIVE_CRLF; then
> -		echo first line | append_cr >>expected &&
> -		echo same line | append_cr >>expected &&
> -		echo ======= | append_cr >>expected
> -	else
> -		echo first line >>expected &&
> -		echo same line >>expected &&
> -		echo ======= >>expected
> -	fi &&
> +	echo first line >>expected &&
> +	echo same line >>expected &&
> +	echo ======= >>expected &&
>  	echo first line | append_cr >>expected &&
>  	echo same line | append_cr >>expected &&
>  	echo ">>>>>>>" >>expected &&
> @@ -135,15 +146,9 @@ test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' '
>  	echo "<<<<<<<" >expected &&
>  	echo first line | append_cr >>expected &&
>  	echo same line | append_cr >>expected &&
> -	if test_have_prereq NATIVE_CRLF; then
> -		echo ======= | append_cr >>expected &&
> -		echo first line | append_cr >>expected &&
> -		echo same line | append_cr >>expected
> -	else
> -		echo ======= >>expected &&
> -		echo first line >>expected &&
> -		echo same line >>expected
> -	fi &&
> +	echo ======= >>expected &&
> +	echo first line >>expected &&
> +	echo same line >>expected &&
>  	echo ">>>>>>>" >>expected &&
>  	git config merge.renormalize false &&
>  	rm -f .gitattributes &&