summaryrefslogtreecommitdiff
path: root/tests/diff
Commit message (Collapse)AuthorAgeFilesLines
* diff::parse: don't include `diff.h`ethomson/diff_parseEdward Thomson2020-06-051-1/+0
| | | | | We don't call any internal functions in the test; we don't need to include `../src/diff.h`.
* diff::workdir: actually test the buffersethomson/difftestEdward Thomson2020-05-231-3/+3
| | | | | | The static test data is erroneously initialized with a length of 0 for three of the strings. This means the tests are not actually examining those strings. Provide the length.
* tests: diff: add test to verify behaviour with empty dir orderingPatrick Steinhardt2020-02-071-0/+43
| | | | | | | It was reported that, given a file "abc.txt", a diff will be shown if an empty directory "abb/" is created, but not if "abd/" is created. Add a test to verify that we do the right thing here and do not depend on any ordering.
* tests: diff: verify that we are able to diff with empty subtreesPatrick Steinhardt2020-02-071-0/+49
| | | | | | | | | | | | While it is not allowed for a tree to have an empty tree as child (e.g. an empty directory), libgit2's tree builder makes it easy to create such trees. As a result, some applications may inadvertently end up with such an invalid tree, and we should try our best and handle them. One such case is when diffing two trees, where one of both trees has such an empty subtree. It was reported that this will cause our diff code to fail. While I wasn't able to reproduce this error, let's still add a test that verifies we continue to handle them correctly.
* diff: make patchid computation work with all types of commits.Gregory Herrero2019-11-281-0/+33
| | | | | | | | | | Current implementation of patchid is not computing a correct patchid when given a patch where, for example, a new file is added or removed. Some more corner cases need to be handled to have same behavior as git patch-id command. Add some more tests to cover those corner cases. Signed-off-by: Gregory Herrero <gregory.herrero@oracle.com>
* patch_parse: handle patches without extended headersDenis Laxalde2019-10-161-0/+10
| | | | | | | | | Extended header lines (especially the "index <hash>..<hash> <mode>") are not required by "git apply" so it import patches. So we allow the from-file/to-file lines (--- a/file\n+++ b/file) to directly follow the git diff header. This fixes #5267.
* patch_parse: handle patches with new empty filesDenis Laxalde2019-09-281-0/+20
| | | | | | | Patches containing additions of empty files will not contain diff data but will end with the index header line followed by the terminating sequence "-- ". We follow the same logic as in cc4c44a and allow "-- " to immediately follow the index header.
* fileops: rename to "futils.h" to match function signaturesPatrick Steinhardt2019-07-201-1/+1
| | | | | | | | | Our file utils functions all have a "futils" prefix, e.g. `git_futils_touch`. One would thus naturally guess that their definitions and implementation would live in files "futils.h" and "futils.c", respectively, but in fact they live in "fileops.h". Rename the files to match expectations.
* configuration: cvar -> configmapPatrick Steinhardt2019-07-181-1/+1
| | | | | `cvar` is an unhelpful name. Refactor its usage to `configmap` for more clarity.
* oid: `is_zero` instead of `iszero`Edward Thomson2019-06-161-10/+10
| | | | | | The only function that is named `issomething` (without underscore) was `git_oid_iszero`. Rename it to `git_oid_is_zero` for consistency with the rest of the library.
* Rename opt init functions to `options_init`Edward Thomson2019-06-143-4/+4
| | | | | | | | | | | | | In libgit2 nomenclature, when we need to verb a direct object, we name a function `git_directobject_verb`. Thus, if we need to init an options structure named `git_foo_options`, then the name of the function that does that should be `git_foo_options_init`. The previous names of `git_foo_init_options` is close - it _sounds_ as if it's initializing the options of a `foo`, but in fact `git_foo_options` is its own noun that should be respected. Deprecate the old names; they'll now call directly to the new ones.
* patch_parse.c: Handle CRLF in parse_header_startDrew DeVault2019-04-051-0/+19
|
* tests: diff: test parsing diffs with a new file with spaces in its pathErik Aigner2019-03-291-0/+18
| | | | | Add a test that verifies that we are able to parse patches which add a new file that has spaces in its path.
* git_error: use new names in internal APIs and usageEdward Thomson2019-01-227-29/+29
| | | | | Move to the `git_error` name in the internal API for error-related functions.
* object_type: use new enumeration namesethomson/index_fixesEdward Thomson2018-12-013-4/+4
| | | | Use the new object_type enumeration names within the codebase.
* index: use new enum and structure namesEdward Thomson2018-12-011-3/+3
| | | | Use the new-style index names throughout our own codebase.
* diff_stats: use git's formatting of renames with common directoriesPatrick Steinhardt2018-10-041-1/+1
| | | | | | | | | | | In cases where a file gets renamed such that the directories containing it previous and after the rename have a common prefix, then git will avoid printing this prefix twice and instead format the rename as "prefix/{old => new}". We currently didn't do anything like that, but simply printed "prefix/old -> prefix/new". Adjust our behaviour to instead match upstream. Adjust the test for this behaviour to expect the new format.
* tests: verify diff stats with renames in subdirectoryPatrick Steinhardt2018-10-041-0/+19
| | | | | | | | | | | Until now, we didn't have any tests that verified that our format for renames in subdirectories is correct. While our current behaviour is no different than for renames that do not happen with a common prefix shared between old and new file name, we intend to change the format to instead match the format that upstream git uses. Add a test case for this to document our current behaviour and to show how the next commit will change that format.
* Merge pull request #4702 from tiennou/fix/coverityPatrick Steinhardt2018-07-201-2/+2
|\ | | | | Assorted Coverity fixes
| * tests: add missing cl_git_pass to testsEtienne Samson2018-07-061-2/+2
| | | | | | Reported by Coverity, CID 1393678-1393697.
* | Merge pull request #4719 from pks-t/pks/delta-oobEdward Thomson2018-07-091-0/+1
|\ \ | |/ |/| Delta OOB access
| * delta: fix sign-extension of big left-shiftPatrick Steinhardt2018-06-291-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Our delta code was originally adapted from JGit, which itself adapted it from git itself. Due to this heritage, we inherited a bug from git.git in how we compute the delta offset, which was fixed upstream in 48fb7deb5 (Fix big left-shifts of unsigned char, 2009-06-17). As explained by Linus: Shifting 'unsigned char' or 'unsigned short' left can result in sign extension errors, since the C integer promotion rules means that the unsigned char/short will get implicitly promoted to a signed 'int' due to the shift (or due to other operations). This normally doesn't matter, but if you shift things up sufficiently, it will now set the sign bit in 'int', and a subsequent cast to a bigger type (eg 'long' or 'unsigned long') will now sign-extend the value despite the original expression being unsigned. One example of this would be something like unsigned long size; unsigned char c; size += c << 24; where despite all the variables being unsigned, 'c << 24' ends up being a signed entity, and will get sign-extended when then doing the addition in an 'unsigned long' type. Since git uses 'unsigned char' pointers extensively, we actually have this bug in a couple of places. In our delta code, we inherited such a bogus shift when computing the offset at which the delta base is to be found. Due to the sign extension we can end up with an offset where all the bits are set. This can allow an arbitrary memory read, as the addition in `base_len < off + len` can now overflow if `off` has all its bits set. Fix the issue by casting the result of `*delta++ << 24UL` to an unsigned integer again. Add a test with a crafted delta that would actually succeed with an out-of-bounds read in case where the cast wouldn't exist. Reported-by: Riccardo Schirone <rschiron@redhat.com> Test-provided-by: Riccardo Schirone <rschiron@redhat.com>
* | patch_parse: populate line numbers while parsing diffsEtienne Samson2018-06-191-0/+71
|/
* Convert usage of `git_buf_free` to new `git_buf_dispose`Patrick Steinhardt2018-06-1011-77/+77
|
* Sanitize the hunk header to ensure it contains UTF-8 valid dataStan Hu2018-05-051-0/+92
| | | | | | | | | | The diff driver truncates the hunk header text to 80 bytes, which can truncate 4-byte Unicode characters and introduce garbage characters in the diff output. This change sanitizes the hunk header before it is displayed. This mirrors the test in git: https://github.com/git/git/blob/master/t/t4025-hunk-header.sh Closes https://github.com/libgit2/rugged/issues/716
* typo: Fixed a trivial typo in test function.Erik van Zijst2018-04-051-1/+1
|
* diff_tform: fix rename detection with rewrite/delete pairPatrick Steinhardt2018-02-201-0/+213
| | | | | | | | | | | | | | | | | | | | | A rewritten file can either be classified as a modification of its contents or of a delete of the complete file followed by an addition of the new content. This distinction becomes important when we want to detect renames for rewrites. Given a scenario where a file "a" has been deleted and another file "b" has been renamed to "a", this should be detected as a deletion of "a" followed by a rename of "a" -> "b". Thus, splitting of the original rewrite into a delete/add pair is important here. This splitting is represented by a flag we can set at the current delta. While the flag is already being set in case we want to break rewrites, we do not do so in case where the `GIT_DIFF_FIND_RENAMES_FROM_REWRITES` flag is set. This can trigger an assert when we try to match the source and target deltas. Fix the issue by setting the `GIT_DIFF_FLAG__TO_SPLIT` flag at the delta when it is a rename target and `GIT_DIFF_FIND_RENAMES_FROM_REWRITES` is set.
* tests: add rename-rewrite scenarios to "renames" repositoryPatrick Steinhardt2018-02-201-0/+12
| | | | | | | Add two more scenarios to the "renames" repository. The first scenario has a major rewrite of a file and a delete of another file, the second scenario has a deletion of a file and rename of another file to the deleted file. Both scenarios will be used in the following commit.
* tests: diff::rename: use defines for commit OIDsPatrick Steinhardt2018-02-201-19/+24
| | | | | | | While we frequently reuse commit OIDs throughout the file, we do not have any constants to refer to these commits. Make this a bit easier to read by giving the commit OIDs somewhat descriptive names of what kind of commit they refer to.
* diff_file: properly refcount blobs when initializing file contentsPatrick Steinhardt2017-12-151-0/+39
| | | | | | | | | | | | | | When initializing a `git_diff_file_content` from a source whose data is derived from a blob, we simply assign the blob's pointer to the resulting struct without incrementing its refcount. Thus, the structure can only be used as long as the blob is kept alive by the caller. Fix the issue by using `git_blob_dup` instead of a direct assignment. This function will increment the refcount of the blob without allocating new memory, so it does exactly what we want. As `git_diff_file_content__unload` already frees the blob when `GIT_DIFF_FLAG__FREE_BLOB` is set, we don't need to add new code handling the free but only have to set that flag correctly.
* patch_parse: fix parsing patches only containing exact renamesPatrick Steinhardt2017-09-011-0/+21
| | | | | | | | Patches which contain exact renames only will not contain an actual diff body, but only a list of files that were renamed. Thus, the patch header is immediately followed by the terminating sequence "-- ". We currently do not recognize this character sequence as a possible terminating sequence. Add it and create a test to catch the failure.
* diff: implement function to calculate patch IDPatrick Steinhardt2017-06-261-0/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The upstream git project provides the ability to calculate a so-called patch ID. Quoting from git-patch-id(1): A "patch ID" is nothing but a sum of SHA-1 of the file diffs associated with a patch, with whitespace and line numbers ignored." Patch IDs can be used to identify two patches which are probably the same thing, e.g. when a patch has been cherry-picked to another branch. This commit implements a new function `git_diff_patchid`, which gets a patch and derives an OID from the diff. Note the different terminology here: a patch in libgit2 are the differences in a single file and a diff can contain multiple patches for different files. The implementation matches the upstream implementation and should derive the same OID for the same diff. In fact, some code has been directly derived from the upstream implementation. The upstream implementation has two different modes to calculate patch IDs, which is the stable and unstable mode. The old way of calculating the patch IDs was unstable in a sense that a different ordering the diffs was leading to different results. This oversight was fixed in git 1.9, but as git tries hard to never break existing workflows, the old and unstable way is still default. The newer and stable way does not care for ordering of the diff hunks, and in fact it is the mode that should probably be used today. So right now, we only implement the stable way of generating the patch ID.
* diff_parse: correctly set options for parsed diffsPatrick Steinhardt2017-03-141-0/+21
| | | | | | | | | | | | The function `diff_parsed_alloc` allocates and initializes a `git_diff_parsed` structure. This structure also contains diff options. While we initialize its flags, we fail to do a real initialization of its values. This bites us when we want to actually use the generated diff as we do not se the option's version field, which is required to operate correctly. Fix the issue by executing `git_diff_init_options` on the embedded struct.
* patch_parse: fix parsing minimal trailing diff linePatrick Steinhardt2017-03-141-0/+21
| | | | | | | | | | | | | | | | | | | | In a diff, the shortest possible hunk with a modification (that is, no deletion) results from a file with only one line with a single character which is removed. Thus the following hunk @@ -1 +1 @@ -a + is the shortest valid hunk modifying a line. The function parsing the hunk body though assumes that there must always be at least 4 bytes present to make up a valid hunk, which is obviously wrong in this case. The absolute minimum number of bytes required for a modification is actually 2 bytes, that is the "+" and the following newline. Note: if there is no trailing newline, the assumption will not be offended as the diff will have a line "\ No trailing newline" at its end. This patch fixes the issue by lowering the amount of bytes required.
* patch_generate: fix `git_diff_foreach` only working with generated diffsPatrick Steinhardt2017-03-141-0/+29
| | | | | | | | | | | | | | | The current logic of `git_diff_foreach` makes the assumption that all diffs passed in are actually derived from generated diffs. With these assumptions we try to derive the actual diff by inspecting either the working directory files or blobs of a repository. This obviously cannot work for diffs parsed from a file, where we do not necessarily have a repository at hand. Since the introduced split of parsed and generated patches, there are multiple functions which help us to handle patches generically, being indifferent from where they stem from. Use these functions and remove the old logic specific to generated patches. This allows re-using the same code for invoking the callbacks on the deltas.
* Merge branch 'pr/3809'Edward Thomson2016-10-092-2/+38
|\
| * make git_diff_stats_to_buf not show 0 insertions or 0 deletionsSim Domingo2016-10-092-2/+38
| |
* | Teach `git_patch_from_diff` about parsed diffsethomson/patch_from_diffEdward Thomson2016-08-241-0/+45
| | | | | | | | | | Ensure that `git_patch_from_diff` can return the patch for parsed diffs, not just generate a patch for a generated diff.
* | patch: show copy information for identical copiesEdward Thomson2016-06-254-13/+98
| | | | | | | | | | | | | | When showing copy information because we are duplicating contents, for example, when performing a `diff --find-copies-harder -M100 -B100`, then show copy from/to lines in a patch, and do not show context. Ensure that we can also parse such patches.
* | patch::parse: test diff with exact rename and copyEdward Thomson2016-06-251-0/+5
| |
* | patch::parse: test diff with simple renameEdward Thomson2016-06-251-12/+27
| |
* | diff::parse tests: test parsing a diffEdward Thomson2016-06-253-0/+107
| | | | | | | | | | Test that we can create a diff file, then parse the results and that the two are identical in-memory.
* | introduce `git_diff_from_buffer` to parse diffsEdward Thomson2016-05-261-0/+60
| | | | | | | | Parse diff files into a `git_diff` structure.
* | git_diff_generated: abstract generated diffsEdward Thomson2016-05-262-0/+2
|/
* diff: test submodules are found with trailing `/`Edward Thomson2016-04-021-0/+47
| | | | | Test that submodules are found when the are included in a pathspec but have a trailing slash.
* iterator: give the tests a proper hierarchyEdward Thomson2016-03-241-1005/+0
| | | | | | Iterator tests were split over repo::iterator and diff::iterator, with duplication between the two. Move them to iterator::index, iterator::tree, and iterator::workdir.
* Added clar test for #3568Jeff Hostetler2016-03-231-0/+129
|
* iterators: refactored tree iteratorEdward Thomson2016-03-231-10/+3
| | | | | | | | Refactored the tree iterator to never recurse; simply process the next entry in order in `advance`. Additionally, reduce the number of allocations and sorting as much as possible to provide a ~30% speedup on case-sensitive iteration. (The gains for case-insensitive iteration are less majestic.)
* iterator: disambiguate reset and reset_rangeEdward Thomson2016-03-231-2/+2
| | | | | | Disambiguate the reset and reset_range functions. Now reset_range with a NULL path will clear the start or end; reset will leave the existing start and end unchanged.
* tree: re-use the id and filename in the odb objectCarlos Martín Nieto2016-03-201-1/+1
| | | | | Instead of copying over the data into the individual entries, point to the originals, which are already in a format we can use.