2011-05-25 10 views
55

मुझे पता है कि जीआईटी किसी भी तरह से स्वचालित रूप से पता लगाती है कि फ़ाइल बाइनरी या टेक्स्ट है या नहीं, और यदि आवश्यक हो तो यह gitattributes को मैन्युअल रूप से सेट करने के लिए उपयोग किया जा सकता है। लेकिन क्या जीआईटी से यह पूछने का एक तरीका है कि यह फाइल का इलाज कैसे करता है? एक ascii.dat फ़ाइल सादे-पाठ युक्त और एक binary.dat फ़ाइल यादृच्छिक द्विआधारी सामान युक्तयह निर्धारित करने के लिए कि क्या गिट बाइनरी या टेक्स्ट के रूप में फ़ाइल को संभालती है?

तो चलो कहते हैं कि मैं उस में दो फाइलों के साथ एक git भंडार डालते हैं। गिट पहली डेटा फ़ाइल को टेक्स्ट और माध्यमिक फ़ाइल बाइनरी के रूप में संभालती है। अब मैं एक जीआईटी वेबफ्रेंड लिखना चाहता हूं जिसमें टेक्स्ट फाइलों के लिए दर्शक और बाइनरी फाइलों के लिए एक विशेष दर्शक है (उदाहरण के लिए हेक्स डंप प्रदर्शित करना)। निश्चित रूप से, मैं अपना खुद का टेक्स्ट/बाइनरी चेक लागू कर सकता हूं लेकिन यह अधिक उपयोगी होगा अगर दर्शक जानकारी पर निर्भर करता है कि जीआईटी इन फ़ाइलों को कैसे संभालता है।

तो अगर मैं फ़ाइल को टेक्स्ट या बाइनरी के रूप में मानता हूं तो मैं जीआईटी से कैसे पूछ सकता हूं?

उत्तर

27

builtin_diff()diff_filespec_is_binary() जो buffer_is_binary() जो पहले 8000 बाइट में एक शून्य बाइट (NUL "चरित्र") के किसी भी घटना (या अगर कम पूरी लंबाई) के लिए जाँच करता कहता है कहता है।

मुझे नहीं लगता कि यह "यह बाइनरी है?" परीक्षण किसी भी कमांड में स्पष्ट रूप से उजागर किया गया है।

git merge-file सीधे buffer_is_binary() का उपयोग करता है, तो आप इसके बारे में उपयोग करने में सक्षम हो सकता है:

git merge-file /dev/null /dev/null file-to-test 

यह error: Cannot merge binary files: file-to-test तरह त्रुटि संदेश का उत्पादन करने लगता है और जब एक बाइनरी फ़ाइल दिया 255 का एक निकास स्थिति अर्जित करता है। मुझे यकीन नहीं है कि मैं इस व्यवहार पर भरोसा करना चाहता हूं।

शायद git diff --numstat अधिक विश्वसनीय होगा:

isBinary() { 
    p=$(printf '%s\t-\t' -) 
    t=$(git diff --no-index --numstat /dev/null "$1") 
    case "$t" in "$p"*) return 0 ;; esac 
    return 1 
} 
isBinary file-to-test && echo binary || echo not binary 

बाइनरी फ़ाइलों के लिए, --numstat उत्पादन के साथ - टैब - टैब शुरू कर देना चाहिए, ताकि हम सिर्फ इतना है कि के लिए परीक्षण।


builtin_diff() कि परिचित होना चाहिए Binary files %s and %s differ तरह तार है।

+1

साइगविन (विंडोज) पर,/dev/null मौजूद नहीं है। किसी को सेठ द्वारा लाए गए जादू SHA1 का उपयोग करना पड़ता है। 'गिट diff --numstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD -" $ 1 "'। – koppor

17

मुझे यह जवाब पसंद नहीं है, लेकिन आप यह देखने के लिए कि क्या यह बाइनरी है, आप गिट-डिफ-पेड़ के आउटपुट को पार्स कर सकते हैं। उदाहरण के लिए:

git diff-tree -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD -- MegaCli 
diff --git a/megaraid/MegaCli b/megaraid/MegaCli 
new file mode 100755 
index 0000000..7f0e997 
Binary files /dev/null and b/megaraid/MegaCli differ 

के विपरीत:

git diff-tree -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD -- megamgr 
diff --git a/megaraid/megamgr b/megaraid/megamgr 
new file mode 100755 
index 0000000..50fd8a1 
--- /dev/null 
+++ b/megaraid/megamgr 
@@ -0,0 +1,78 @@ 
+#!/bin/sh 
[…] 

ओह, और btw, 4b825d ... एक जादू SHA जो खाली पेड़ का प्रतिनिधित्व करता है (यह एक खाली पेड़ के लिए SHA है, लेकिन गिट विशेष रूप से इस जादू के बारे में पता है)।

+2

धन्यवाद, अच्छा महोदय। - filename' प्रारूप - मैं 'Git diff पेड़ 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD' जो' है --numstat इस्तेमाल किया। –

+2

आप अपने रेपो में सभी बाइनरी फ़ाइलों की एक सूची चाहते हैं, आप 'Git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 प्रमुख --numstat कर सकते हैं - | grep "^ -" | कट-एफ 3' – bonh

+1

सेठ कृपया अंतिम वाक्य में टाइपो को ठीक करें, 4b82 ** 5 ** डी होना चाहिए; तो मुझे 1-वर्ण संपादित करने की अनुमति नहीं देगी। – chrisinmtown

23
git grep -I --name-only --untracked -e . -- ascii.dat binary.dat ... 

फ़ाइलें जो पाठ फ़ाइलों के रूप में व्याख्या git के नाम वापस आ जाएगी।

आप वाइल्डकार्ड का उपयोग कर सकते हैं उदा।

git grep -I --name-only --untracked -e . -- *.ps1 
+0

बाद के संस्करणों के साथ काम करता है, लेकिन गिट 1.7.5.4 के साथ यह सिर्फ _fatal देता है: खाली (उप) अभिव्यक्ति_। नियमित रूप से अभिव्यक्ति को '-e।' में बदलना इस संस्करण के साथ काम करता है (शायद खाली फाइलों की गलत फाइलों को गलत पहचानने की लागत पर!)। –

+0

फ़ाइल का परीक्षण करने का वह आसान तरीका पसंद आया। धन्यवाद! –

+0

मैंने इसे अधिक-संगत होने के लिए '-e'' में बदल दिया और फ़ाइलों की एक विस्तृत श्रृंखला के साथ काम करने के लिए' --untracked 'जोड़ा। – eckes

-3

आप कमांड लाइन टूल 'फ़ाइल' उपयोगिता का उपयोग कर सकते हैं। Windows पर यह Git स्थापना में शामिल है और सामान्य रूप से सी में में स्थित: \ Program Files \ Git \ usr \ बिन फ़ोल्डर

file --mime-encoding * 

Get encoding of a file in Windows

+1

स्पष्टीकरण के बिना डाउनवोट क्यों गलत है? –

+2

मैं वह नहीं हूं जिसने इसे कम किया है, लेकिन इसमें कोई संदेह नहीं था क्योंकि 'फ़ाइल' के पास कुछ भी नहीं है कि गिट फ़ाइल प्रकार को कैसे निर्धारित करता है। 'फ़ाइल' गिट कोड का उपयोग नहीं करता है, और गिट 'फ़ाइल' कमांड का उपयोग नहीं करता है। उदाहरण के लिए, 'फ़ाइल', इस बारे में कुछ नहीं जानता कि .gitattributes फ़ाइल फ़ाइल प्रकार को निर्धारित करने में गिट की सहायता कैसे करती है। –

0

में अधिक देखें गरीब कोड गुणवत्ता के लिए थप्पड़ मारा होने का खतरा कम, मैं एक सी उपयोगिता सूचीबद्ध कर रहा हूं, is_binary, गिट स्रोत में मूल buffer_is_binary() दिनचर्या के आसपास बनाया गया है। निर्माण और चलाने के लिए कृपया आंतरिक टिप्पणियां देखें। आसानी से संशोधित:

/*********************************************************** 
* is_binary.c 
* 
* Usage: is_binary <pathname> 
* Returns a 1 if a binary; return a 0 if non-binary 
* 
* Thanks to Git and Stackoverflow developers for helping with these routines: 
* - the buffer_is_binary() routine from the xdiff-interface.c module 
* in git source code. 
* - the read-a-filename-from-stdin route 
* - the read-a-file-into-memory (fill_buffer()) routine 
* 
* To build: 
* % gcc is_binary.c -o is_binary 
* 
* To build debuggable (to push a few messages to stdout): 
* % gcc -DDEBUG=1 ./is_binary.c -o is_binary 
* 
* BUGS: 
* Doesn't work with piped input, like 
* % cat foo.tar | is_binary 
* Claims that zero input is binary. Actually, 
* what should it be? 
* 
* Revision 1.4 
* 
* Tue Sep 12 09:01:33 EDT 2017 
***********************************************************/ 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define MAX_PATH_LENGTH 200 
#define FIRST_FEW_BYTES 8000 

/* global, unfortunately */ 
char *source_blob_buffer; 

/* From: https://stackoverflow.com/questions/14002954/c-programming-how-to-read-the-whole-file-contents-into-a-buffer */ 

/* From: https://stackoverflow.com/questions/1563882/reading-a-file-name-from-piped-command */ 

/* From: https://stackoverflow.com/questions/6119956/how-to-determine-if-git-handles-a-file-as-binary-or-as-text 
*/ 

/* The key routine in this function is from libc: void *memchr(const void *s, int c, size_t n); */ 
/* Checks for any occurrence of a zero byte (NUL character) in the first 8000 bytes (or the entire length if shorter). */ 

int buffer_is_binary(const char *ptr, unsigned long size) 
{ 
    if (FIRST_FEW_BYTES < size) 
    size = FIRST_FEW_BYTES; 
    /* printf("buff = %s.\n", ptr); */ 
    return !!memchr(ptr, 0, size); 
} 
int fill_buffer(FILE * file_object_pointer) { 
    fseek(file_object_pointer, 0, SEEK_END); 
    long fsize = ftell(file_object_pointer); 
    fseek(file_object_pointer, 0, SEEK_SET); //same as rewind(f); 
    source_blob_buffer = malloc(fsize + 1); 
    fread(source_blob_buffer, fsize, 1, file_object_pointer); 
    fclose(file_object_pointer); 
    source_blob_buffer[fsize] = 0; 
    return (fsize + 1); 
} 
int main(int argc, char *argv[]) { 

    char pathname[MAX_PATH_LENGTH]; 
    FILE *file_object_pointer; 

    if (argc == 1) { 
    file_object_pointer = stdin; 
    } else { 
    strcpy(pathname,argv[1]); 
#ifdef DEBUG 
    printf("pathname=%s.\n", pathname); 
#endif 
    file_object_pointer = fopen (pathname, "rb"); 
    if (file_object_pointer == NULL) { 
     printf ("I'm sorry, Dave, I can't do that--"); 
     printf ("open the file '%s', that is.\n", pathname); 
     exit(3); 
    } 
    } 
    if (!file_object_pointer) { 
    printf("Not a file nor a pipe--sorry.\n"); 
    exit (4); 
    } 
    int fsize = fill_buffer(file_object_pointer); 
    int result = buffer_is_binary(source_blob_buffer, fsize - 2); 

#ifdef DEBUG 
    if (result == 1) { 
    printf ("%s %d\n", pathname, fsize - 1); 
    } 
    else { 
    printf ("File '%s' is NON-BINARY; size is %d bytes.\n", pathname, fsize - 1); 
    } 
#endif 
    exit(result); 
    /* easy check -- 'echo $?' after running */ 
} 
संबंधित मुद्दे