Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git-apply fails mysteriously, how do I troubleshoot/fix?

Tags:

git

patch

I'm currently trying to to code-style checking on the PRs of a (github) repository, and I want to deliver patches to the submitters with which they can easily fix the codestyle. To this end, I'm pulling down their PR, run our uncrustify script over it to fix any style errors, and want to create a .patch file they can easily apply. However, it consistently breaks on some files.

I do (git version 1.7.10.4 with core.autocrlf=input, core.filemode=false):

$ git checkout pr-branch $ git log -1 (shows: commit dbb8d3f) $ git status (nothing to commit, working directory clean) $ <run the code styler script, which modifies some files> $ git diff > ../style.patch (so the patch file lands outside the repo) $ git reset --hard HEAD (to simulate the situation at the submitter's end) $ git log -1 (shows: commit dbb8d3f) $ git status (nothing to commit, working directory clean, so we are where we started) $ git apply ../style.patch error: patch failed: somefile.cpp:195 error: somefile.cpp: patch does not apply (same output using the --check option) 

This only applies to some files, not all of them. I don't know how to troubleshoot this, i.e. how to get git to tell me exactly where it goes wrong - it only tells me a hunk# when I dig, but that's still pretty huge.

What I've tried so far (without success):

  1. apply --reverse, apply --whitespace=nowarn
  2. diff HEAD instead of diff alone
  3. make a dummy commit (committing works without problem!), use format-patch, delete the dummy commit, apply patch with git-am with or without -3, or apply with git-apply
  4. Have the patch file in the local dir instead of one up (grasping at straws, here)
  5. Check the man-pages of git-diff, -apply, -format-patch, -am for anything useful
  6. patch with the linux patch command
  7. ....

I don't know what could be wrong with the diff. Whitespace things should only warn, right? In any case, I won't want to ignore them, since it's a style fix which obviously involves whitespace.

How can I fix/diagnose this or even find out where it bails exactly? Would it help if I posted the diff of one of the culprit files? What baffles me also is that the committ works without problem, but the patch created from the commit does not??

After wrestling with this for several hours I'm at the end of my knowledge...

like image 776
Christoph Avatar asked Feb 01 '13 15:02

Christoph


People also ask

Why is git apply skipping patch?

A patch is usually skipped when the changes it contains were already applied in the past. There are many possible reasons for this: a merge, a cherry-pick, changes operated manually or using another patch etc.

What is git apply?

git apply takes a patch (e.g. the output of git diff ) and applies it to the working directory (or index, if --index or --cached is used). git am takes a mailbox of commits formatted as an email messages (e.g. the output of git format-patch ) and applies them to the current branch.

What is git patch?

GIT patch or GIT diff is used to share the changes made by you to others without pushing it to main branch of the repository. This way other people can check your changes from the GIT patch file you made and suggest the necessary corrections.


2 Answers

Update:

You can use git apply -v to see more detailed info about what's going on, git apply --check to just verify the operation, or git apply --index to rebuild the local index file.

Based on your comment, it seems your local index was corrupted, and so index solved it.

I will leave my original answer and the comments mostly to give people context on what was going on, as I suspect other people would jump to the same initial conclusions I had based on the problem description.

------

Most likely nothing's wrong with the diff. Instead look at the target git repository. While you are doing git reset --hard HEAD, nothing guarantees you that the HEAD on that other repository is the same as the HEAD on your.

Do git log on the target repo and look at the commit at the top. Is it the same as the one you produced the diff from? Most likely it is not. Look down the history and check if the commit you need is there. If it is, then the target repo is ahead of yours, and you have to go back, do git pull (or git rebase) and produce a new diff. If it isn't, then the target repo is behind yours, and you need to do git pull (or git rebase) on the target repo to bring it up to speed.

Keep in mind that if you have other people committing to your "master" repo (the one where bot yours and the target repositories are pulling from), you might have to git pull both repositories, to get them to a reasonably recent common commit.

like image 132
Franci Penov Avatar answered Oct 05 '22 20:10

Franci Penov


Try to check against your patch file - example :

git apply --reject mypatch.patch 

this will show you differences if any - here is an example of how it could look like :

error: patch failed: <filename>:<linenumber> error: while searching for :     cout << "}" << endl; // example of a line in your patch 
like image 20
serup Avatar answered Oct 05 '22 19:10

serup