forked from laullon/gitx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPBRefMenuItem.m
216 lines (167 loc) · 8.8 KB
/
PBRefMenuItem.m
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
//
// PBRefMenuItem.m
// GitX
//
// Created by Pieter de Bie on 01-11-08.
// Copyright 2008 Pieter de Bie. All rights reserved.
//
#import "PBRefMenuItem.h"
#import "PBStashCommandFactory.h"
@implementation PBRefMenuItem
@synthesize refish;
+ (PBRefMenuItem *) itemWithTitle:(NSString *)title action:(SEL)selector enabled:(BOOL)isEnabled
{
if (!isEnabled)
selector = nil;
PBRefMenuItem *item = [[PBRefMenuItem alloc] initWithTitle:title action:selector keyEquivalent:@""];
[item setEnabled:isEnabled];
return item;
}
+ (PBRefMenuItem *) separatorItem
{
PBRefMenuItem *item = (PBRefMenuItem *)[super separatorItem];
return item;
}
+ (NSArray *) defaultMenuItemsForRef:(PBGitRef *)ref inRepository:(PBGitRepository *)repo target:(id)target
{
if (!ref || !repo || !target) {
return nil;
}
NSMutableArray *items = [NSMutableArray array];
NSString *targetRefName = [ref shortName];
PBGitRef *headRef = [[repo headRef] ref];
NSString *headRefName = [headRef shortName];
BOOL isHead = [ref isEqualToRef:headRef];
BOOL isOnHeadBranch = isHead ? YES : [repo isRefOnHeadBranch:ref];
BOOL isDetachedHead = (isHead && [headRefName isEqualToString:@"HEAD"]);
NSString *remoteName = [ref remoteName];
if (!remoteName && [ref isBranch])
remoteName = [[repo remoteRefForBranch:ref error:NULL] remoteName];
BOOL hasRemote = (remoteName ? YES : NO);
BOOL isRemote = ([ref isRemote] && ![ref isRemoteBranch]);
if (!isRemote) {
// checkout ref
NSString *checkoutTitle = [@"Checkout " stringByAppendingString:targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle:checkoutTitle action:@selector(checkout:) enabled:!isHead]];
[items addObject:[PBRefMenuItem separatorItem]];
NSString *resetTitle = [NSString stringWithFormat:@"Reset %@ to %@…", headRefName, targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle: resetTitle action:@selector(reset:) enabled:YES]];
[items addObject:[PBRefMenuItem separatorItem]];
// create branch
NSString *createBranchTitle = [ref isRemoteBranch] ? [NSString stringWithFormat:@"Create Branch That Tracks %@…", targetRefName] : @"Create Branch…";
[items addObject:[PBRefMenuItem itemWithTitle:createBranchTitle action:@selector(createBranch:) enabled:YES]];
// create tag
[items addObject:[PBRefMenuItem itemWithTitle:@"Create Tag…" action:@selector(createTag:) enabled:YES]];
// view tag info
if ([ref isTag])
[items addObject:[PBRefMenuItem itemWithTitle:@"View Tag Info…" action:@selector(showTagInfoSheet:) enabled:YES]];
// Diff
NSString *diffTitle = [NSString stringWithFormat:@"Diff with %@", headRefName];
[items addObject:[PBRefMenuItem itemWithTitle:diffTitle action:@selector(diffWithHEAD:) enabled:!isHead]];
[items addObject:[PBRefMenuItem separatorItem]];
// merge ref
NSString *mergeTitle = isOnHeadBranch ? @"Merge" : [NSString stringWithFormat:@"Merge %@ into %@", targetRefName, headRefName];
[items addObject:[PBRefMenuItem itemWithTitle:mergeTitle action:@selector(merge:) enabled:!isOnHeadBranch]];
// rebase
NSString *rebaseTitle = isOnHeadBranch ? @"Rebase" : [NSString stringWithFormat:@"Rebase %@ on %@", headRefName, targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle:rebaseTitle action:@selector(rebaseHeadBranch:) enabled:!isOnHeadBranch]];
[items addObject:[PBRefMenuItem separatorItem]];
}
// fetch
NSString *fetchTitle = hasRemote ? [NSString stringWithFormat:@"Fetch %@", remoteName] : @"Fetch";
[items addObject:[PBRefMenuItem itemWithTitle:fetchTitle action:@selector(fetchRemote:) enabled:hasRemote]];
// pull
NSString *pullTitle = hasRemote ? [NSString stringWithFormat:@"Pull %@ and Update %@", remoteName, headRefName] : @"Pull";
[items addObject:[PBRefMenuItem itemWithTitle:pullTitle action:@selector(pullRemote:) enabled:hasRemote]];
// push
if (isRemote || [ref isRemoteBranch]) {
// push updates to remote
NSString *pushTitle = [NSString stringWithFormat:@"Push Updates to %@", remoteName];
[items addObject:[PBRefMenuItem itemWithTitle:pushTitle action:@selector(pushUpdatesToRemote:) enabled:YES]];
}
else if (isDetachedHead) {
[items addObject:[PBRefMenuItem itemWithTitle:@"Push" action:nil enabled:NO]];
}
else {
// push to default remote
BOOL hasDefaultRemote = NO;
if (![ref isTag] && hasRemote) {
hasDefaultRemote = YES;
NSString *pushTitle = [NSString stringWithFormat:@"Push %@ to %@", targetRefName, remoteName];
[items addObject:[PBRefMenuItem itemWithTitle:pushTitle action:@selector(pushDefaultRemoteForRef:) enabled:YES]];
}
// push to remotes submenu
NSArray *remoteNames = [repo remotes];
if ([remoteNames count] && !(hasDefaultRemote && ([remoteNames count] == 1))) {
NSString *pushToTitle = [NSString stringWithFormat:@"Push %@ to", targetRefName];
PBRefMenuItem *pushToItem = [PBRefMenuItem itemWithTitle:pushToTitle action:nil enabled:YES];
NSMenu *remotesMenu = [[NSMenu alloc] initWithTitle:@"remotesMenu"];
for (NSString *remote in remoteNames) {
PBRefMenuItem *remoteItem = [PBRefMenuItem itemWithTitle:remote action:@selector(pushToRemote:) enabled:YES];
[remoteItem setTarget:target];
[remoteItem setRefish:ref];
[remoteItem setRepresentedObject:remote];
[remotesMenu addItem:remoteItem];
}
[pushToItem setSubmenu:remotesMenu];
[items addObject:pushToItem];
}
}
// delete ref
[items addObject:[PBRefMenuItem separatorItem]];
NSString *deleteTitle = [NSString stringWithFormat:@"Delete %@…", targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle:deleteTitle action:@selector(showDeleteRefSheet:) enabled:!isDetachedHead]];
// rename ref
NSString *renameTitle = [NSString stringWithFormat:@"Rename %@…", targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle:renameTitle action:@selector(showRenameSheet:) enabled:!isDetachedHead]];
if (isRemote)
{
// change Remote Url
[items addObject:[PBRefMenuItem separatorItem]];
NSString *changeRemoteUrlTitle = [NSString stringWithFormat:@"Change Remote-URL from %@…", targetRefName];
[items addObject:[PBRefMenuItem itemWithTitle:changeRemoteUrlTitle action:@selector(showChangeRemoteUrlSheet:) enabled:YES]];
}
[items addObject:[PBRefMenuItem separatorItem]];
NSString *copyTitle = @"Copy Reference to Clipboard";
[items addObject:[PBRefMenuItem itemWithTitle:copyTitle action:@selector(copyRefName:) enabled:!isDetachedHead]];
for (PBRefMenuItem *item in items) {
[item setTarget:target];
[item setRefish:ref];
}
return items;
}
+ (NSArray *) defaultMenuItemsForCommit:(PBGitCommit *)commit target:(id)target
{
NSMutableArray *items = [NSMutableArray array];
NSString *headBranchName = [[[commit.repository headRef] ref] shortName];
BOOL isOnHeadBranch = [commit isOnHeadBranch];
BOOL isHead = [[commit sha] isEqual:[commit.repository headSHA]];
[items addObject:[PBRefMenuItem itemWithTitle:@"Checkout Commit" action:@selector(checkout:) enabled:YES]];
[items addObject:[PBRefMenuItem separatorItem]];
NSString *resetTitle = [NSString stringWithFormat:@"Reset %@ to here…", headBranchName];
[items addObject:[PBRefMenuItem itemWithTitle: resetTitle action:@selector(reset:) enabled:YES]];
[items addObject:[PBRefMenuItem separatorItem]];
[items addObject:[PBRefMenuItem itemWithTitle:@"Create Branch…" action:@selector(createBranch:) enabled:YES]];
[items addObject:[PBRefMenuItem itemWithTitle:@"Create Tag…" action:@selector(createTag:) enabled:YES]];
[items addObject:[PBRefMenuItem separatorItem]];
[items addObject:[PBRefMenuItem itemWithTitle:@"Copy SHA" action:@selector(copySHA:) enabled:YES]];
[items addObject:[PBRefMenuItem itemWithTitle:@"Copy Patch" action:@selector(copyPatch:) enabled:YES]];
NSString *diffTitle = [NSString stringWithFormat:@"Diff with %@", headBranchName];
[items addObject:[PBRefMenuItem itemWithTitle:diffTitle action:@selector(diffWithHEAD:) enabled:!isHead]];
[items addObject:[PBRefMenuItem separatorItem]];
// merge commit
NSString *mergeTitle = isOnHeadBranch ? @"Merge commit" : [NSString stringWithFormat:@"Merge commit into %@", headBranchName];
[items addObject:[PBRefMenuItem itemWithTitle:mergeTitle action:@selector(merge:) enabled:!isOnHeadBranch]];
// cherry pick
NSString *cherryPickTitle = isOnHeadBranch ? @"Cherry pick commit" : [NSString stringWithFormat:@"Cherry pick commit to %@", headBranchName];
[items addObject:[PBRefMenuItem itemWithTitle:cherryPickTitle action:@selector(cherryPick:) enabled:!isOnHeadBranch]];
// rebase
NSString *rebaseTitle = isOnHeadBranch ? @"Rebase commit" : [NSString stringWithFormat:@"Rebase %@ on commit", headBranchName];
[items addObject:[PBRefMenuItem itemWithTitle:rebaseTitle action:@selector(rebaseHeadBranch:) enabled:!isOnHeadBranch]];
for (PBRefMenuItem *item in items) {
[item setTarget:target];
[item setRefish:commit];
}
return items;
}
@end