Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 187 lines (151 sloc) 6.854 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
//
// PBGitCommitController.m
// GitX
//
// Created by Pieter de Bie on 19-09-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "PBGitCommitController.h"
#import "NSFileHandleExt.h"
#import "PBChangedFile.h"
#import "PBWebChangesController.h"
#import "PBGitIndex.h"

@interface PBGitCommitController ()
- (void)refreshFinished:(NSNotification *)notification;
- (void)commitStatusUpdated:(NSNotification *)notification;
- (void)commitFinished:(NSNotification *)notification;
- (void)commitFailed:(NSNotification *)notification;
- (void)amendCommit:(NSNotification *)notification;
- (void)indexChanged:(NSNotification *)notification;
- (void)indexOperationFailed:(NSNotification *)notification;
@end

@implementation PBGitCommitController

@synthesize status, index, busy;

- (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller
{
if (!(self = [super initWithRepository:theRepository superController:controller]))
return nil;

index = [[PBGitIndex alloc] initWithRepository:theRepository workingDirectory:[NSURL fileURLWithPath:[theRepository workingDirectory]]];
[index refresh];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshFinished:) name:PBGitIndexFinishedIndexRefresh object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexChanged:) name:PBGitIndexIndexUpdated object:index];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexOperationFailed:) name:PBGitIndexOperationFailed object:index];

return self;
}

- (void)awakeFromNib
{
[super awakeFromNib];

[commitMessageView setTypingAttributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:12.0] forKey:NSFontAttributeName]];

[unstagedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasUnstagedChanges == 1"]];
[cachedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasStagedChanges == 1"]];

[unstagedFilesController setSortDescriptors:[NSArray arrayWithObjects:
[[NSSortDescriptor alloc] initWithKey:@"status" ascending:false],
[[NSSortDescriptor alloc] initWithKey:@"path" ascending:true], nil]];
[cachedFilesController setSortDescriptors:[NSArray arrayWithObject:
[[NSSortDescriptor alloc] initWithKey:@"path" ascending:true]]];

[cachedFilesController setAutomaticallyRearrangesObjects:NO];
[unstagedFilesController setAutomaticallyRearrangesObjects:NO];
}

- (void) removeView
{
[webController closeView];
[super finalize];
}

- (NSResponder *)firstResponder;
{
return commitMessageView;
}

- (IBAction)signOff:(id)sender
{
if (![repository.config valueForKeyPath:@"user.name"] || ![repository.config valueForKeyPath:@"user.email"])
return [[repository windowController] showMessageSheet:@"User's name not set" infoText:@"Signing off a commit requires setting user.name and user.email in your git config"];
NSString *SOBline = [NSString stringWithFormat:@"Signed-off-by: %@ <%@>",
[repository.config valueForKeyPath:@"user.name"],
[repository.config valueForKeyPath:@"user.email"]];

if([commitMessageView.string rangeOfString:SOBline].location == NSNotFound) {
NSArray *selectedRanges = [commitMessageView selectedRanges];
commitMessageView.string = [NSString stringWithFormat:@"%@\n\n%@",
commitMessageView.string, SOBline];
[commitMessageView setSelectedRanges: selectedRanges];
}
}

- (void) refresh:(id) sender
{
self.busy = YES;
self.status = @"Refreshing index…";
[index refresh];

// Reload refs (in case HEAD changed)
[repository reloadRefs];
}

- (void) updateView
{
[self refresh:nil];
}

- (IBAction) commit:(id) sender
{
if ([[NSFileManager defaultManager] fileExistsAtPath:[repository.fileURL.path stringByAppendingPathComponent:@"MERGE_HEAD"]]) {
[[repository windowController] showMessageSheet:@"Cannot commit merges" infoText:@"GitX cannot commit merges yet. Please commit your changes from the command line."];
return;
}

if ([[cachedFilesController arrangedObjects] count] == 0) {
[[repository windowController] showMessageSheet:@"No changes to commit" infoText:@"You must first stage some changes before committing"];
return;
}

NSString *commitMessage = [commitMessageView string];
if ([commitMessage length] < 3) {
[[repository windowController] showMessageSheet:@"Commitmessage missing" infoText:@"Please enter a commit message before committing"];
return;
}

[cachedFilesController setSelectionIndexes:[NSIndexSet indexSet]];
[unstagedFilesController setSelectionIndexes:[NSIndexSet indexSet]];

self.busy = YES;
[commitMessageView setEditable:NO];

[index commitWithMessage:commitMessage];
}


# pragma mark PBGitIndex Notification handling
- (void)refreshFinished:(NSNotification *)notification
{
self.busy = NO;
self.status = @"Index refresh finished";
}

- (void)commitStatusUpdated:(NSNotification *)notification
{
self.status = [[notification userInfo] objectForKey:@"description"];
}

- (void)commitFinished:(NSNotification *)notification
{
[commitMessageView setEditable:YES];
[commitMessageView setString:@""];
[webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]];
}

- (void)commitFailed:(NSNotification *)notification
{
self.busy = NO;
NSString *reason = [[notification userInfo] objectForKey:@"description"];
self.status = [@"Commit failed: " stringByAppendingString:reason];
[commitMessageView setEditable:YES];
[[repository windowController] showMessageSheet:@"Commit failed" infoText:reason];
}

- (void)amendCommit:(NSNotification *)notification
{
// Replace commit message with the old one if it's less than 3 characters long.
// This is just a random number.
if ([[commitMessageView string] length] > 3)
return;

NSString *message = [[notification userInfo] objectForKey:@"message"];
commitMessageView.string = message;
}

- (void)indexChanged:(NSNotification *)notification
{
[cachedFilesController rearrangeObjects];
[unstagedFilesController rearrangeObjects];
}

- (void)indexOperationFailed:(NSNotification *)notification
{
[[repository windowController] showMessageSheet:@"Index operation failed" infoText:[[notification userInfo] objectForKey:@"description"]];
}

@end
Something went wrong with that request. Please try again.