2

When I cherry-pick from another repo I often get binary-conflict like this:

`$ git cherry-pick -e 75fa3f
 Performing inexact rename detection:  97% (636400/652525), done.
 warning: Cannot merge binary files: src/Pippo.ext (HEAD:src/Pippo.ext vs. 75fa3f18... Aggiornamento.:othersrc/Pippo.ext)
 error: could not apply 75fa3f18... Aggiornamento.`

All files are ANSI/ASCII, no unicode.

In this case I should abort cherry-pick, manually copy file and then commit.

I also added in .git/info/attributes:
*.ext diff

but without luck.

Peter Krebs
  • 3,831
  • 2
  • 15
  • 29
Samuele
  • 21
  • 1
  • Are you editing `.git/info/attributes` directly? You should have a [`.gitattributes`](https://git-scm.com/docs/gitattributes) file with `*.ext text` in it (add more as needed). – Peter Krebs May 16 '22 at 09:40
  • @PeterKrebs yes, I edite .git/info/attributes directly. Now I tried adding *.ext text, but it does not worked. But "text" is not related to line ending? – Samuele May 16 '22 at 15:36

1 Answers1

2

Git thinks (believes) that these two file names:

  • HEAD:src/Pippo.ext (src/Pippo.ext in revision HEAD)
  • 75fa3f18:othersrc/Pippo.ext

represent the same file, with some changes to be merged as a result of the cherry pick. But at the same time, Git thinks that at least one version of this file is binary.

Git's idea of a "binary file" is one that has a NUL byte within the first 8000 bytes, or that has a size exceeding about 1 gigabyte (MAX_XDIFF_SIZE from xdif-interface.h):

/*
 * xdiff isn't equipped to handle content over a gigabyte;
 * we make the cutoff 1GB - 1MB to give some breathing
 * room for constant-sized additions (e.g., merge markers)
 */                     
#define MAX_XDIFF_SIZE (1024UL * 1024 * 1023) 

The actual test code, in ll-merge.c, reads:

        if (orig->size > MAX_XDIFF_SIZE ||
            src1->size > MAX_XDIFF_SIZE ||
            src2->size > MAX_XDIFF_SIZE ||
            buffer_is_binary(orig->ptr, orig->size) ||
            buffer_is_binary(src1->ptr, src1->size) ||
            buffer_is_binary(src2->ptr, src2->size)) {
                return ll_binary_merge(drv_unused, result,
                                       path,
                                       orig, orig_name,
                                       src1, name1,
                                       src2, name2,
                                       opts, marker_size);
        }                          

with buffer_is_binary using that NUL-byte-in-the-first-8000-bytes test.

Unfortunately, even if you mark the file as text with .gitattributes or git/info/attributes, these tests are still used (it's apparently required by the xdiff code). If marking the file as text with an attribute fails, the three input files must violate either the size or the binary test rules, and you will have to produce your own merge for these files.

In this case I should abort cherry-pick, manually copy file and then commit.

Rather than git cherry-pick --abort you should simply (or complicated-ly?) find or extract the correct merged result file(s) and use git add and/or git rm as needed to complete the cherry-pick merge step. Then use git cherry-pick --continue to finish the cherry-pick.

torek
  • 448,244
  • 59
  • 642
  • 775
  • About git add/git rm/git cherry-pick --continue, if I do a git add and then cherry-pick --continue, git tell me to use "commit --allow-empty". If I do so, I get the commit, but in binary mode. Insetad if I solve the conflict using external tool (winmerge) and save the file, when I cherry-pick --continue it works as expected. I think there is a sarcasso of different settings between the two repository wich make me crazy. – Samuele May 23 '22 at 08:35