Skip to content

Commit

Permalink
Revert "Faster multiple file staging (#629)"
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasderraugh committed Jan 22, 2020
1 parent 58fb0f9 commit 683f6de
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 211 deletions.
14 changes: 2 additions & 12 deletions GitUpKit/Core/GCDiff-Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,6 @@ - (void)testUnifiedDiff {
XCTAssertTrue([self.repository addFileToIndex:@"renamed1.txt" error:NULL]);
[self updateFileAtPath:@"type-changed.txt" withString:@""];
XCTAssertTrue([self.repository addFileToIndex:@"type-changed.txt" error:NULL]);

NSArray* files = @[ @".gitignore", @"modified.txt", @"deleted.txt", @"renamed1.txt", @"type-changed.txt" ];

// Test adding and removing multiple files
XCTAssertTrue([self.repository removeFilesFromIndex:files error:NULL]);
XCTAssertEqual([self.repository checkIndexStatus:NULL].deltas.count, 0);

XCTAssertTrue([self.repository addFilesToIndex:files error:NULL]);
XCTAssertEqual([self.repository checkIndexStatus:NULL].deltas.count, 5);

XCTAssertNotNil([self.repository createCommitFromHEADWithMessage:@"Update" error:NULL]);

// Touch files
Expand All @@ -189,8 +179,8 @@ - (void)testUnifiedDiff {

// Stage some files
XCTAssertTrue([self.repository addFileToIndex:@"modified.txt" error:NULL]);
files = @[ @"deleted.txt", @"renamed1.txt" ];
XCTAssertTrue([self.repository removeFilesFromIndex:files error:NULL]);
XCTAssertTrue([self.repository removeFileFromIndex:@"deleted.txt" error:NULL]);
XCTAssertTrue([self.repository removeFileFromIndex:@"renamed1.txt" error:NULL]);
XCTAssertTrue([self.repository addFileToIndex:@"renamed2.txt" error:NULL]);
XCTAssertTrue([self.repository addFileToIndex:@"added.txt" error:NULL]);

Expand Down
1 change: 0 additions & 1 deletion GitUpKit/Core/GCIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ typedef BOOL (^GCIndexLineFilter)(GCLineDiffChange change, NSUInteger oldLineNum
- (BOOL)resetLinesInFile:(NSString*)path index:(GCIndex*)index toCommit:(GCCommit*)commit error:(NSError**)error usingFilter:(GCIndexLineFilter)filter;

- (BOOL)checkoutFileToWorkingDirectory:(NSString*)path fromIndex:(GCIndex*)index error:(NSError**)error;
- (BOOL)checkoutFilesToWorkingDirectory:(NSArray<NSString*>*)paths fromIndex:(GCIndex*)index error:(NSError**)error;
- (BOOL)checkoutLinesInFileToWorkingDirectory:(NSString*)path fromIndex:(GCIndex*)index error:(NSError**)error usingFilter:(GCIndexLineFilter)filter;

- (BOOL)clearConflictForFile:(NSString*)path inIndex:(GCIndex*)index error:(NSError**)error;
Expand Down
18 changes: 3 additions & 15 deletions GitUpKit/Core/GCIndex.m
Original file line number Diff line number Diff line change
Expand Up @@ -485,24 +485,12 @@ - (BOOL)resetLinesInFile:(NSString*)path index:(GCIndex*)index toCommit:(GCCommi
}

- (BOOL)checkoutFileToWorkingDirectory:(NSString*)path fromIndex:(GCIndex*)index error:(NSError**)error {
return [self checkoutFilesToWorkingDirectory:@[ path ]
fromIndex:index
error:error];
}

- (BOOL)checkoutFilesToWorkingDirectory:(NSArray<NSString*>*)paths fromIndex:(GCIndex*)index error:(NSError**)error {
git_checkout_options options = GIT_CHECKOUT_OPTIONS_INIT;
options.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_UPDATE_INDEX | GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH; // There's no reason to update the index
options.paths.count = paths.count;
char** pathStrings = malloc(paths.count * sizeof(char*));
options.paths.strings = pathStrings;
for (NSUInteger i = 0; i < paths.count; i++) {
const char* filePath = GCGitPathFromFileSystemPath(paths[i]);
options.paths.strings[i] = (char*)filePath;
}

options.paths.count = 1;
const char* filePath = GCGitPathFromFileSystemPath(path);
options.paths.strings = (char**)&filePath;
CALL_LIBGIT2_FUNCTION_RETURN(NO, git_checkout_index, self.private, index.private, &options);
free(pathStrings);
return YES;
}

Expand Down
26 changes: 1 addition & 25 deletions GitUpKit/Extensions/GCRepository+Index-Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,9 @@ - (void)testIndex {
XCTAssertTrue([self.repository addFileToIndex:@"test.txt" error:NULL]);
[self assertGitCLTOutputEqualsString:@"A test.txt\n" withRepository:self.repository command:@"status", @"--ignored", @"--porcelain", nil];

// Add multiple files to working directory
NSMutableArray* filePaths = [[NSMutableArray alloc] init];
NSString* expectedGitCLTOutput = [[NSString alloc] init];
for (int i = 0; i < 50; i++) {
NSString* filePath = [NSString stringWithFormat:@"hello_world%02d.txt", i];
[self updateFileAtPath:filePath withString:@"Bonjour le monde!\n"];
[filePaths addObject:filePath];
expectedGitCLTOutput = [expectedGitCLTOutput stringByAppendingFormat:@"A %@\n", filePath];
}
expectedGitCLTOutput = [expectedGitCLTOutput stringByAppendingString:@"A test.txt\n"];

// Add multiple files to index
XCTAssertTrue([self.repository addFilesToIndex:filePaths error:NULL]);
[self assertGitCLTOutputEqualsString:expectedGitCLTOutput withRepository:self.repository command:@"status", @"--ignored", @"--porcelain", nil];

// Add remove multiple files from index
XCTAssertTrue([self.repository removeFilesFromIndex:filePaths error:NULL]);
expectedGitCLTOutput = [expectedGitCLTOutput stringByReplacingOccurrencesOfString:@"A test.txt\n" withString:@""];
expectedGitCLTOutput = [expectedGitCLTOutput stringByReplacingOccurrencesOfString:@"A hello_world" withString:@"?? hello_world"];
expectedGitCLTOutput = [@"A test.txt\n" stringByAppendingString:expectedGitCLTOutput];
[self assertGitCLTOutputEqualsString:expectedGitCLTOutput withRepository:self.repository command:@"status", @"--ignored", @"--porcelain", nil];

// Reset index
XCTAssertTrue([self.repository resetIndexToHEAD:NULL]);
expectedGitCLTOutput = [expectedGitCLTOutput stringByReplacingOccurrencesOfString:@"A test.txt\n" withString:@""];
expectedGitCLTOutput = [expectedGitCLTOutput stringByAppendingString:@"?? test.txt\n"];
[self assertGitCLTOutputEqualsString:expectedGitCLTOutput withRepository:self.repository command:@"status", @"--ignored", @"--porcelain", nil];
[self assertGitCLTOutputEqualsString:@"?? test.txt\n" withRepository:self.repository command:@"status", @"--ignored", @"--porcelain", nil];
}

- (void)testIndex_Lines {
Expand Down
4 changes: 0 additions & 4 deletions GitUpKit/Extensions/GCRepository+Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@
- (BOOL)resetIndexToHEAD:(NSError**)error; // Like git reset --mixed HEAD but does not update reflog

- (BOOL)removeFileFromIndex:(NSString*)path error:(NSError**)error; // git rm --cached {file} - Delete file from index
- (BOOL)removeFilesFromIndex:(NSArray<NSString*>*)paths error:(NSError**)error; // git rm --cached {file} - Delete files from index

- (BOOL)addFileToIndex:(NSString*)path error:(NSError**)error; // git add {file} - Copy file from workdir to index (aka stage file)
- (BOOL)addFilesToIndex:(NSArray<NSString*>*)paths error:(NSError**)error;
- (BOOL)resetFileInIndexToHEAD:(NSString*)path error:(NSError**)error; // git reset --mixed {file} - Copy file from HEAD to index (aka unstage file)
- (BOOL)resetFilesInIndexToHEAD:(NSArray<NSString*>*)paths error:(NSError**)error;
- (BOOL)checkoutFileFromIndex:(NSString*)path error:(NSError**)error; // git checkout {file} - Copy file from index to workdir (aka discard file)
- (BOOL)checkoutFilesFromIndex:(NSArray<NSString*>*)paths error:(NSError**)error;

- (BOOL)addLinesFromFileToIndex:(NSString*)path error:(NSError**)error usingFilter:(GCIndexLineFilter)filter; // git add -p {file} - Copy only some lines of file from workdir to index (aka stage lines)
- (BOOL)resetLinesFromFileInIndexToHEAD:(NSString*)path error:(NSError**)error usingFilter:(GCIndexLineFilter)filter; // git reset -p {file} - Copy only some lines of file from HEAD to index (aka unstage lines)
Expand Down
69 changes: 10 additions & 59 deletions GitUpKit/Extensions/GCRepository+Index.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,61 +39,22 @@ - (BOOL)resetIndexToHEAD:(NSError**)error {
}

- (BOOL)removeFileFromIndex:(NSString*)path error:(NSError**)error {
return [self removeFilesFromIndex:@[ path ] error:error];
}

- (BOOL)removeFilesFromIndex:(NSArray<NSString*>*)paths error:(NSError**)error {
GCIndex* index = [self readRepositoryIndex:error];
if (index == nil) {
return NO;
}

for (NSString* path in paths) {
if (![self removeFile:path fromIndex:index error:error] || (error && *error != nil)) {
[self writeRepositoryIndex:index error:error];
return NO;
}
}

return [self writeRepositoryIndex:index error:error];
return [self removeFile:path fromIndex:index error:error] && [self writeRepositoryIndex:index error:error];
}

- (BOOL)addFileToIndex:(NSString*)path error:(NSError**)error {
return [self addFilesToIndex:@[ path ] error:error];
}

- (BOOL)addFilesToIndex:(NSArray<NSString*>*)paths error:(NSError**)error {
GCIndex* index = [self readRepositoryIndex:error];
if (index == nil) {
return NO;
}

BOOL failed = NO;
BOOL shouldWriteRepository = NO;
for (NSString* path in paths) {
if (![self addFileInWorkingDirectory:path toIndex:index error:error] || (error && *error != nil)) {
failed = YES;
break;
}

shouldWriteRepository = YES;
}

if (failed && shouldWriteRepository) {
if (shouldWriteRepository) {
[self writeRepositoryIndex:index error:NULL];
}
return NO;
}

return [self writeRepositoryIndex:index error:error];
return [self addFileInWorkingDirectory:path toIndex:index error:error] && [self writeRepositoryIndex:index error:error];
}

- (BOOL)resetFileInIndexToHEAD:(NSString*)path error:(NSError**)error {
return [self resetFilesInIndexToHEAD:@[ path ] error:error];
}

- (BOOL)resetFilesInIndexToHEAD:(NSArray<NSString*>*)paths error:(NSError**)error {
GCIndex* index = [self readRepositoryIndex:error];
if (index == nil) {
return NO;
Expand All @@ -102,34 +63,24 @@ - (BOOL)resetFilesInIndexToHEAD:(NSArray<NSString*>*)paths error:(NSError**)erro
if (![self lookupHEADCurrentCommit:&headCommit branch:NULL error:error]) {
return NO;
}

for (NSString* path in paths) {
if (headCommit) {
if (![self resetFile:path inIndex:index toCommit:headCommit error:error]) {
[self writeRepositoryIndex:index error:error];
return NO;
}
} else {
if (![self removeFile:path fromIndex:index error:error]) {
[self writeRepositoryIndex:index error:error];
return NO;
}
if (headCommit) {
if (![self resetFile:path inIndex:index toCommit:headCommit error:error]) {
return NO;
}
} else {
if (![self removeFile:path fromIndex:index error:error]) {
return NO;
}
}

return [self writeRepositoryIndex:index error:error];
}

- (BOOL)checkoutFileFromIndex:(NSString*)path error:(NSError**)error {
return [self checkoutFilesFromIndex:@[ path ] error:error];
}

- (BOOL)checkoutFilesFromIndex:(NSArray<NSString*>*)paths error:(NSError**)error {
GCIndex* index = [self readRepositoryIndex:error];
if (index == nil) {
return NO;
}
return [self checkoutFilesToWorkingDirectory:paths fromIndex:index error:error];
return [self checkoutFileToWorkingDirectory:path fromIndex:index error:error];
}

- (BOOL)addLinesFromFileToIndex:(NSString*)path error:(NSError**)error usingFilter:(GCIndexLineFilter)filter {
Expand Down
3 changes: 0 additions & 3 deletions GitUpKit/Utilities/GIViewController+Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@
- (void)discardSubmoduleAtPath:(NSString*)path resetIndex:(BOOL)resetIndex; // Prompts user

- (void)stageAllChangesForFile:(NSString*)path;
- (void)stageAllChangesForFiles:(NSArray<NSString*>*)paths;
- (void)stageSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLines newLines:(NSIndexSet*)newLines;
- (void)unstageAllChangesForFile:(NSString*)path;
- (void)unstageAllChangesForFiles:(NSArray<NSString*>*)paths;
- (void)unstageSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLines newLines:(NSIndexSet*)newLines;

- (BOOL)discardAllChangesForFile:(NSString*)path resetIndex:(BOOL)resetIndex error:(NSError**)error;
- (BOOL)discardAllChangesForFiles:(NSArray<NSString*>*)paths resetIndex:(BOOL)resetIndex error:(NSError**)error;
- (void)discardAllChangesForFile:(NSString*)path resetIndex:(BOOL)resetIndex; // Prompts user
- (BOOL)discardSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLines newLines:(NSIndexSet*)newLines resetIndex:(BOOL)resetIndex error:(NSError**)error;
- (void)discardSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLines newLines:(NSIndexSet*)newLines resetIndex:(BOOL)resetIndex; // Prompts user
Expand Down
67 changes: 12 additions & 55 deletions GitUpKit/Utilities/GIViewController+Utilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,34 +108,13 @@ - (void)discardSubmoduleAtPath:(NSString*)path resetIndex:(BOOL)resetIndex {
}

- (void)stageAllChangesForFile:(NSString*)path {
return [self stageAllChangesForFiles:@[ path ]];
}

- (void)stageAllChangesForFiles:(NSArray<NSString*>*)paths {
NSError* error;
NSMutableArray* existingFiles = [NSMutableArray array];
NSMutableArray* nonExistingFiles = [NSMutableArray array];
for (NSString* path in paths) {
if ([[NSFileManager defaultManager] fileExistsAtPath:[self.repository absolutePathForFile:path]]) {
[existingFiles addObject:path];
} else {
[nonExistingFiles addObject:path];
}
}

if (existingFiles.count > 0) {
if (![self.repository addFilesToIndex:existingFiles error:&error]) {
[self presentError:error];
}
}

if (nonExistingFiles.count > 0) {
if (![self.repository removeFilesFromIndex:nonExistingFiles error:&error]) {
[self presentError:error];
}
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[self.repository absolutePathForFile:path] followLastSymlink:NO];
if ((fileExists && [self.repository addFileToIndex:path error:&error]) || (!fileExists && [self.repository removeFileFromIndex:path error:&error])) {
[self.repository notifyRepositoryChanged];
} else {
[self presentError:error];
}

[self.repository notifyRepositoryChanged];
}

- (void)stageSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLines newLines:(NSIndexSet*)newLines {
Expand All @@ -158,12 +137,8 @@ - (void)stageSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldLin
}

- (void)unstageAllChangesForFile:(NSString*)path {
[self unstageAllChangesForFiles:@[ path ]];
}

- (void)unstageAllChangesForFiles:(NSArray<NSString*>*)paths {
NSError* error;
if ([self.repository resetFilesInIndexToHEAD:paths error:&error]) {
if ([self.repository resetFileInIndexToHEAD:path error:&error]) {
[self.repository notifyWorkingDirectoryChanged];
} else {
[self presentError:error];
Expand All @@ -190,36 +165,18 @@ - (void)unstageSelectedChangesForFile:(NSString*)path oldLines:(NSIndexSet*)oldL
}

- (BOOL)discardAllChangesForFile:(NSString*)path resetIndex:(BOOL)resetIndex error:(NSError**)error {
return [self discardAllChangesForFiles:@[ path ]
resetIndex:resetIndex
error:error];
}

- (BOOL)discardAllChangesForFiles:(NSArray<NSString*>*)paths resetIndex:(BOOL)resetIndex error:(NSError**)error {
BOOL success = NO;
if (resetIndex) {
GCCommit* commit;
if ([self.repository lookupHEADCurrentCommit:&commit branch:NULL error:error] && [self.repository resetFilesInIndexToHEAD:paths error:error]) {
success = YES;
for (NSString* path in paths) {
if (commit && [self.repository checkTreeForCommit:commit containsFile:path error:NULL]) {
if (![self.repository safeDeleteFileIfExists:path error:error] && [self.repository checkoutFileFromIndex:path error:error]) {
return NO;
}
} else {
if (![self.repository safeDeleteFileIfExists:path error:error]) {
return NO;
}
}
if ([self.repository lookupHEADCurrentCommit:&commit branch:NULL error:error] && [self.repository resetFileInIndexToHEAD:path error:error]) {
if (commit && [self.repository checkTreeForCommit:commit containsFile:path error:NULL]) {
success = [self.repository safeDeleteFileIfExists:path error:error] && [self.repository checkoutFileFromIndex:path error:error];
} else {
success = [self.repository safeDeleteFile:path error:error];
}
}
} else {
for (NSString* path in paths) {
if (![self.repository safeDeleteFileIfExists:path error:error]) {
return NO;
}
}
success = [self.repository checkoutFilesFromIndex:paths error:error];
success = [self.repository safeDeleteFileIfExists:path error:error] && [self.repository checkoutFileFromIndex:path error:error];
}
return success;
}
Expand Down
Loading

0 comments on commit 683f6de

Please sign in to comment.