github.com/git-lfs/git-lfs@v2.5.2+incompatible/docs/spec.md (about)

     1  # Git LFS Specification
     2  
     3  This is a general guide for Git LFS clients.  Typically it should be
     4  implemented by a command line `git-lfs` tool, but the details may be useful
     5  for other tools.
     6  
     7  ## The Pointer
     8  
     9  The core Git LFS idea is that instead of writing large blobs to a Git repository,
    10  only a pointer file is written.
    11  
    12  * Pointer files are text files which MUST contain only UTF-8 characters.
    13  * Each line MUST be of the format `{key} {value}\n` (trailing unix newline).
    14  * Only a single space character between `{key}` and `{value}`.
    15  * Keys MUST only use the characters `[a-z] [0-9] . -`.
    16  * The first key is _always_ `version`.
    17  * Lines of key/value pairs MUST be sorted alphabetically in ascending order
    18  (with the exception of `version`, which is always first).
    19  * Values MUST NOT contain return or newline characters.
    20  * Pointer files MUST be stored in Git with their executable bit matching that
    21  of the replaced file.
    22  
    23  An empty file is the pointer for an empty file. That is, empty files are
    24  passed through LFS without any change.
    25  
    26  The required keys are:
    27  
    28  * `version` is a URL that identifies the pointer file spec.  Parsers MUST use
    29  simple string comparison on the version, without any URL parsing or
    30  normalization.  It is case sensitive, and %-encoding is discouraged.
    31  * `oid` tracks the unique object id for the file, prefixed by its hashing
    32  method: `{hash-method}:{hash}`.  Currently, only `sha256` is supported.
    33  * `size` is in bytes.
    34  
    35  Example of a v1 text pointer:
    36  
    37  ```
    38  version https://git-lfs.github.com/spec/v1
    39  oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
    40  size 12345
    41  (ending \n)
    42  ```
    43  
    44  Blobs created with the pre-release version of the tool generated files with
    45  a different version URL.  Git LFS can read these files, but writes them using
    46  the version URL above.
    47  
    48  ```
    49  version https://hawser.github.com/spec/v1
    50  oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
    51  size 12345
    52  (ending \n)
    53  ```
    54  
    55  For testing compliance of any tool generating its own pointer files, the
    56  reference is this official Git LFS tool:
    57  
    58  **NOTE:** exact pointer command behavior TBD!
    59  
    60  * Tools that parse and regenerate pointer files MUST preserve keys that they
    61  don't know or care about.
    62  * Run the `pointer` command to generate a pointer file for the given local
    63  file:
    64  
    65      ```
    66      $ git lfs pointer --file=path/to/file
    67      Git LFS pointer for path/to/file:
    68  
    69      version https://git-lfs.github.com/spec/v1
    70      oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
    71      size 12345
    72      ```
    73  
    74  * Run `pointer` to compare the blob OID of a pointer file built by Git LFS with
    75  a pointer built by another tool.
    76  
    77    * Write the other implementation's pointer to "other/pointer/file":
    78  
    79      ```
    80      $ git lfs pointer --file=path/to/file --pointer=other/pointer/file
    81      Git LFS pointer for path/to/file:
    82  
    83      version https://git-lfs.github.com/spec/v1
    84      oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
    85      size 12345
    86  
    87      Blob OID: 60c8d8ab2adcf57a391163a7eeb0cdb8bf348e44
    88  
    89      Pointer from other/pointer/file
    90      version https://git-lfs.github.com/spec/v1
    91      oid sha256 4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
    92      size 12345
    93  
    94      Blob OID: 08e593eeaa1b6032e971684825b4b60517e0638d
    95  
    96      Pointers do not match
    97      ```
    98  
    99    * It can also read STDIN to get the other implementation's pointer:
   100  
   101      ```
   102      $ cat other/pointer/file | git lfs pointer --file=path/to/file --stdin
   103      Git LFS pointer for path/to/file:
   104  
   105      version https://git-lfs.github.com/spec/v1
   106      oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
   107      size 12345
   108  
   109      Blob OID: 60c8d8ab2adcf57a391163a7eeb0cdb8bf348e44
   110  
   111      Pointer from STDIN
   112      version https://git-lfs.github.com/spec/v1
   113      oid sha256 4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
   114      size 12345
   115  
   116      Blob OID: 08e593eeaa1b6032e971684825b4b60517e0638d
   117  
   118      Pointers do not match
   119      ```
   120  
   121  ## Intercepting Git
   122  
   123  Git LFS uses the `clean` and `smudge` filters to decide which files use it.  The
   124  global filters can be set up with `git lfs install`:
   125  
   126  ```
   127  $ git lfs install
   128  ```
   129  
   130  These filters ensure that large files aren't written into the repository proper,
   131  instead being stored locally at `.git/lfs/objects/{OID-PATH}` (where `{OID-PATH}`
   132  is a sharded filepath of the form `OID[0:2]/OID[2:4]/OID`), synchronized with
   133  the Git LFS server as necessary.  Here is a sample path to a file:
   134  
   135      .git/lfs/objects/4d/7a/4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
   136  
   137  The `clean` filter runs as files are added to repositories.  Git sends the
   138  content of the file being added as STDIN, and expects the content to write
   139  to Git as STDOUT.
   140  
   141  * Stream binary content from STDIN to a temp file, while calculating its SHA-256
   142  signature.
   143  * Atomically move the temp file to `.git/lfs/objects/{OID-PATH}` if it does not
   144  exist, and the sha-256 signature of the contents matches the given OID.
   145  * Delete the temp file.
   146  * Write the pointer file to STDOUT.
   147  
   148  Note that the `clean` filter does not push the file to the server.  Use the
   149  `git push` command to do that (lfs files are pushed before commits in a pre-push hook).
   150  
   151  The `smudge` filter runs as files are being checked out from the Git repository
   152  to the working directory.  Git sends the content of the Git blob as STDIN, and
   153  expects the content to write to the working directory as STDOUT.
   154  
   155  * Read 100 bytes.
   156  * If the content is ASCII and matches the pointer file format:
   157    * Look for the file in `.git/lfs/objects/{OID-PATH}`.
   158    * If it's not there, download it from the server.
   159    * Write its contents to STDOUT
   160  * Otherwise, simply pass the STDIN out through STDOUT.
   161  
   162  The `.gitattributes` file controls when the filters run.  Here's a sample file that
   163  runs all mp3 and zip files through Git LFS:
   164  
   165  ```
   166  $ cat .gitattributes
   167  *.mp3 filter=lfs -text
   168  *.zip filter=lfs -text
   169  ```
   170  
   171  Use the `git lfs track` command to view and add to `.gitattributes`.