Skip to content
Merged

Diff #103

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
5012bd2
Sketch initialisation API
boidanny Nov 29, 2012
abbeada
Declare an enum for git_delta_t
boidanny Nov 30, 2012
543ded7
Sketch a processing block for the file level of the diff.
boidanny Nov 30, 2012
bf67679
Sketch GTDiffDelta API.
boidanny Nov 30, 2012
e9cb72f
Sketch GTDiffFile API.
boidanny Nov 30, 2012
0f69f51
Sketch GTDiffHunk API
boidanny Nov 30, 2012
b9e1dce
Reflect new class structure in GTDiff.h
boidanny Nov 30, 2012
c7488b5
Update project.
boidanny Nov 30, 2012
595c0eb
Create hunk initialisation API.
boidanny Nov 30, 2012
6924548
Delta initialisation.
boidanny Nov 30, 2012
04a250f
GTDiff initialisation.
boidanny Nov 30, 2012
a7080d5
Move the declaration of GTDiffFileDelta.
boidanny Nov 30, 2012
aa40c44
Remove unnecessary `@class`
boidanny Nov 30, 2012
a2701e9
Add API to fetch the number of deltas of a given type.
boidanny Nov 30, 2012
fe41bc2
GTDiff lifecycle.
boidanny Nov 30, 2012
b4f0c1d
Implement delta generation.
boidanny Nov 30, 2012
7147838
Only build deltas once.
boidanny Nov 30, 2012
f8bfb12
Adjust convenience constructors signatures.
boidanny Nov 30, 2012
542d8eb
Note that we need to settle on an options strategy.
boidanny Nov 30, 2012
f6e2d94
Implement initialisation for 2 trees.
boidanny Nov 30, 2012
fe68272
Implement diff from index to tree.
boidanny Nov 30, 2012
f8c8e7d
Implement working dir to index.
boidanny Nov 30, 2012
f284d8b
Implement working dir to tree.
boidanny Nov 30, 2012
86484d5
GTDiffDelta is now initialised with a patch.
boidanny Nov 30, 2012
583faca
Typo fix.
boidanny Nov 30, 2012
7faa681
Hunks should be enumerated to keep them lazy-ish.
boidanny Nov 30, 2012
1782579
Implement basic lifecycle of GTDiffDelta.
boidanny Nov 30, 2012
18af33f
Implement git_diff_delta.
boidanny Nov 30, 2012
90b04c1
Diff file initialisation API.
boidanny Nov 30, 2012
eccc58c
isBinary implementation.
boidanny Nov 30, 2012
5c743f5
old and new file implementation.
boidanny Nov 30, 2012
e35e59b
Status implementaiton.
boidanny Nov 30, 2012
75cad03
hunkCount implementation.
boidanny Nov 30, 2012
27d91e8
Return hunks as an array.
boidanny Nov 30, 2012
be3b54d
Whitespace --;
boidanny Nov 30, 2012
8ed3942
Initialise a hunk with a delta and hunk number.
boidanny Nov 30, 2012
d849daf
Hunk initialisation.
boidanny Nov 30, 2012
c4fffb4
Hunk enumeration.
boidanny Nov 30, 2012
aff2911
Move the libgit2 pointer back to where it currently is… no idea why t…
boidanny Nov 30, 2012
1d13af1
Update signatures of difflist initialisers.
boidanny Nov 30, 2012
970f80b
Correctly initialise hunks.
boidanny Nov 30, 2012
90d73a2
Implement GTDiffFile as a simple state object.
boidanny Nov 30, 2012
83a114d
Move back to enumerating over the deltas.
boidanny Nov 30, 2012
b863826
Change options to a dictionary.
boidanny Nov 30, 2012
e27e129
Declare options consts.
boidanny Nov 30, 2012
d4d2750
Declare options flags enum.
boidanny Nov 30, 2012
d20ea18
Implement the options consts.
boidanny Nov 30, 2012
94d6ccf
Implement the building of an options struct.
boidanny Nov 30, 2012
79a361f
Return NULL if given a nil dictionary.
boidanny Nov 30, 2012
5833ebd
Lol pointers.
boidanny Nov 30, 2012
60e49e9
Pass the created options struct into our diff creation.
boidanny Nov 30, 2012
3cfd2e8
More cocoa-y block usage in GTDiff.
boidanny Dec 3, 2012
a9be483
OldTree -> Tree
boidanny Dec 4, 2012
b2c681a
ForRepository -> InRepository
boidanny Dec 4, 2012
4b3f1d2
uint32 -> uint32_t
boidanny Dec 4, 2012
4af300b
Style fix for braces.
boidanny Dec 4, 2012
c55ac1d
Assert we aren't initing with a difflist.
boidanny Dec 4, 2012
4bd0faf
Remove unused block typedef.
boidanny Dec 4, 2012
f4dc110
Assert that we don't initialise a delta with a NULL patch.
boidanny Dec 4, 2012
fe888e3
Brace style fix.
boidanny Dec 4, 2012
11a2650
Copy hunks.
boidanny Dec 4, 2012
64662f5
Cocoa-y blocks in GTDiffHunk.
boidanny Dec 4, 2012
3588a67
Use initWithBytes:length:encoding over withCharacters.
boidanny Dec 4, 2012
e31a8b4
We don't need to demand repositories from the user.
boidanny Dec 4, 2012
e1fd8f9
Document options consts.
boidanny Dec 4, 2012
8ee8f8a
Document flags enum.
boidanny Dec 4, 2012
08c439f
Document GTDiff class.
boidanny Dec 4, 2012
003836c
Document the git_diff_list property.
boidanny Dec 4, 2012
260cb4a
Remove unnecesary to-do.
boidanny Dec 4, 2012
ff9a35e
Document deltaCount.
boidanny Dec 4, 2012
09fa475
Document initialisers.
boidanny Dec 4, 2012
d97733e
Document numberOfDeltasWithType.
boidanny Dec 4, 2012
6c975af
Document enumerateDeltasUsingBlock.
boidanny Dec 4, 2012
5943df0
Unsplit the 2 @class statements in GTDiffDelta.
boidanny Dec 4, 2012
07c6b5b
Document GTDiffDeltaType.
boidanny Dec 4, 2012
7cb03c2
Document GTDiffDelta.
boidanny Dec 4, 2012
6c9cd12
Document the delta's libgit2 properties.
boidanny Dec 4, 2012
6dffb7f
Document GTDiffData's basic state.
boidanny Dec 4, 2012
8bb9a38
Document -hunks.
boidanny Dec 4, 2012
088ee0a
Document the designated initialiser.
boidanny Dec 4, 2012
7244eb0
NSUInteger -> mode_t for a file's mode.
boidanny Dec 4, 2012
cf82c0f
Document GTDiffFile.
boidanny Dec 4, 2012
27ac67c
Unnecessary @class --
boidanny Dec 4, 2012
b80d355
Document GTDiffHunk.
boidanny Dec 4, 2012
4216ce9
Make ze headers public.
boidanny Dec 4, 2012
8f2a753
withOptions -> options.
boidanny Dec 5, 2012
587c2d7
Better English for numberofDeltasWithType documentation.
boidanny Dec 5, 2012
cea22d0
recommend -> recommended
boidanny Dec 5, 2012
9377752
Updating the implementation with new method sigs helps.
boidanny Dec 5, 2012
b89e3b1
Don't allocate options struct on the heap.
boidanny Dec 10, 2012
838b971
Comment our cast to char*
boidanny Dec 10, 2012
48cc651
return const git_diff_delta* rather than lacking the const.
boidanny Dec 10, 2012
b7702d9
Return nil if a hunk fails to correctly initialise.
boidanny Dec 10, 2012
e7bd6f1
Better docs for diff options courtesy of @arrbee.
boidanny Dec 10, 2012
6759e89
Add GTDiffFileDeltaTypeChange documentation.
boidanny Dec 10, 2012
3ee7044
Use copy to denote immutable readonly properties.
boidanny Dec 10, 2012
2ed1806
Use the more cocoa boolean method to stop enumeration.
boidanny Dec 10, 2012
fb7f585
Stub tests and remove auto-running tests on build.
boidanny Dec 11, 2012
c689349
Safer diff initialisers.
boidanny Dec 11, 2012
687d28b
Options struct is now created by writeback.
boidanny Dec 11, 2012
31c91e0
Flesh out initialisation tests.
boidanny Dec 11, 2012
07b38f7
Rearrange setup slightly.
boidanny Dec 11, 2012
a77854c
Add unit tests for the diff content.
boidanny Dec 13, 2012
e8d25b4
Strip trailing new lines in hunk headers.
boidanny Dec 13, 2012
32e1d0c
Strip out any newlines for diff lines too.
boidanny Dec 13, 2012
5f00a30
Add headers to objectivegit.h.
boidanny Dec 13, 2012
3811b2c
Create a spec for the diff tests and move initialisation to it.
boidanny Dec 17, 2012
85f6dcf
Remove old diff tests.
boidanny Dec 17, 2012
0e96d8a
Add the Test_App repo into our test fixtures.
boidanny Dec 17, 2012
2d22b60
Add an inline function to get the new test app fixture.
boidanny Dec 17, 2012
3ef8978
Use the zipped up fixtures instead.
boidanny Dec 17, 2012
934a826
Deal with unzipping test fixtures at test-time.
boidanny Dec 17, 2012
7f68b0f
Add a much more thorough test of a basic modified file diff.
boidanny Dec 17, 2012
f4a3e56
Test for nil diffs.
boidanny Dec 17, 2012
0b49035
Test for added file diffs.
boidanny Dec 17, 2012
7500fef
Test for binary files.
boidanny Dec 17, 2012
6ce9109
Abstract out all that duplicated setup code.
boidanny Dec 17, 2012
53336ec
Unit test file deletions.
boidanny Dec 17, 2012
90728c0
Block style fixes.
boidanny Dec 17, 2012
57bd3bb
Document that GTDiffFileDeltaTypeChange goes both ways
boidanny Dec 17, 2012
e46310c
Adjust naming to make more sense.
boidanny Dec 17, 2012
9aa5127
Clearer diff creation docs.
boidanny Dec 17, 2012
f2ed1d9
Param assert that block shit.
boidanny Dec 17, 2012
1fd5d68
We now have an enumeration-based API for hunks.
boidanny Dec 17, 2012
38d07a1
Document the new hunk enumeration.
boidanny Dec 17, 2012
50a9212
Use the new hunk enumeration in our tests.
boidanny Dec 17, 2012
35d9f64
Hunks retain their delta now.
boidanny Dec 17, 2012
9991f92
Block style fix.
boidanny Dec 17, 2012
e9ac8ed
Status -> type.
boidanny Dec 17, 2012
f778aa9
NSUInteger -> GTDiffFileFlag
boidanny Dec 17, 2012
34aa843
Confirmed. It's megabytes not megabits.
boidanny Dec 18, 2012
e26d732
Lolwut --
boidanny Dec 18, 2012
7ff2294
Pursuade Xcode to remove an invisible space.
boidanny Dec 18, 2012
ee39f62
Dot syntax ++
boidanny Dec 18, 2012
9f691b2
Copy our setupDiffFromCommitSHAs block.
boidanny Dec 18, 2012
346592a
lolindentation.
boidanny Dec 18, 2012
c94eab9
isBinary -> binary
boidanny Dec 18, 2012
52b3c98
Redeclare first/second commit vars in each describe.
boidanny Dec 18, 2012
13bcd6f
Cast file.flags.
boidanny Dec 18, 2012
d360980
Always use a temp directory for fixtures.
boidanny Dec 18, 2012
d853045
Add findSimilarWithOptions
boidanny Dec 18, 2012
65729cc
Document the find options constants.
boidanny Dec 18, 2012
1dc6e87
Bump libgit2 to track development.
boidanny Dec 18, 2012
f3e3ee7
Set the version of the findOptions struct.
boidanny Dec 18, 2012
599b88d
Update to new diff function signatures.
boidanny Dec 18, 2012
2a8ebde
Update diff spec with the new method sigs.
boidanny Dec 18, 2012
d2988e7
Merge branch 'master' into diff
boidanny Dec 18, 2012
8b440f5
Update clone bindings to match the new API.
boidanny Dec 18, 2012
ff80bfa
Imma assume this was meant to check withCheckout.
boidanny Dec 18, 2012
cea4994
Wibble.
boidanny Dec 18, 2012
aeb2776
Fix git clone unit tests.
boidanny Dec 18, 2012
4ce57b0
Update fixtures zip to include a rename.
boidanny Dec 18, 2012
011ce40
Rename test ++
boidanny Dec 18, 2012
c2ff71d
Neatly initialise our options structs.
boidanny Dec 18, 2012
478e177
Test that we are building the options struct properly.
boidanny Dec 18, 2012
ef154c3
Move setupDiff block init into the beforeEach.
boidanny Dec 18, 2012
2bd17ee
Remove an old header.
boidanny Dec 18, 2012
068560b
Docs typo --;
boidanny Dec 18, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 additions & 0 deletions Classes/GTDiff.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
//
// GTDiff.h
// ObjectiveGitFramework
//
// Created by Danny Greg on 29/11/2012.
// Copyright (c) 2012 GitHub, Inc. All rights reserved.
//

#import "git2.h"

#import "GTDiffDelta.h"

@class GTDiffDelta;
@class GTRepository;
@class GTTree;

// An `NSNumber` wrapped `GTDiffOptionsFlags` representing any flags you wish to
// pass into the initialisation.
extern NSString *const GTDiffOptionsFlagsKey;

// An `NSNumber` wrapped `NSUInteger` dictating the number of unchanged lines
// that define the boundary of a hunk (and to display around it).
//
// Defaults to 3.
extern NSString *const GTDiffOptionsContextLinesKey;

// An `NSNumber` wrapped `NSUInteger` dictating the maximum number of unchanged
// lines between hunk boundaries before the hunks will be merged.
//
// Defaults to 0.
extern NSString *const GTDiffOptionsInterHunkLinesKey;

// An `NSString` to prefix old file names with.
//
// Defaults to "a".
extern NSString *const GTDiffOptionsOldPrefixKey;

// An `NSString` to prefix new file names with.
//
// Defaults to "b".
extern NSString *const GTDiffOptionsNewPrefixKey;

// An `NSNumber` wrapped `NSUInteger` determining the maximum size (in bytes)
// of a file to diff. Above this size the file will be treated as binary.
//
// Defaults to 512MB.
extern NSString *const GTDiffOptionsMaxSizeKey;

// Enum for use as documented in the options dictionary with the
// `GTDiffOptionsFlagsKey` key.
//
// See diff.h for documentation of each individual flag.
typedef enum : git_diff_option_t {
GTDiffOptionsFlagsNormal = GIT_DIFF_NORMAL,
GTDiffOptionsFlagsReverse = GIT_DIFF_REVERSE,
GTDiffOptionsFlagsForceText = GIT_DIFF_FORCE_TEXT,
GTDiffOptionsFlagsIgnoreWhitespace = GIT_DIFF_IGNORE_WHITESPACE,
GTDiffOptionsFlagsIgnoreWhitespaceChange = GIT_DIFF_IGNORE_WHITESPACE_CHANGE,
GTDiffOptionsFlagsIgnoreWhitespaceEOL = GIT_DIFF_IGNORE_WHITESPACE_EOL,
GTDiffOptionsFlagsIgnoreSubmodules = GIT_DIFF_IGNORE_SUBMODULES,
GTDiffOptionsFlagsPatience = GIT_DIFF_PATIENCE,
GTDiffOptionsFlagsIncludeIgnored = GIT_DIFF_INCLUDE_IGNORED,
GTDiffOptionsFlagsIncludeUntracked = GIT_DIFF_INCLUDE_UNTRACKED,
GTDiffOptionsFlagsIncludeUnmodified = GIT_DIFF_INCLUDE_UNMODIFIED,
GTDiffOptionsFlagsRecurseUntrackedDirs = GIT_DIFF_RECURSE_UNTRACKED_DIRS,
GTDiffOptionsFlagsDisablePathspecMatch = GIT_DIFF_DISABLE_PATHSPEC_MATCH,
GTDiffOptionsFlagsDeltasAreICase = GIT_DIFF_DELTAS_ARE_ICASE,
GTDiffOptionsFlagsIncludeUntrackedContent = GIT_DIFF_INCLUDE_UNTRACKED_CONTENT,
GTDiffOptionsFlagsSkipBinaryCheck = GIT_DIFF_SKIP_BINARY_CHECK,
GTDiffOptionsFlagsIncludeTypeChange = GIT_DIFF_INCLUDE_TYPECHANGE,
GTDiffOptionsFlagsIncludeTypeChangeTrees = GIT_DIFF_INCLUDE_TYPECHANGE_TREES,
GTDiffOptionsFlagsIgnoreFileMode = GIT_DIFF_IGNORE_FILEMODE,
} GTDiffOptionsFlags;

// An `NSNumber` wrapped `GTDiffOptionsFlags` bitmask containing any of the
// flags documented below.
//
// Defualts to `GTDiffFindOptionsFlagsFindRenames`.
extern NSString *const GTDiffFindOptionsFlagsKey;

// An `NSNumber` wrapped `NSUInteger` dictating the similarity between files
// to be considered a rename.
//
// This is a value as per the git similarity index and should be between 1 and
// 100 (0 and above 100 use the default).
//
// Defaults to 50.
extern NSString *const GTDiffFindOptionsRenameThresholdKey;

// An `NSNumber` wrapped `NSUInteger` dictating how similar a modified file can
// be to be eligable as a rename.
//
// This is a value as per the git similarity index and should be between 1 and
// 100 (0 and above 100 use the default).
//
// Defaults to 50.
extern NSString *const GTDiffFindOptionsRenameFromRewriteThresholdKey;

// An `NSNumber` wrapped `NSUInteger` dictating how similar a modified file can
// be to be considered a copy.
//
// This is a value as per the git similarity index and should be between 1 and
// 100 (0 and above 100 use the default).
//
// Defaults to 50.
extern NSString *const GTDiffFindOptionsCopyThresholdKey;

// An `NSNumber` wrapped `NSUInteger` dictating how similar a modified file can
// be to be to be broken into a separate deletion and addition pair.
//
// This is a value as per the git similarity index and should be between 1 and
// 100 (0 and above 100 use the default).
//
// Defaults to 60.
extern NSString *const GTDiffFindOptionsBreakRewriteThresholdKey;

// An `NSNumber` wrapped `NSUInteger` dictating the maximum amount of similarity
// sources to examine.
//
// This is the equivalent of the `diff.renameLimit` config value.
//
// Defaults to 200.
extern NSString *const GTDiffFindOptionsTargetLimitKey;

// Enum for options passed into `-findSimilarWithOptions:`.
//
// For individual case documentation see `diff.h`.
typedef enum : git_diff_find_t {
GTDiffFindOptionsFlagsFindRenames = GIT_DIFF_FIND_RENAMES,
GTDiffFindOptionsFlagsFindRenamesFromRewrites = GIT_DIFF_FIND_RENAMES_FROM_REWRITES,
GTDiffFindOptionsFlagsFindCopies = GIT_DIFF_FIND_COPIES,
GTDiffFindOptionsFlagsFindCopiesFromUnmodified = GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED,
GTDiffFindOptionsFlagsFindAndBreakRewrites = GIT_DIFF_FIND_AND_BREAK_REWRITES,
} GTDiffFindOptionsFlags;

// A class representing a single "diff".
//
// Analagous to `git_diff_list` in libgit2, this object represents a list of
// changes or "deltas", which are represented by `GTDiffDelta` objects.
@interface GTDiff : NSObject

// The libgit2 diff list object.
@property (nonatomic, readonly) git_diff_list *git_diff_list;

// The number of deltas represented by the diff object.
@property (nonatomic, readonly) NSUInteger deltaCount;

// Create a diff between 2 `GTTree`s.
//
// The 2 trees must be from the same repository, or an exception will be thrown.
//
// oldTree - The "left" side of the diff.
// newTree - The "right" side of the diff.
// options - A dictionary containing any of the above options key constants, or
// nil to use the defaults.
//
// Returns a newly created `GTDiff` object or nil on error.
+ (GTDiff *)diffOldTree:(GTTree *)oldTree withNewTree:(GTTree *)newTree options:(NSDictionary *)options;

// Create a diff between a repository's current index.
//
// This is equivalent to `git diff --cached <treeish>` or if you pass the HEAD
// tree, then `git diff --cached`.
//
// The tree you pass will be used for the "left" side of the diff, and the
// index will be used for the "right" side of the diff.
//
// tree - The tree to be diffed. The index will be taken from this tree's
// repository. The left side of the diff.
// options - A dictionary containing any of the above options key constants, or
// nil to use the defaults.
//
// Returns a newly created `GTDiff` object or nil on error.
+ (GTDiff *)diffIndexFromTree:(GTTree *)tree options:(NSDictionary *)options;

// Create a diff between the index and working directory in a given repository.
//
// This matches the `git diff` command.
//
// repository - The repository to be used for the diff.
// options - A dictionary containing any of the above options key constants,
// or nil to use the defaults.
//
// Returns a newly created `GTDiff` object or nil on error.
+ (GTDiff *)diffIndexToWorkingDirectoryInRepository:(GTRepository *)repository options:(NSDictionary *)options;

// Create a diff between a repository's working directory and a tree.
//
// tree - The tree to be diffed. The tree will be the left side of the diff.
// options - A dictionary containing any of the above options key constants, or
// nil to use the defaults.
//
// Returns a newly created `GTDiff` object or nil on error.
+ (GTDiff *)diffWorkingDirectoryFromTree:(GTTree *)tree options:(NSDictionary *)options;

// Designated initialiser.
- (instancetype)initWithGitDiffList:(git_diff_list *)diffList;

// The number of deltas of the given type that are contained in the diff.
- (NSUInteger)numberOfDeltasWithType:(GTDiffDeltaType)deltaType;

// Enumerate the deltas in a diff.
//
// It is worth noting that the `git_diff_patch` objects backing each delta
// contain the entire contents in memory. It is therefore recommended you
// do not store the `delta` object given here, but instead perform any work
// necessary within the provided block.
//
// Also note that this method blocks during the enumeration.
//
// block - A block to be executed for each delta. Setting `stop` to `YES`
// immediately stops the enumeration.
- (void)enumerateDeltasUsingBlock:(void (^)(GTDiffDelta *delta, BOOL *stop))block;

// Modify the diff list to combine similar changes using the given options.
//
// options - A dictionary containing any of the above find options key constants
// or nil to use the defaults.
- (void)findSimilarWithOptions:(NSDictionary *)options;

@end
177 changes: 177 additions & 0 deletions Classes/GTDiff.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
//
// GTDiff.m
// ObjectiveGitFramework
//
// Created by Danny Greg on 29/11/2012.
// Copyright (c) 2012 GitHub, Inc. All rights reserved.
//

#import "GTDiff.h"

#import "GTDiffDelta.h"
#import "GTRepository.h"
#import "GTTree.h"

NSString *const GTDiffOptionsFlagsKey = @"GTDiffOptionsFlagsKey";
NSString *const GTDiffOptionsContextLinesKey = @"GTDiffOptionsContextLinesKey";
NSString *const GTDiffOptionsInterHunkLinesKey = @"GTDiffOptionsInterHunkLinesKey";
NSString *const GTDiffOptionsOldPrefixKey = @"GTDiffOptionsOldPrefixKey";
NSString *const GTDiffOptionsNewPrefixKey = @"GTDiffOptionsNewPrefixKey";
NSString *const GTDiffOptionsMaxSizeKey = @"GTDiffOptionsMaxSizeKey";

NSString *const GTDiffFindOptionsFlagsKey = @"GTDiffFindOptionsFlagsKey";
NSString *const GTDiffFindOptionsRenameThresholdKey = @"GTDiffFindOptionsRenameThresholdKey";
NSString *const GTDiffFindOptionsRenameFromRewriteThresholdKey = @"GTDiffFindOptionsRenameFromRewriteThresholdKey";
NSString *const GTDiffFindOptionsCopyThresholdKey = @"GTDiffFindOptionsCopyThresholdKey";
NSString *const GTDiffFindOptionsBreakRewriteThresholdKey = @"GTDiffFindOptionsBreakRewriteThresholdKey";
NSString *const GTDiffFindOptionsTargetLimitKey = @"GTDiffFindOptionsTargetLimitKey";

@implementation GTDiff

+ (BOOL)optionsStructFromDictionary:(NSDictionary *)dictionary optionsStruct:(git_diff_options *)newOptions {
if (dictionary == nil || dictionary.count < 1) return NO;

NSNumber *flagsNumber = dictionary[GTDiffOptionsFlagsKey];
if (flagsNumber != nil) newOptions->flags = (uint32_t)flagsNumber.unsignedIntegerValue;

NSNumber *contextLinesNumber = dictionary[GTDiffOptionsContextLinesKey];
if (contextLinesNumber != nil) newOptions->context_lines = (uint16_t)contextLinesNumber.unsignedIntegerValue;

NSNumber *interHunkLinesNumber = dictionary[GTDiffOptionsInterHunkLinesKey];
if (interHunkLinesNumber != nil) newOptions->interhunk_lines = (uint16_t)interHunkLinesNumber.unsignedIntegerValue;

// We cast to char* below to work around a current bug in libgit2, which is
// fixed in https://github.com/libgit2/libgit2/pull/1118

NSString *oldPrefix = dictionary[GTDiffOptionsOldPrefixKey];
if (oldPrefix != nil) newOptions->old_prefix = (char *)oldPrefix.UTF8String;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have to cast this, either we're wrong, or libgit2 is. One of the two needs to be fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think libgit2 is wrong. It should be const char * and I see that it is not currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yarp.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I open an issue on libgit2/libgit2 @arrbee

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I fixed it in libgit2/libgit2#1118 but that's not really an appropriate place for that fix, plus it will probably be a week before that PR is ready to merge.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dannygreg Can we add a comment to this code referencing that PR, just so we know that the cast is a temporary workaround?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can indeed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment added in 838b971.


NSString *newPrefix = dictionary[GTDiffOptionsNewPrefixKey];
if (newPrefix != nil) newOptions->new_prefix = (char *)newPrefix.UTF8String;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


NSNumber *maxSizeNumber = dictionary[GTDiffOptionsMaxSizeKey];
if (maxSizeNumber != nil) newOptions->max_size = (uint16_t)maxSizeNumber.unsignedIntegerValue;

return YES;
}

+ (GTDiff *)diffOldTree:(GTTree *)oldTree withNewTree:(GTTree *)newTree options:(NSDictionary *)options {
NSParameterAssert([oldTree.repository isEqualTo:newTree.repository]);

git_diff_options optionsStruct = GIT_DIFF_OPTIONS_INIT;
BOOL optionsStructCreated = [self optionsStructFromDictionary:options optionsStruct:&optionsStruct];
git_diff_list *diffList;
int returnValue = git_diff_tree_to_tree(&diffList, oldTree.repository.git_repository, oldTree.git_tree, newTree.git_tree, (optionsStructCreated ? &optionsStruct : NULL));
if (returnValue != GIT_OK) return nil;

GTDiff *newDiff = [[GTDiff alloc] initWithGitDiffList:diffList];
return newDiff;
}

+ (GTDiff *)diffIndexFromTree:(GTTree *)tree options:(NSDictionary *)options {
NSParameterAssert(tree != nil);

git_diff_options optionsStruct = GIT_DIFF_OPTIONS_INIT;
BOOL optionsStructCreated = [self optionsStructFromDictionary:options optionsStruct:&optionsStruct];
git_diff_list *diffList;
int returnValue = git_diff_tree_to_index(&diffList, tree.repository.git_repository, tree.git_tree, NULL, (optionsStructCreated ? &optionsStruct : NULL));
if (returnValue != GIT_OK) return nil;

GTDiff *newDiff = [[GTDiff alloc] initWithGitDiffList:diffList];
return newDiff;
}

+ (GTDiff *)diffIndexToWorkingDirectoryInRepository:(GTRepository *)repository options:(NSDictionary *)options {
NSParameterAssert(repository != nil);

git_diff_options optionsStruct = GIT_DIFF_OPTIONS_INIT;
BOOL optionsStructCreated = [self optionsStructFromDictionary:options optionsStruct:&optionsStruct];
git_diff_list *diffList;
int returnValue = git_diff_index_to_workdir(&diffList, repository.git_repository, NULL, (optionsStructCreated ? &optionsStruct : NULL));
if (returnValue != GIT_OK) return nil;

GTDiff *newDiff = [[GTDiff alloc] initWithGitDiffList:diffList];
return newDiff;
}

+ (GTDiff *)diffWorkingDirectoryFromTree:(GTTree *)tree options:(NSDictionary *)options {
NSParameterAssert(tree != nil);

git_diff_options optionsStruct = GIT_DIFF_OPTIONS_INIT;
BOOL optionsStructCreated = [self optionsStructFromDictionary:options optionsStruct:&optionsStruct];
git_diff_list *diffList;
int returnValue = git_diff_tree_to_workdir(&diffList, tree.repository.git_repository, tree.git_tree, (optionsStructCreated ? &optionsStruct : NULL));
if (returnValue != GIT_OK) return nil;

GTDiff *newDiff = [[GTDiff alloc] initWithGitDiffList:diffList];
return newDiff;
}

- (instancetype)initWithGitDiffList:(git_diff_list *)diffList {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should assert that the argument isn't NULL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This was done)

NSParameterAssert(diffList != NULL);

self = [super init];
if (self == nil) return nil;

_git_diff_list = diffList;

return self;
}

- (void)dealloc {
git_diff_list_free(self.git_diff_list);
}

- (void)enumerateDeltasUsingBlock:(void (^)(GTDiffDelta *delta, BOOL *stop))block {
NSParameterAssert(block != nil);

for (NSUInteger idx = 0; idx < self.deltaCount; idx ++) {
git_diff_patch *patch;
int result = git_diff_get_patch(&patch, NULL, self.git_diff_list, idx);
if (result != GIT_OK) continue;
GTDiffDelta *delta = [[GTDiffDelta alloc] initWithGitPatch:patch];
BOOL stop = NO;
block(delta, &stop);
if (stop) return;
}
}

- (NSUInteger)deltaCount {
return git_diff_num_deltas(self.git_diff_list);
}

- (NSUInteger)numberOfDeltasWithType:(GTDiffDeltaType)deltaType {
return git_diff_num_deltas_of_type(self.git_diff_list, (git_delta_t)deltaType);
}

- (BOOL)findOptionsStructWithDictionary:(NSDictionary *)dictionary optionsStruct:(git_diff_find_options *)newOptions {
if (dictionary == nil || dictionary.count < 1) return NO;

NSNumber *flagsNumber = dictionary[GTDiffFindOptionsFlagsKey];
if (flagsNumber != nil) newOptions->flags = (uint32_t)flagsNumber.unsignedIntegerValue;

NSNumber *renameThresholdNumber = dictionary[GTDiffFindOptionsRenameThresholdKey];
if (renameThresholdNumber != nil) newOptions->rename_threshold = renameThresholdNumber.unsignedIntValue;

NSNumber *renameFromRewriteThresholdNumber = dictionary[GTDiffFindOptionsRenameFromRewriteThresholdKey];
if (renameFromRewriteThresholdNumber != nil) newOptions->rename_from_rewrite_threshold = renameFromRewriteThresholdNumber.unsignedIntValue;

NSNumber *copyThresholdNumber = dictionary[GTDiffFindOptionsCopyThresholdKey];
if (copyThresholdNumber != nil) newOptions->copy_threshold = copyThresholdNumber.unsignedIntValue;

NSNumber *breakRewriteThresholdNumber = dictionary[GTDiffFindOptionsBreakRewriteThresholdKey];
if (renameThresholdNumber != nil) newOptions->break_rewrite_threshold = breakRewriteThresholdNumber.unsignedIntValue;

NSNumber *targetLimitNumber = dictionary[GTDiffFindOptionsTargetLimitKey];
if (targetLimitNumber != nil) newOptions->target_limit = targetLimitNumber.unsignedIntValue;

return YES;
}

- (void)findSimilarWithOptions:(NSDictionary *)options {
git_diff_find_options findOptions = GIT_DIFF_FIND_OPTIONS_INIT;
BOOL findOptionsCreated = [self findOptionsStructWithDictionary:options optionsStruct:&findOptions];
git_diff_find_similar(self.git_diff_list, (findOptionsCreated ? &findOptions : NULL));
}

@end
Loading