Skip to content
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

cherry-pick failed : add_cacheinfo failed to refresh for path #1780

Closed
chucklu opened this issue Aug 7, 2018 · 22 comments
Closed

cherry-pick failed : add_cacheinfo failed to refresh for path #1780

chucklu opened this issue Aug 7, 2018 · 22 comments

Comments

@chucklu
Copy link

chucklu commented Aug 7, 2018

Setup

  • Which version of Git for Windows are you using? Is it 32-bit or 64-bit?
$ git --version --build-options

 git version 2.18.0.windows.1
cpu: x86_64
built from commit: cd1a74fc9dc8a07626c216940db9a51f25206e03
sizeof-long: 4
  • Which version of Windows are you running? Vista, 7, 8, 10? Is it 32-bit or 64-bit?
$ cmd.exe /c ver

Microsoft Windows [Version 10.0.16299.547]
  • What options did you set as part of the installation? Or did you choose the
    defaults?
# One of the following:
> type "C:\Program Files\Git\etc\install-options.txt"
> type "C:\Program Files (x86)\Git\etc\install-options.txt"
> type "%USERPROFILE%\AppData\Local\Programs\Git\etc\install-options.txt"
$ cat /etc/install-options.txt

Editor Option: Notepad++
Path Option: Cmd
SSH Option: OpenSSH
CURL Option: WinSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Performance Tweaks FSCache: Enabled
Use Credential Manager: Enabled
Enable Symlinks: Disabled

Details

  • Which terminal/shell are you running Git from? e.g Bash/CMD/PowerShell/other

Bash

 git cherry-pick 9e3252^..126c0c
  • What did you expect to occur after running these commands?

cherry-pick successfully

  • What actually happened instead?

cherry-pick failed

The trace info for cherry-pick is as following:

$ git_trace=1 gcm_trace=1 git cherry-pick 9e3252^..126c0c
09:23:52.160079 exec-cmd.c:236 trace: resolved executable dir: C:/Progr am Files/Git/mingw64/bin
09:23:52.171109 git.c:415 trace: built-in: git cherry-pick 9e3252^ ..126c0c
Performing inexact rename detection: 100% (5862848/5862848), done.
09:24:04.932967 run-command.c:637 trace: run_command: 'git-lfs filter-process'
09:24:05.062300 trace git-lfs: exec: git 'version'
09:24:05.203674 trace git-lfs: exec: git 'config' '-l'
09:24:05.248795 trace git-lfs: Install hook: pre-push, force=false, path=C:\Users\clu\source\repos\Test.git\hooks\pre-push, upgrading...
09:24:05.250808 trace git-lfs: Install hook: post-checkout, force=false, path=C:\Users\clu\source\repos\Test.git\hooks\post-checkout, upgrading...
09:24:05.251802 trace git-lfs: Install hook: post-commit, force=false, path=C:\Users\clu\source\repos\Test.git\hooks\post-commit, upgrading...
09:24:05.252805 trace git-lfs: Install hook: post-merge, force=false, path=C:\Users\clu\source\repos\Test.git\hooks\post-merge, upgrading...
09:24:05.253807 trace git-lfs: Initialize filter-process
09:24:05.253807 trace git-lfs: exec: git '-c' 'filter.lfs.smudge=' '-c' 'filter.lfs.clean=' '-c' 'filter.lfs.process=' '-c' 'filter.lfs.required=false' 'rev-parse' 'HEAD' '--symbolic-full-name' 'HEAD'
09:24:05.309955 trace git-lfs: tq: running as batched queue, batch size of 100
error: add_cacheinfo failed to refresh for path '/Lib/ICSharpCode.SharpZipLib.dll'; merge aborting.
fatal: cherry-pick failed
09:24:05.321987 run-command.c:46 trace: run_command: running exit handler for pid 20124
09:24:05.321987 trace git-lfs: filepathfilter: rewrite ".git" as "/.git/"
09:24:05.321987 trace git-lfs: filepathfilter: rewrite "/.git" as "/.git"
09:24:05.321987 trace git-lfs: filepathfilter: rejecting "tmp" via []
09:24:05.321987 trace git-lfs: filepathfilter: accepting "tmp"

@chucklu
Copy link
Author

chucklu commented Aug 7, 2018

It seems the problem is caused by git lfs, after I remove the .gitattributes file from git repository.
The cherry-pick works fine.

@ttaylorr
Copy link

ttaylorr commented Aug 7, 2018

This looks like it's a problem with Git for Window's cherry pick implementation, rather than Git LFS's implementation of anything. @dscho or @chucklu could you please re-open this issue?

If I am wrong, and this is indeed a problem with Git LFS, please don't hesitate to let me know and I'd be more than happy to figure out what's going on.

@dscho
Copy link
Member

dscho commented Aug 7, 2018

If anybody can come up with a truly verifiable MCVE, that would be quite welcome. For the record, the suggested one produces this on my side:

$ git cherry-pick 9e3252^..126c0c
error: object 9e3252dd3d7e9f5475320cb280327ebd248e64e2 is a tree, not a commit
fatal: bad revision '9e3252^..126c0c'

So: that's not an MCVE.

@dscho dscho reopened this Aug 7, 2018
@chucklu
Copy link
Author

chucklu commented Aug 8, 2018

Hi @dscho ,
The command git cherry-pick 9e3252^..126c0c was execute in my local repository.
The commit exist in my repository.

 I will try to reproduce this in another repository later and push it to github.

@dscho
Copy link
Member

dscho commented Aug 8, 2018

I will try to reproduce this in another repository later and push it to github.

Please do so every time you offer an MCVE. If it is not verifiable on the other end, it is not verifiable, and therefore not complete, so it is not an MCVE but an ME. And since it is frustrating for everybody else, either, it is an MFE.

@chucklu
Copy link
Author

chucklu commented Aug 8, 2018

Sorry, I have tired to reproduce it in a new git repository.
But I failed to reproduce, the error only happened in a particular repository, and it' s not public.
I will close this issue for now, thanks for your help @dscho .

@dscho
Copy link
Member

dscho commented Aug 8, 2018 via email

@mehrdadn
Copy link

mehrdadn commented Nov 11, 2018

@dscho I came up with a (hopefully) MCVE. Could you please look into this? :) It's been an extremely frustrating/crippling error to deal with. It was introduced sometime in the last few months; I haven't yet figured out when.

$ git --version --build-options
git version 2.19.1.windows.1.516.g2c704875d0.MSVC
cpu: x86_64
built from commit: 2c704875d0085aa794b18a70d9027acee3906bee
sizeof-long: 4
sizeof-size_t: 8
$ git init --quiet
$ git commit --quiet --allow-empty --allow-empty-message -m ""
$ printf '%s\n' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 > testfile
$ git add testfile
$ git commit --quiet -m "testfile"
$ git branch B1
$ sed "s/18/1x8/" testfile -i
$ git add testfile
$ git commit --quiet -m "testfile18"
$ sed "s/3/x3/" testfile -i
$ git add testfile
$ git commit --quiet -m "testfile3"
$ git branch B2
$ git checkout --quiet B1
$ git cherry-pick B2
error: add_cacheinfo failed to refresh for path 'testfile'; merge aborting.
Auto-merging testfile
fatal: cherry-pick failed

(n.b. I changed the hash above to the nearest one in your repo; the one I built from has my own extra local commits so technically its hash is different.)

@mehrdadn
Copy link

@dscho: Actually, just kidding, I figured it out. It was due to my local addition of enable_fscache(1) in the beginning of refresh_index(). Reverting my change there seems to have fixed the issue for me. Maybe others are encountering a similar issue caused by enable_fscache somewhere?

@ChristianStadelmann
Copy link

I just ran into this issue with git version 2.23.0.windows.1 and would like to add a few more details. Should I open a new bug or would you reopen this one?

@dscho
Copy link
Member

dscho commented Jan 28, 2020

I just ran into this issue with git version 2.23.0.windows.1 and would like to add a few more details. Should I open a new bug or would you reopen this one?

Please first try to reproduce it with v2.25.0, and if it does, please work on an MCVE. Then open a new bug (referencing this bug for the historical record).

Thank you.

@chucklu
Copy link
Author

chucklu commented Jan 28, 2020

@ChristianStadelmann You could open another new issue, if you can provide a git repository which can stably reproduce this bug.

@ChristianStadelmann
Copy link

Ok, thanks for the hints. I'll be trying to find a MCVE and open a new issue then.

@ChristianStadelmann
Copy link

The issue happened with a quite large and complex Repo which surely is no MCVE. Is there any guide to extract a MCVE? Anything better than bisecting and comparing git config and repo metadata?

@dscho
Copy link
Member

dscho commented Jan 29, 2020

Is there any guide to extract a MCVE?

There is no comprehensive guide, no. A couple of things you could try:

  • Try to export the repository with the --anonymize option, then import the result into a freshly git initialized worktree, see if the problem occurs, still.
  • Try to recreate the issue with a substantially reduced set of files:
    • If you, as @chucklu, are cherry-picking a commit range, first identify which commit causes the problem, the figure out whether that commit is enough to git cherry-pick, or whether the symptoms are only on display for commit ranges
    • Identify the files that are changed between HEAD, the commit to be cherry-picked, and its parent. Then copy just that subset of files into a newly git initialized worktree, recreating a very simple commit graph by using the parent as base commit, then applying the changes corresponding to the commit to be cherry-picked, then create a new branch from its parent (git switch -c branch HEAD^), then apply the changes corresponding to HEAD in the original repository.
  • A slightly different method to whittle down the original test case to a minimal one would start with a new worktree and a new branch (git worktree add -b try-to-reduce-to-an-mcve mcve-worktree), then delete some files via git rm from HEAD (and git commit --amend ---no-edit) and try to git cherry-pick again, then delete some more, until you get to a point where the problem does not reproduce any longer. Then try something similar in a second worktree with the commit that needs to be cherry-picked. It is a tedious process all right, but if you don't do it, you cannot ask anybody else to do it, either.
  • Forgo the entire MCVE business and start to debug yourself, most likely by first compiling Git (sdk build git in the Git for Windows SDK), then running it in-place using cd /my/worktree && /usr/src/git/git --exec-path=/usr/src/git cherry-pick ..., then probably instrument the code with tons of fprintf(stderr, "%s:%d ...\n", __FILE__, __LINE_, ...); statements, rebuild and re-run.

@Deeem2031
Copy link

This issue (and #2781) might be related with the question I just posted on stackoverflow, which does have a MCVE. The major difference being that I use a custom merge driver instead of git lfs.
I think it is possible that the underlying cause is the same, so I hope this helps.

@dscho
Copy link
Member

dscho commented Jun 16, 2021

This issue (and #2781) might be related with the question I just posted on stackoverflow, which does have a MCVE. The major difference being that I use a custom merge driver instead of git lfs.
I think it is possible that the underlying cause is the same, so I hope this helps.

Indeed, I think what is happening here is that there is a file with no line endings at all, and during the cherry-pick, the merge driver updated it to have CR/LF line endings. And then refresh_cache_ent() says that it is modified, when the merge machinery assumed that it was just written, so it must be essentially up to date.

@dscho
Copy link
Member

dscho commented Jun 16, 2021

I bet it is this call: https://github.com/git-for-windows/git/blob/v2.32.0.windows.1/merge-recursive.c#L1365-L1366. Right after we asked the low-level merge driver to write that file, and right after we read back the contents written by said driver, we write the loose object verbatim. Via write_object_file(). No conversion, or line endings handled.

But when we then ask ie_modified() (which eventually calls ce_compare_data(), which in turn hands off to index_fd()), the conversions are applied.

a couple of busy hours later

I think I have a fix, at least it fixes the issue demonstrated in the MCVE (for everybody lurking in this ticket: take home this lesson as to just how important an MCVE is):

diff --git a/merge-recursive.c b/merge-recursive.c
index 69d678c9cd77..3c5b6297e399 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1351,6 +1351,7 @@ static int merge_mode_and_contents(struct merge_options *opt,
 		else if (oideq(&b->oid, &o->oid))
 			oidcpy(&result->blob.oid, &a->oid);
 		else if (S_ISREG(a->mode)) {
+			struct strbuf dest = STRBUF_INIT;
 			mmbuffer_t result_buf;
 			int ret = 0, merge_status;
 
@@ -1361,6 +1362,21 @@ static int merge_mode_and_contents(struct merge_options *opt,
 			if ((merge_status < 0) || !result_buf.ptr)
 				ret = err(opt, _("Failed to execute internal merge"));
 
+			if (!ret &&
+			    convert_to_git(opt->repo->index, filename,
+					   result_buf.ptr, result_buf.size,
+					   &dest, 0)) {
+				/*
+				 * Cannot use SWAP() because result_buf.size is
+				 * an unsigned long and dest.len is a size_t.
+				 */
+				size_t len = dest.len;
+				dest.len = result_buf.size;
+				result_buf.size = len;
+				SWAP(result_buf.ptr, dest.buf);
+			}
+			strbuf_release(&dest);
+
 			if (!ret &&
 			    write_object_file(result_buf.ptr, result_buf.size,
 					      blob_type, &result->blob.oid))

I will now work on a regression test and then contribute the patch to the Git mailing list.

@dscho
Copy link
Member

dscho commented Jun 16, 2021

Waaaait a moment.

The custom merge driver is supposed to receive the clean contents, not the smudged ones. For example, if CR/LF line endings are configured, the merge driver sees the files with LF-only line endings, just like they are in Git's database.

Likewise, the merge driver is supposed to write a result that is clean, not smudged. In our case, this would be without CR/LF line endings.

In your MCVE, the contents of file.txt do not have a line ending. Neither does $localFile contain that line ending. It comes in by writing the contents out using Out-File without -NoNewline.

So the bug is actually in the merge driver, and above-mentioned diff is incorrect.

I admit that the error message is not helpful at all, and should probably be improved.

@dscho
Copy link
Member

dscho commented Jun 16, 2021

@Deeem2031 I left this answer at the StackOverflow post:

The problem is actually in the merge driver, i.e. mergeDriver.ps1.

Git's contract is that the file contents received, and written, by the merge driver are in the "clean" form, i.e. in your case with LF-only (or at least without CR/LF) line endings.

However, (Get-Content $localFile) | Out-File $localFile does not leave the file contents unchanged, despite how it might look like. The reason is that $localFile has no line ending at all in your case. hexdump -C says this about its contents:

00000000  ef bb bf 76 65 72 73 69  6f 6e 20 3d 20 31 35 30  |...version = 150|

And Out-File appends a CR/LF!

So if you change your merge driver to call Out-File -NoNewline instead, it will work without that add_cacheinfo error message.

That is, it will work as intended: that cherry-pick will say that nothing was changed, and ask you if you want to commit nevertheless (which would require the --allow-empty option).

@mehrdadn
Copy link

I think even Get-Content appends a newline... I'm not sure if there's a safe way to do this in native PowerShell at all. You might need to use File.ReadAllBytes and just hope the file fits in memory.

@builder-main
Copy link

Hello there, how is the issue going. I'm facing the following :
Best regards

git cherry-pick feature/multithreaded-tests^1 feature/multithreaded-tests
error: add_cacheinfo failed to refresh for path 'XXX'; merge aborting.
fatal: cherry-pick failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants