"Assertion failed" when using patch.exe of Git for Windows

Issue

I have a directory contains several files to be modified. Instead of doing changes manually(because there are so many files) i downloaded a diff file(made by some other user), this diff file is executed by a .bat file.

let me make it more systematic.

  1. bat file is WinDDK_7600.16385.1_patch.bat and path of this file is(C:\Users\kunze\Documents\Visual Studio 2010\Projects\busmaster-master\Documents\1 Development Environment\files)

contents of this file are

@echo on

set PATH=%PATH%;%ProgramFiles%\Git\bin

patch -p1 -d C:/ < WinDDK_7600.16385.1.diff

pause
  1. When i run bat file this will run WinDDK_7600.16385.1.diff and this difference file has changes for many fileslocated in C:\WinDDK. Path of this file is C:\Users\kunze\Documents\Visual Studio 2010\Projects\busmaster-master\Documents\1 Development Environment\files

  2. Files for which differences need to be updated are located in this directory C:\WinDDK

  3. I already have set path environment variable for git/bin

  4. Can someone please let me know what changes should i made in my WinDDK_7600.16385.1_patch.bat file so that it will find and update all the files located in C:\WinDDK directory

I have tried several times and every time i am getting this error "Assertion failed: hunk, file ../patch-2.5.9-src/patch.c, line 354" ? whats the issue ?

Solution

.diff files, the patch tool and their relevance to Git

First of all, this problem has nothing to do with Git. Git for Windows, which you supposedly have installed on your computer, just happens to be shipped with the Windows port of patcha program to apply changes described by specially-formatted files. Specifically, GfW includes the GNU patch program.

The patch.exe program supplied with GfW is located under %ProgramFiles%\Git\bin (unless you’ve overriden the installation location).

What does a .diff file contain and how patch works

The patch file format

To cite the Wikipedia article linked above, a diff file looks like this:

--- /path/to/original   ''timestamp''
+++ /path/to/new    ''timestamp''
@@ -1,3 +1,9 @@
+This is an important
+notice! It should
+therefore be located at
+the beginning of this
+document!
+
 This part of the
 document has stayed the
 same from version to
@@ -5,16 +11,10 @@
 be shown if it doesn't
 change.  Otherwise, that
 would not be helping to
-compress the size of the
-changes.
-
-This paragraph contains
-text that is outdated.
-It will be deleted in the
-near future.
+compress anything.

 It is important to spell
-check this dokument. On
+check this document. On
 the other hand, a
 misspelled word isn't
 the end of the world.

Here’s what we have here:

  • First are the two lines of the header which describe which file was original and which one was “new” when the diff file was generated based on them—the differences are in the “new” file compared to the “original” one.
  • The @@ ... @@ blocks delimit “hunks” which describe where in the original file the piece to change by this hunk is located, how many lines it originally contained and how many it will contain after patching.

    The next (and most important) thing about the hunk is change markers: + denote added lines, - denote deleted lines while lines prefixed with (a single space character) do not change and provide context for the patch tool to be able to perform “fuzzy matching”—based not only on line count but on actual file content as well.

How the patch tool works

The patch tool takes the .diff file and

  1. Reads it up until the first header, parses the header, extracts the name of the file to patch from it.
  2. Locates the file with the name obtained on step (1) in the target directory.
  3. Reads the first hunk, locates it in the file it found, and applies the patch from the hunk.

    If patching the hunk fails, patch creates a special “rejects” file (by combining the tail name of the file it attempted to patch plus the .rej extension) and writes there the failed hunk.

  4. Goes to the next hunk and repeats until the end of the patch file is hit of the new header is found.

    If the next header is found, it repeats the steps starting from (2), otherwise it exits.

How the patch tool locates the files to patch

Most often, headers in patch files contain relative pathnames (like foo/bar/baz.c) and the patch tool goes like this:

  1. Extracts that name from the header.
  2. Takes the tool’s current directory and appends that pathname onto it to get the name of the file to patch.

Two command-line options affect the patch tool’s behaviour:

  • The -d <dir> option tell it to change its current directory to <dir> before doing its work.
  • The -p N option tell it to trim N path components off the pathname extracted from the header before further considering it.

    This means that with -p1 passed to it, patch would convert foo/bar/baz.c to bar/baz.c before trying to locate that file.

By now, you should be able to fully understand what your batch file does, and I ask you to work this out to stop considering all this the black voodoo.

“Assertion failed” error from the patch tool

My guess is that you’ve hit an unfortunate bug which occasionally manifests itself in various Windows ports of patch—a problem with EOL markers: the tool simply chokes on CR+LF sequences.

Possible ways to work around this:

  • Try git apply as explained here—Git does not use patch.exe but rather its own machinery which is taught by GfW porters to work okay with Windows EOLs.
  • Try other ports of patch, for instance this one from the GnuWin32 project.

    Note that you might hit some UAC problem with it; here is how to fix it.

Answered By – kostix

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published