Re: [BUG] attribute "eol" with "crlf"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Works fine for me. Thanks

> Junio C Hamano <gitster@xxxxxxxxx> writes:
>
>> ...
>> What you said is _technically_ correct in that sense.
>>
>> However, I think the CRLF filter used to have a hack to strip "\r" if the
>> repository data records "\r" at the end of line. This was intended to help
>> people who checked in such a broken text file (if it is a text file, then
>> raw ascii CR does not have a place in it in the repository representation)
>> and it was a useful hack to help people recover from such mistakes to
>> start the project from DOS-only world (with CRLF in the repository data)
>> and migrate to cross platform world (with LF in the repository data, CRLF
>> in the DOS working tree).  I suspect that the streaming filter conversion
>> may not have the same hack in it.
>
> Perhaps something like this, but I do not use CRLF myself, so it probably
> needs to be checked by extra sets of eyes.
>
> Thanks.
>
> -- >8 --
> Subject: lf_to_crlf_filter(): resurrect CRLF->CRLF hack
>
> The non-streaming version of the filter counts CRLF and LF in the whole
> buffer, and returns without doing anything when they match (i.e. what is
> recorded in the object store already uses CRLF). This was done to help
> people who added files from the DOS world before realizing they want to go
> cross platform and adding .gitattributes to tell Git that they only want
> CRLF in their working tree.
>
> The streaming version of the filter does not want to read the whole thing
> before starting to work, as that defeats the whole point of streaming. So
> we instead check what byte follows CR whenever we see one, and add CR
> before LF only when the LF does not immediately follow CR already to keep
> CRLF as is.
>
> Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
> ---
>  convert.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 50 insertions(+), 10 deletions(-)
>
> diff --git a/convert.c b/convert.c
> index c028275..8daf4e4 100644
> --- a/convert.c
> +++ b/convert.c
> @@ -879,7 +879,8 @@ int is_null_stream_filter(struct stream_filter *filter)
>
>  struct lf_to_crlf_filter {
>        struct stream_filter filter;
> -       unsigned want_lf:1;
> +       unsigned has_held:1;
> +       char held;
>  };
>
>  static int lf_to_crlf_filter_fn(struct stream_filter *filter,
> @@ -889,10 +890,14 @@ static int lf_to_crlf_filter_fn(struct stream_filter *filter,
>        size_t count, o = 0;
>        struct lf_to_crlf_filter *lf_to_crlf = (struct lf_to_crlf_filter *)filter;
>
> -       /* Output a pending LF if we need to */
> -       if (lf_to_crlf->want_lf) {
> -               output[o++] = '\n';
> -               lf_to_crlf->want_lf = 0;
> +       /*
> +        * We may be holding onto the CR to see if it is followed by a
> +        * LF, in which case we would need to go to the main loop.
> +        * Otherwise, just emit it to the output stream.
> +        */
> +       if (lf_to_crlf->has_held && (lf_to_crlf->held != '\r' || !input)) {
> +               output[o++] = lf_to_crlf->held;
> +               lf_to_crlf->has_held = 0;
>        }
>
>        /* We are told to drain */
> @@ -902,22 +907,57 @@ static int lf_to_crlf_filter_fn(struct stream_filter *filter,
>        }
>
>        count = *isize_p;
> -       if (count) {
> +       if (count || lf_to_crlf->has_held) {
>                size_t i;
> +               int was_cr = 0;
> +
> +               if (lf_to_crlf->has_held) {
> +                       was_cr = 1;
> +                       lf_to_crlf->has_held = 0;
> +               }
> +
>                for (i = 0; o < *osize_p && i < count; i++) {
>                        char ch = input[i];
> +
>                        if (ch == '\n') {
>                                output[o++] = '\r';
> -                               if (o >= *osize_p) {
> -                                       lf_to_crlf->want_lf = 1;
> -                                       continue; /* We need to increase i */
> -                               }
> +                       } else if (was_cr) {
> +                               /*
> +                                * Previous round saw CR and it is not followed
> +                                * by a LF; emit the CR before processing the
> +                                * current character.
> +                                */
> +                               output[o++] = '\r';
>                        }
> +
> +                       /*
> +                        * We may have consumed the last output slot,
> +                        * in which case we need to break out of this
> +                        * loop; hold the current character before
> +                        * returning.
> +                        */
> +                       if (*osize_p <= o) {
> +                               lf_to_crlf->has_held = 1;
> +                               lf_to_crlf->held = ch;
> +                               continue; /* break but increment i */
> +                       }
> +
> +                       if (ch == '\r') {
> +                               was_cr = 1;
> +                               continue;
> +                       }
> +
> +                       was_cr = 0;
>                        output[o++] = ch;
>                }
>
>                *osize_p -= o;
>                *isize_p -= i;
> +
> +               if (!lf_to_crlf->has_held && was_cr) {
> +                       lf_to_crlf->has_held = 1;
> +                       lf_to_crlf->held = '\r';
> +               }
>        }
>        return 0;
>  }
��.n��������+%������w��{.n��������n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]