Merge branch 'fix_interspacing'
[GitX.git] / PBGitTree.m
blob59a2659c00a371da4e5c939bce232bdbfccab88a
1 //
2 //  PBGitTree.m
3 //  GitTest
4 //
5 //  Created by Pieter de Bie on 15-06-08.
6 //  Copyright 2008 __MyCompanyName__. All rights reserved.
7 //
9 #import "PBGitTree.h"
10 #import "PBGitCommit.h"
11 #import "NSFileHandleExt.h"
12 #import "PBEasyPipe.h"
13 #import "PBEasyFS.h"
15 @implementation PBGitTree
17 @synthesize sha, path, repository, leaf, parent;
19 + (PBGitTree*) rootForCommit:(id) commit
21         PBGitCommit* c = commit;
22         PBGitTree* tree = [[self alloc] init];
23         tree.parent = nil;
24         tree.leaf = NO;
25         tree.sha = c.sha;
26         tree.repository = c.repository;
27         tree.path = @"";
28         return tree;
31 + (PBGitTree*) treeForTree: (PBGitTree*) prev andPath: (NSString*) path;
33         PBGitTree* tree = [[self alloc] init];
34         tree.parent = prev;
35         tree.sha = prev.sha;
36         tree.repository = prev.repository;
37         tree.path = path;
38         return tree;
41 - init
43         children = nil;
44         localFileName = nil;
45         leaf = YES;
46         return self;
49 - (NSString*) refSpec
51         return [NSString stringWithFormat:@"%@:%@", self.sha, self.fullPath];
54 - (BOOL) isLocallyCached
56         NSFileManager* fs = [NSFileManager defaultManager];
57         if (localFileName && [fs fileExistsAtPath:localFileName])
58         {
59                 NSDate* mtime = [[fs attributesOfItemAtPath:localFileName error: nil] objectForKey:NSFileModificationDate];
60                 if ([mtime compare:localMtime] == 0)
61                         return YES;
62         }
63         return NO;
66 - (NSString*) contents
68         if (!leaf)
69                 return [NSString stringWithFormat:@"This is a tree with path %@", self];
71         NSData* data = nil;
72         
73         if ([self isLocallyCached])
74                 data = [NSData dataWithContentsOfFile: localFileName];
75         else {
76                 NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
77                 data = [handle readDataToEndOfFile];
78         }
79         
80         return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
83 - (void) saveToFolder: (NSString *) dir
85         NSString* newName = [dir stringByAppendingPathComponent:path];
87         if (leaf) {
88                 NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
89                 NSData* data = [handle readDataToEndOfFile];
90                 [data writeToFile:newName atomically:YES];
91         } else { // Directory
92                 [[NSFileManager defaultManager] createDirectoryAtPath:newName attributes:nil];
93                 for (PBGitTree* child in children)
94                         [child saveToFolder: newName];
95         }
98 - (NSString*) tmpDirWithContents
100         if (leaf)
101                 return nil;
103         if (!localFileName)
104                 localFileName = [PBEasyFS tmpDirWithPrefix: path];
106         NSLog(@"Exporting children..");
108         for (PBGitTree* child in [self children]) {
109                 NSLog(@"Telling %@ to save to %@!", [child fullPath], localFileName);
110                 [child saveToFolder: localFileName];
111         }
112         
113         return localFileName;
116         
118 - (NSString*) tmpFileNameForContents
120         if (!leaf)
121                 return [self tmpDirWithContents];
122         
123         if ([self isLocallyCached])
124                 return localFileName;
125         
126         if (!localFileName)
127                 localFileName = [[PBEasyFS tmpDirWithPrefix: sha] stringByAppendingPathComponent:path];
128         
129         NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
130         NSData* data = [handle readDataToEndOfFile];
131         [data writeToFile:localFileName atomically:YES];
132         
133         NSFileManager* fs = [NSFileManager defaultManager];
134         localMtime = [[fs attributesOfItemAtPath:localFileName error: nil] objectForKey:NSFileModificationDate];
136         return localFileName;
139 - (NSArray*) children
141         if (children != nil)
142                 return children;
143         
144         NSString* ref = [self refSpec];
145         NSLog(@"Starting get for %@", ref);
147         NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", ref, nil]];
148         [handle readLine];
149         [handle readLine];
150         
151         NSMutableArray* c = [NSMutableArray array];
152         
153         NSString* p = [handle readLine];
154         while (p.length > 0) {
155                 BOOL isLeaf = ([p characterAtIndex:p.length - 1] != '/');
156                 if (!isLeaf)
157                         p = [p substringToIndex:p.length -1];
159                 PBGitTree* child = [PBGitTree treeForTree:self andPath:p];
160                 child.leaf = isLeaf;
161                 [c addObject: child];
162                 
163                 p = [handle readLine];
164         }
165         children = c;
166         return c;
169 - (NSString*) fullPath
171         if (!parent)
172                 return @"";
173         
174         if ([parent.fullPath isEqualToString:@""])
175                 return self.path;
176         
177         return [parent.fullPath stringByAppendingPathComponent: self.path];
180 - (void) finalize
182         if (localFileName)
183                 [[NSFileManager defaultManager] removeFileAtPath:localFileName handler:nil];
184         [super finalize];
186 @end