Skip to content

Work on gitx #302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions Classes/Controllers/ApplicationController.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "ApplicationController.h"
#import "PBRepositoryDocumentController.h"
#import "PBGitRevisionCell.h"
#import "PBGitWindowController.h"
#import "PBServicesController.h"
Expand Down Expand Up @@ -67,6 +68,20 @@ - (void)registerServices
}
}

- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
NSURL *repository = [NSURL fileURLWithPath:filename];
NSError *error = nil;
NSDocument *doc = [[PBRepositoryDocumentController sharedDocumentController] openDocumentWithContentsOfURL:repository
display:YES
error:&error];
if (!doc) {
NSLog(@"Error opening repository \"%@\": %@", repository.path, error);
return NO;
}

return YES;
}

- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
{
if(!started || [[[NSDocumentController sharedDocumentController] documents] count])
Expand Down
1 change: 0 additions & 1 deletion Classes/Controllers/PBRepositoryDocumentController.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#import "PBGitRevList.h"
#import "PBEasyPipe.h"
#import "PBGitBinary.h"
#import "GitRepoFinder.h"

#import <ObjectiveGit/GTRepository.h>

Expand Down
29 changes: 27 additions & 2 deletions Classes/Util/NSApplication+GitXScripting.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#import "PBDiffWindowController.h"
#import "PBGitRepository.h"
#import "PBCloneRepositoryPanel.h"

#import <ObjectiveGit/GTRepository.h>
#import "PBGitBinary.h"
#import "PBEasyPipe.h"


@implementation NSApplication (GitXScripting)
Expand All @@ -27,6 +27,31 @@ - (void)showDiffScriptCommand:(NSScriptCommand *)command
}
}

- (void)performDiffScriptCommand:(NSScriptCommand *)command
{
NSURL *repositoryURL = command.directParameter;
NSArray *diffOptions = command.arguments[@"diffOptions"];

diffOptions = [[NSArray arrayWithObjects:@"diff", @"--no-ext-diff", nil] arrayByAddingObjectsFromArray:diffOptions];

int retValue = 1;
NSString *diffOutput = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:diffOptions inDir:[repositoryURL path] retValue:&retValue];
if (retValue) {
// if there is an error diffOutput should have the error output from git
if (diffOutput)
NSLog(@"%s\n", [diffOutput UTF8String]);
else
NSLog(@"Invalid diff command [%d]\n", retValue);
return;
}

if (diffOutput) {
PBDiffWindowController *diffController = [[PBDiffWindowController alloc] initWithDiff:diffOutput];
[diffController showWindow:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
}

- (void)initRepositoryScriptCommand:(NSScriptCommand *)command
{
NSError *error = nil;
Expand Down
10 changes: 8 additions & 2 deletions Classes/Util/PBEasyPipe.m
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,14 @@ + (NSString*) outputForCommand:(NSString *) cmd
[inHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[inHandle closeFile];
}

[task launch];

@try {
[task launch];
}
@catch (NSException *exception) {
if (ret) *ret = -1;
return nil;
}

NSData* data = [handle readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Expand Down
78 changes: 30 additions & 48 deletions Classes/git/PBGitRepository.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
#import "GitXScriptingConstants.h"
#import "PBHistorySearchController.h"
#import "PBGitRepositoryWatcher.h"
#import "GitRepoFinder.h"
#import "PBRepositoryFinder.h"
#import "PBGitSubmodule.h"
#import "PBGitHistoryList.h"


Expand Down Expand Up @@ -148,21 +149,17 @@ - (void)makeWindowControllers
// if the repository is already open then this is also a good place to catch the event as the window is about to be brought forward
- (void)showWindows
{
NSAppleEventDescriptor *currentAppleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
NSScriptCommand *command = [NSScriptCommand currentCommand];

if (currentAppleEvent) {
NSAppleEventDescriptor *eventRecord = [currentAppleEvent paramDescriptorForKeyword:keyAEPropData];
if (command) {
NSURL *repoURL = [command directParameter];

// on app launch there may be many repositories opening, so double check that this is the right repo
NSString *path = [[eventRecord paramDescriptorForKeyword:typeFileURL] stringValue];
if (path) {
NSURL *workingDirectory = [NSURL URLWithString:path];
if ([[GitRepoFinder gitDirForURL:workingDirectory] isEqual:[self fileURL]]) {
NSAppleEventDescriptor *argumentsList = [eventRecord paramDescriptorForKeyword:kGitXAEKeyArgumentsList];
[self handleGitXScriptingArguments:argumentsList inWorkingDirectory:workingDirectory];

// showWindows may be called more than once during app launch so remove the CLI data after we handle the event
[currentAppleEvent removeDescriptorWithKeyword:keyAEPropData];
if (repoURL) {
repoURL = [PBRepositoryFinder gitDirForURL:repoURL];
if ([repoURL isEqual:self.gitURL]) {
NSArray *arguments = command.arguments[@"openOptions"];
[self handleGitXScriptingArguments:arguments];
}
}
}
Expand Down Expand Up @@ -215,6 +212,15 @@ - (NSURL *)gitURL {
return self.gtRepo.gitDirectoryURL;
}

- (NSURL *)workingDirectoryURL {
return self.gtRepo.fileURL;
}

- (NSString *)workingDirectory
{
return self.workingDirectoryURL.path;
}

- (void)forceUpdateRevisions
{
[revisionList forceUpdate];
Expand Down Expand Up @@ -566,20 +572,6 @@ - (void) readCurrentBranch
self.currentBranch = [self addBranch: [self headRef]];
}

- (NSString *) workingDirectory
{
const char* workdir = git_repository_workdir(self.gtRepo.git_repository);
if (workdir)
{
NSString* result = [[NSString stringWithUTF8String:workdir] stringByStandardizingPath];
return result;
}
else
{
return self.fileURL.path;
}
}

#pragma mark Remotes

- (NSArray *) remotes
Expand Down Expand Up @@ -955,7 +947,7 @@ - (BOOL) deleteRef:(PBGitRef *)ref

#pragma mark GitX Scripting

- (void)handleRevListArguments:(NSArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
- (void)handleRevListArguments:(NSArray *)arguments
{
if (![arguments count])
return;
Expand All @@ -967,45 +959,35 @@ - (void)handleRevListArguments:(NSArray *)arguments inWorkingDirectory:(NSURL *)
PBGitRef *refArgument = [self refForName:[arguments lastObject]];
if (refArgument) {
revListSpecifier = [[PBGitRevSpecifier alloc] initWithRef:refArgument];
revListSpecifier.workingDirectory = workingDirectory;
revListSpecifier.workingDirectory = self.workingDirectoryURL;
}
}

if (!revListSpecifier) {
revListSpecifier = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
revListSpecifier.workingDirectory = workingDirectory;
revListSpecifier.workingDirectory = self.workingDirectoryURL;
}

self.currentBranch = [self addBranch:revListSpecifier];
[PBGitDefaults setShowStageView:NO];
[self.windowController showHistoryView:self];
}

- (void)handleBranchFilterEventForFilter:(PBGitXBranchFilterType)filter additionalArguments:(NSMutableArray *)arguments inWorkingDirectory:(NSURL *)workingDirectory
- (void)handleBranchFilterEventForFilter:(PBGitXBranchFilterType)filter additionalArguments:(NSArray *)arguments
{
self.currentBranchFilter = filter;
[PBGitDefaults setShowStageView:NO];
[self.windowController showHistoryView:self];

// treat any additional arguments as a rev-list specifier
if ([arguments count] > 1) {
[arguments removeObjectAtIndex:0];
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
arguments = [arguments subarrayWithRange:NSMakeRange(1, arguments.count)];
[self handleRevListArguments:arguments];
}
}

- (void)handleGitXScriptingArguments:(NSAppleEventDescriptor *)argumentsList inWorkingDirectory:(NSURL *)workingDirectory
- (void)handleGitXScriptingArguments:(NSArray *)arguments
{
NSMutableArray *arguments = [NSMutableArray array];
uint argumentsIndex = 1; // AppleEvent list descriptor's are one based
while(1) {
NSAppleEventDescriptor *arg = [argumentsList descriptorAtIndex:argumentsIndex++];
if (arg)
[arguments addObject:[arg stringValue]];
else
break;
}

if (![arguments count])
return;

Expand All @@ -1018,22 +1000,22 @@ - (void)handleGitXScriptingArguments:(NSAppleEventDescriptor *)argumentsList inW
}

if ([firstArgument isEqualToString:@"--all"]) {
[self handleBranchFilterEventForFilter:kGitXAllBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
[self handleBranchFilterEventForFilter:kGitXAllBranchesFilter additionalArguments:arguments];
return;
}

if ([firstArgument isEqualToString:@"--local"]) {
[self handleBranchFilterEventForFilter:kGitXLocalRemoteBranchesFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
[self handleBranchFilterEventForFilter:kGitXLocalRemoteBranchesFilter additionalArguments:arguments];
return;
}

if ([firstArgument isEqualToString:@"--branch"]) {
[self handleBranchFilterEventForFilter:kGitXSelectedBranchFilter additionalArguments:arguments inWorkingDirectory:workingDirectory];
[self handleBranchFilterEventForFilter:kGitXSelectedBranchFilter additionalArguments:arguments];
return;
}

// if the argument is not a known command then treat it as a rev-list specifier
[self handleRevListArguments:arguments inWorkingDirectory:workingDirectory];
[self handleRevListArguments:arguments];
}

// for the scripting bridge
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// GitRepoFinder.h
// PBRepositoryFinder.h
// GitX
//
// Created by Rowan James on 13/11/2012.
Expand All @@ -8,7 +8,7 @@

#import <Foundation/Foundation.h>

@interface GitRepoFinder : NSObject
@interface PBRepositoryFinder : NSObject

+ (NSURL*)workDirForURL:(NSURL*)fileURL;
+ (NSURL*)gitDirForURL:(NSURL*)fileURL;
Expand Down
83 changes: 83 additions & 0 deletions Classes/git/PBRepositoryFinder.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// PBRepositoryFinder.m
// GitX
//
// Created by Rowan James on 13/11/2012.
//
//

#import "PBRepositoryFinder.h"

@implementation PBRepositoryFinder

+ (NSURL *)workDirForURL:(NSURL *)fileURL;
{
if (!fileURL.isFileURL) {
return nil;
}

git_repository *repo = NULL;
git_repository_open_ext(&repo, fileURL.path.UTF8String, GIT_REPOSITORY_OPEN_CROSS_FS, NULL);
if (!repo) {
return NULL;
}

const char *workdir = git_repository_workdir(repo);
NSURL *result = nil;
if (workdir) {
result = [NSURL fileURLWithPath:[NSString stringWithUTF8String:workdir]];
}

git_repository_free(repo); repo = nil;
return result;
}

+ (NSURL *)gitDirForURL:(NSURL *)fileURL
{
if (!fileURL.isFileURL)
{
return nil;
}
git_buf path_buffer = {NULL, 0, 0};
int gitResult = git_repository_discover(&path_buffer,
[fileURL.path UTF8String],
GIT_REPOSITORY_OPEN_CROSS_FS,
nil);

NSData *repoPathBuffer = nil;
if (path_buffer.ptr) {
repoPathBuffer = [NSData dataWithBytes:path_buffer.ptr length:path_buffer.asize];
git_buf_free(&path_buffer);
}

if (gitResult == GIT_OK && repoPathBuffer.length)
{
NSString* repoPath = [NSString stringWithUTF8String:repoPathBuffer.bytes];
BOOL isDirectory;
if ([[NSFileManager defaultManager] fileExistsAtPath:repoPath
isDirectory:&isDirectory] && isDirectory)
{
NSURL* result = [NSURL fileURLWithPath:repoPath
isDirectory:isDirectory];
return result;
}
}
return nil;
}

+ (NSURL *)fileURLForURL:(NSURL *)inputURL
{
NSURL* gitDir = [self gitDirForURL:inputURL];
if (!gitDir) {
return nil; // not a Git directory at all
}

NSURL *workDir = [self workDirForURL:inputURL];
if (workDir) {
return workDir; // root of this working copy or deepest submodule
}

return gitDir; // bare repo
}

@end
Loading