mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
PBGitTree: Don't try to print binary-file contents
This patch prevents the plaintext display of files with binary content in tree-view by connecting the content to the textContents attribute. PBGitTree is extended with the method textContents, which returns the textual representation of a PBGitTree-object. The methods first checks the output of "git check-attr binary <file>" to see if the user set/unset the binary attribute manually. Then it checks for common binary file-extensions. If this method can't determine whether the file is binary, the file-content is loaded and Unix "file" is run on the first 100 bytes of the file to make a decision. It also adds the -[PBGitTree fileSize] method to check the size of the file before actually loading its contents. Signed-off-by: Johannes Gilger <heipei@hackvalue.de> Edited-by: Pieter de Bie <pdebie@ai.rug.nl>
This commit is contained in:
committed by
Pieter de Bie
parent
8750060621
commit
8243cf58b3
+37
-32
@@ -43,6 +43,7 @@
|
||||
<string>path</string>
|
||||
<string>contents</string>
|
||||
<string>selectedTab</string>
|
||||
<string>textContents</string>
|
||||
</object>
|
||||
<string key="NSObjectClassName">PBGitTree</string>
|
||||
<object class="_NSManagedProxy" key="_NSManagedProxy"/>
|
||||
@@ -2047,35 +2048,6 @@
|
||||
</object>
|
||||
<int key="connectionID">264</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: selection.contents</string>
|
||||
<reference key="source" ref="75600241"/>
|
||||
<reference key="destination" ref="69733037"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="75600241"/>
|
||||
<reference key="NSDestination" ref="69733037"/>
|
||||
<string key="NSLabel">value: selection.contents</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">selection.contents</string>
|
||||
<object class="NSDictionary" key="NSOptions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>NSAllowsEditingMultipleValuesSelection</string>
|
||||
<string>NSConditionallySetsEditable</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="0" id="8"/>
|
||||
<reference ref="8"/>
|
||||
</object>
|
||||
</object>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">266</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">branchPopUp</string>
|
||||
@@ -2146,6 +2118,35 @@
|
||||
</object>
|
||||
<int key="connectionID">290</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">value: selection.textContents</string>
|
||||
<reference key="source" ref="75600241"/>
|
||||
<reference key="destination" ref="69733037"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="75600241"/>
|
||||
<reference key="NSDestination" ref="69733037"/>
|
||||
<string key="NSLabel">value: selection.textContents</string>
|
||||
<string key="NSBinding">value</string>
|
||||
<string key="NSKeyPath">selection.textContents</string>
|
||||
<object class="NSDictionary" key="NSOptions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSMutableArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>NSAllowsEditingMultipleValuesSelection</string>
|
||||
<string>NSConditionallySetsEditable</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<boolean value="NO" id="6"/>
|
||||
<reference ref="6"/>
|
||||
</object>
|
||||
</object>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">291</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<object class="NSArray" key="orderedObjects">
|
||||
@@ -2858,6 +2859,8 @@
|
||||
<string>273.IBPluginDependency</string>
|
||||
<string>28.IBPluginDependency</string>
|
||||
<string>28.IBShouldRemoveOnLegacySave</string>
|
||||
<string>287.IBPluginDependency</string>
|
||||
<string>288.IBPluginDependency</string>
|
||||
<string>29.IBPluginDependency</string>
|
||||
<string>29.IBShouldRemoveOnLegacySave</string>
|
||||
<string>3.IBPluginDependency</string>
|
||||
@@ -2950,7 +2953,7 @@
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>{{504, 612}, {346, 102}}</string>
|
||||
<string>{{504, 612}, {346, 102}}</string>
|
||||
<reference ref="8"/>
|
||||
<integer value="0" id="8"/>
|
||||
<boolean value="YES" id="5"/>
|
||||
<reference ref="5"/>
|
||||
<string>{1000, 102}</string>
|
||||
@@ -2990,6 +2993,8 @@
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<reference ref="9"/>
|
||||
@@ -3021,7 +3026,7 @@
|
||||
</object>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>{{59, 67}, {852, 432}}</string>
|
||||
<string>{{321, 67}, {852, 432}}</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
@@ -3056,7 +3061,7 @@
|
||||
</object>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">290</int>
|
||||
<int key="maxID">291</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
|
||||
+4
-1
@@ -10,13 +10,15 @@
|
||||
#import "PBGitRepository.h"
|
||||
|
||||
@interface PBGitTree : NSObject {
|
||||
long long _fileSize;
|
||||
|
||||
NSString* sha;
|
||||
NSString* path;
|
||||
PBGitRepository* repository;
|
||||
__weak PBGitTree* parent;
|
||||
NSArray* children;
|
||||
BOOL leaf;
|
||||
|
||||
|
||||
NSString* localFileName;
|
||||
NSDate* localMtime;
|
||||
}
|
||||
@@ -26,6 +28,7 @@
|
||||
- (void) saveToFolder: (NSString *) directory;
|
||||
|
||||
- (NSString*) tmpFileNameForContents;
|
||||
- (long long)fileSize;
|
||||
|
||||
@property(copy) NSString* sha;
|
||||
@property(copy) NSString* path;
|
||||
|
||||
+83
-12
@@ -63,25 +63,96 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)hasBinaryHeader:(NSString *)fileHeader
|
||||
{
|
||||
if (!fileHeader)
|
||||
return NO;
|
||||
|
||||
NSString *filetype = [PBEasyPipe outputForCommand:@"/usr/bin/file"
|
||||
withArgs:[NSArray arrayWithObjects:@"-b", @"-N", @"-", nil]
|
||||
inDir:[repository workingDirectory]
|
||||
inputString:fileHeader
|
||||
retValue:nil];
|
||||
|
||||
return [filetype rangeOfString:@"text"].location == NSNotFound;
|
||||
}
|
||||
|
||||
- (BOOL)hasBinaryAttributes
|
||||
{
|
||||
// First ask git check-attr if the file has a binary attribute custom set
|
||||
NSFileHandle *handle = [repository handleInWorkDirForArguments:[NSArray arrayWithObjects:@"check-attr", @"binary", [self fullPath], nil]];
|
||||
NSData *data = [handle readDataToEndOfFile];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
|
||||
|
||||
if (!string)
|
||||
return NO;
|
||||
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
||||
|
||||
if ([string hasSuffix:@"binary: set"])
|
||||
return YES;
|
||||
|
||||
if ([string hasSuffix:@"binary: unset"])
|
||||
return NO;
|
||||
|
||||
// Binary state unknown, do a check on common filename-extensions
|
||||
for (NSString *extension in [NSArray arrayWithObjects:@".pdf", @".jpg", @".jpeg", @".png", @".bmp", @".gif", @".o", nil]) {
|
||||
if ([[self fullPath] hasSuffix:extension])
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString*) contents
|
||||
{
|
||||
if (!leaf)
|
||||
return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
|
||||
|
||||
NSData* data = nil;
|
||||
|
||||
if ([self isLocallyCached])
|
||||
data = [NSData dataWithContentsOfFile: localFileName];
|
||||
else {
|
||||
NSFileHandle* handle = [repository handleForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
|
||||
data = [handle readDataToEndOfFile];
|
||||
if ([self isLocallyCached]) {
|
||||
NSData *data = [NSData dataWithContentsOfFile:localFileName];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
if (!string)
|
||||
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
|
||||
return string;
|
||||
}
|
||||
|
||||
NSString* string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
if (!string) {
|
||||
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
|
||||
}
|
||||
return string;
|
||||
return [repository outputForArguments:[NSArray arrayWithObjects:@"show", [self refSpec], nil]];
|
||||
}
|
||||
|
||||
- (long long)fileSize
|
||||
{
|
||||
if (_fileSize)
|
||||
return _fileSize;
|
||||
|
||||
NSFileHandle *handle = [repository handleForArguments:[NSArray arrayWithObjects:@"cat-file", @"-s", [self refSpec], nil]];
|
||||
NSString *sizeString = [[NSString alloc] initWithData:[handle readDataToEndOfFile] encoding:NSISOLatin1StringEncoding];
|
||||
|
||||
if (!sizeString)
|
||||
_fileSize = -1;
|
||||
else
|
||||
_fileSize = [sizeString longLongValue];
|
||||
|
||||
return _fileSize;
|
||||
}
|
||||
|
||||
- (NSString *)textContents
|
||||
{
|
||||
if (!leaf)
|
||||
return [NSString stringWithFormat:@"This is a tree with path %@", [self fullPath]];
|
||||
|
||||
if ([self hasBinaryAttributes])
|
||||
return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]];
|
||||
|
||||
long long fileSize = [self fileSize];
|
||||
if (fileSize > 52428800) // ~50MB
|
||||
return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], fileSize];
|
||||
|
||||
NSString *contents = [self contents];
|
||||
|
||||
if ([self hasBinaryHeader:([contents length] >= 100) ? [contents substringToIndex:99] : contents])
|
||||
return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], fileSize];
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
- (void) saveToFolder: (NSString *) dir
|
||||
|
||||
Reference in New Issue
Block a user