2 // PBGitCommitController.m
5 // Created by Pieter de Bie on 19-09-08.
6 // Copyright 2008 __MyCompanyName__. All rights reserved.
9 #import "PBGitCommitController.h"
10 #import "NSFileHandleExt.h"
11 #import "PBChangedFile.h"
12 #import "PBWebChangesController.h"
13 #import "PBGitIndex.h"
15 @interface PBGitCommitController ()
16 - (void)refreshFinished:(NSNotification *)notification;
17 - (void)commitStatusUpdated:(NSNotification *)notification;
18 - (void)commitFinished:(NSNotification *)notification;
19 - (void)commitFailed:(NSNotification *)notification;
20 - (void)amendCommit:(NSNotification *)notification;
21 - (void)indexChanged:(NSNotification *)notification;
22 - (void)indexOperationFailed:(NSNotification *)notification;
25 @implementation PBGitCommitController
27 @synthesize status, index, busy;
29 - (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller
31 if (!(self = [super initWithRepository:theRepository superController:controller]))
34 index = [[PBGitIndex alloc] initWithRepository:theRepository workingDirectory:[NSURL fileURLWithPath:[theRepository workingDirectory]]];
37 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshFinished:) name:PBGitIndexFinishedIndexRefresh object:index];
38 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index];
39 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index];
40 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index];
41 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index];
42 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexChanged:) name:PBGitIndexIndexUpdated object:index];
43 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexOperationFailed:) name:PBGitIndexOperationFailed object:index];
52 [commitMessageView setTypingAttributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:12.0] forKey:NSFontAttributeName]];
54 [unstagedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasUnstagedChanges == 1"]];
55 [cachedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasStagedChanges == 1"]];
57 [unstagedFilesController setSortDescriptors:[NSArray arrayWithObjects:
58 [[NSSortDescriptor alloc] initWithKey:@"status" ascending:false],
59 [[NSSortDescriptor alloc] initWithKey:@"path" ascending:true], nil]];
60 [cachedFilesController setSortDescriptors:[NSArray arrayWithObject:
61 [[NSSortDescriptor alloc] initWithKey:@"path" ascending:true]]];
63 [cachedFilesController setAutomaticallyRearrangesObjects:NO];
64 [unstagedFilesController setAutomaticallyRearrangesObjects:NO];
69 [webController closeView];
73 - (NSResponder *)firstResponder;
75 return commitMessageView;
78 - (IBAction)signOff:(id)sender
80 if (![repository.config valueForKeyPath:@"user.name"] || ![repository.config valueForKeyPath:@"user.email"])
81 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"];
82 NSString *SOBline = [NSString stringWithFormat:@"Signed-off-by: %@ <%@>",
83 [repository.config valueForKeyPath:@"user.name"],
84 [repository.config valueForKeyPath:@"user.email"]];
86 if([commitMessageView.string rangeOfString:SOBline].location == NSNotFound) {
87 NSArray *selectedRanges = [commitMessageView selectedRanges];
88 commitMessageView.string = [NSString stringWithFormat:@"%@\n\n%@",
89 commitMessageView.string, SOBline];
90 [commitMessageView setSelectedRanges: selectedRanges];
94 - (void) refresh:(id) sender
97 self.status = @"Refreshing index…";
100 // Reload refs (in case HEAD changed)
101 [repository reloadRefs];
109 - (IBAction) commit:(id) sender
111 if ([[NSFileManager defaultManager] fileExistsAtPath:[repository.fileURL.path stringByAppendingPathComponent:@"MERGE_HEAD"]]) {
112 [[repository windowController] showMessageSheet:@"Cannot commit merges" infoText:@"GitX cannot commit merges yet. Please commit your changes from the command line."];
116 if ([[cachedFilesController arrangedObjects] count] == 0) {
117 [[repository windowController] showMessageSheet:@"No changes to commit" infoText:@"You must first stage some changes before committing"];
121 NSString *commitMessage = [commitMessageView string];
122 if ([commitMessage length] < 3) {
123 [[repository windowController] showMessageSheet:@"Commitmessage missing" infoText:@"Please enter a commit message before committing"];
127 [cachedFilesController setSelectionIndexes:[NSIndexSet indexSet]];
128 [unstagedFilesController setSelectionIndexes:[NSIndexSet indexSet]];
131 [commitMessageView setEditable:NO];
133 [index commitWithMessage:commitMessage];
137 # pragma mark PBGitIndex Notification handling
138 - (void)refreshFinished:(NSNotification *)notification
141 self.status = @"Index refresh finished";
144 - (void)commitStatusUpdated:(NSNotification *)notification
146 self.status = [[notification userInfo] objectForKey:@"description"];
149 - (void)commitFinished:(NSNotification *)notification
151 [commitMessageView setEditable:YES];
152 [commitMessageView setString:@""];
153 [webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]];
156 - (void)commitFailed:(NSNotification *)notification
159 NSString *reason = [[notification userInfo] objectForKey:@"description"];
160 self.status = [@"Commit failed: " stringByAppendingString:reason];
161 [commitMessageView setEditable:YES];
162 [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason];
165 - (void)amendCommit:(NSNotification *)notification
167 // Replace commit message with the old one if it's less than 3 characters long.
168 // This is just a random number.
169 if ([[commitMessageView string] length] > 3)
172 NSString *message = [[notification userInfo] objectForKey:@"message"];
173 commitMessageView.string = message;
176 - (void)indexChanged:(NSNotification *)notification
178 [cachedFilesController rearrangeObjects];
179 [unstagedFilesController rearrangeObjects];
182 - (void)indexOperationFailed:(NSNotification *)notification
184 [[repository windowController] showMessageSheet:@"Index operation failed" infoText:[[notification userInfo] objectForKey:@"description"]];