An open API service indexing awesome lists of open source software.

https://github.com/sabicalija/git-lfs-intro

git-lfs introduction
https://github.com/sabicalija/git-lfs-intro

git git-lfs

Last synced: 8 months ago
JSON representation

git-lfs introduction

Awesome Lists containing this project

README

          

= git-lfs tutorial
Alija Sabic, link:mailto:sabic.alija@gmail.com?subject=GitHub:Β git-lfs-intro[sabic.alija@gmail.com]

:icons: font
:icon-set: font

// Set new URI for reference to FontAwesome CSS
:iconfont-cdn: //maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.mi$

:caution-caption: ☠
:important-caption: ❗
:note-caption: πŸ›ˆ
:tip-caption: πŸ’‘
:warning-caption: ⚠

:toc: left
:toc2:
:docinfo2:
// article, book or manpage
:doctype: article
:source-highlighter: prettify

== Setup git repository with *git-lfs*

This repository was setup using following commands:

. Create a directory
+
.Create directory
[subs="verbatim,macros"]
----
pass:q[~$ *mkdir* git-lfs-intro]
pass:q[~$ *cd* git-lfs-intro]
----

. Initialize git and git-lfs
+
[CAUTION]
=====
`*git lfs install* --local --skip-smudge` (explained below) adds configuration locally (folder).
However, the local configuration file (`.git/config`) can't be tracked and hence, uploaded to a remote repository.

Use `*git lfs install* --skip-smudge` to prevent LFS from downloading or cloning files (globally) unless explicitly specified.

[WARNING]
====
`--skip-smudge` adds following entries to the global git config at `~/.gitconfig`:

`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.required=true +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.clean=git-lfs clean -- %f +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.smudge=git-lfs smudge --skip -- %f +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.process=git-lfs filter-process --skip +
=====
+
[subs="verbatim,macros"]
.Initialize git and git-lfs
----
pass:q[~/git-lfs-intro$ *git init*]
pass:q[Initialized empty Git repository in ~/git-lfs-intro/.git/]

~/git-lfs-intro$ pass:q[*git lfs install*] --local --skip-smudge <1> <2>
pass:q[Updated git hooks.]
pass:q[Git LFS initialized.]

~/git-lfs-intro$ pass:q[*git lfs track*] '*.pdf' <3>
pass:q[Tracking "*.pdf"]
----
<1> `--local` sets the "lfs" smudge and clean filters in the local repository's git config, instead of the global git config (`~/.gitconfig`).
<2> `--skip-smudge` skips automatic downloading of objects on clone or pull. This requires a manual "git lfs pull" every time a new commit is checked out on your repository.
<3> `*git lfs track*` starts tracking given pattern(s) through git LFS.

+
[NOTE]
====
`--local` in combination with `--skip-smudge` adds following entries to the local git config at `.git/config`:

=====
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.smudge=git-lfs smudge --skip -- %f +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.process=git-lfs filter-process --skip +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.required=true +
`.git/config` {nbsp} {nbsp} {nbsp} filter.lfs.clean=git-lfs clean -- %f +
=====

====

. Create 'git-lfs' man-pages pdfs
+
.Create data to track with LFS
[subs="verbatim,macros"]
----
pass:q[~/git-lfs-intro$ *apropos*. | *awk* '{print $1}' | *grep* git-lfs | while read in; do *man* -t "$in" | *ps2pdf* - "$in".pdf; done]
pass:q[~/git-lfs-intro$ *ls*]
pass:q[git-lfs-checkout.pdf git-lfs-config.pdf git-lfs-fetch.pdf git-lfs-install.pdf git-lfs-logs.pdf]
pass:q[git-lfs.pdf git-lfs-post-merge.pdf git-lfs-pull.pdf git-lfs-status.pdf git-lfs-unlock.pdf]
pass:q[git-lfs-clean.pdf git-lfs-env.pdf git-lfs-filter-process.pdf git-lfs-lock.pdf git-lfs-ls-files.pdf]
pass:q[git-lfs-pointer.pdf git-lfs-pre-push.pdf git-lfs-push.pdf git-lfs-track.pdf git-lfs-untrack.pdf]
pass:q[git-lfs-clone.pdf git-lfs-ext.pdf git-lfs-fsck.pdf git-lfs-locks.pdf git-lfs-migrate.pdf]
pass:q[git-lfs-post-checkout.pdf git-lfs-prune.pdf git-lfs-smudge.pdf git-lfs-uninstall.pdf git-lfs-update.pdf]
----

. Add files and `.gitattributes` and commit
+
.Commit files
[subs="verbatim,macros"]
----
pass:q[~/git-lfs-intro$ *git add* .gitattributes "*.pdf"]
pass:q[~/git-lfs-intro$ *git commit* -m "Initial commit"]
----

== Clone repository

To prevent lfs from downloading or cloning LFS tracked files _globally_ enter:

.Configure skipping LFS tracked files
[subs="verbatim,macros"]
----
pass:q[$ *git lfs install* --skip-smudge]
----

This will prevent downloading lfs files when cloning repositories.
If you `clone` this repository now, by entering the command below, git will download only a _pointer_ to the lfs file (named just as the original file).

To clone this LFS repository enter:
[subs="verbatim,macros"]
.Clone the repository
----
pass:q[~/temp$ *git clone* https://github.com/sabicalija/git-lfs-intro.git]
----

/////
[NOTE]
=====
This repository is set up with `--local --skip-smudge`.

Files tracked with git LFS will not be downloaded or cloned. +
Use `git lfs pull` or `git lfs pull --include=filename` to pull all or single files, respecitively.
=====
/////

== Load lfs file

You can download all or single files by entering following command:

* *Single file*
+
[subs="verbatim,macros"]
.Pull single LFS tracked file
----
pass:q[~/temp/git-lfs-intro$ *git lfs pull* --include=filename]
----
+
To download the main git-lfs manpage pdf enter
+
[subs="verbatim,macros"]
.Pull file "git-lfs.pdf"
----
pass:q[~/temp/git-lfs-intro$ *git lfs pull* --include="git-lfs.pdf"]
pass:q[Git LFS: (1 of 1 files) 18.97 KB / 18.97 KB]
----

+
[NOTE]
=====
Stage the newly downloaded file. This gives git the chance, to see that the "new" file is actually already tracked by git-lfs.

[subs="verbatim,macros"]
.Restore respository state
----
pass:q[~/temp/git-lfs-intro$ *git add* git-lfs.pdf]
----

or reset the repository by entering:
[subs="verbatim,macros"]
.Restore (reset) repostiory state
----
pass:q[~/temp/git-lfs-intro$ *git reset* HEAD .]
----
=====

* *All files*
+
[subs="verbatim,macros"]
.Pull all LFS tracked files
----
pass:q[~/temp/git-lfs-intro$ *git lfs pull*]
pass:q[Git LFS: (29 of 29 files) 475.39 KB / 475.39 KB]
----

== Convert lfs file to pointer

In case you don't need the original binary anymore, you can convert it back to a pointer file.
To achieve this enter following commands:

[subs="verbatim,macros"]
.Convert LFS tracked binary to pointer
----
pass:q[~/temp/git-lfs-intro$ *git lfs pointer* --file=filename]
pass:q[Git LFS pointer for filename]

pass:q[version https://git-lfs.github.com/spec/v1]
pass:q[oid sha256:dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]
pass:q[size 19425]
----

This will output the generated pointer to the `stdout`.
_Copy_ the content to a new file, _delete_ the downloaded LFS file, and rename the newly created pointer file using it's original name.
Now, stage the file again, to restore the repository's state.

To convert the main `git-lfs.pdf` manpage pdf to a pointer file enter:

[subs="verbatim,macros"]
.Convert "git-lfs.pdf" to pointer
----
pass:q[~/temp/git-lfs-intro$ *git lfs pointer* --file="git-lfs.pdf" > git-lfs.pdf.pt]
pass:q[Git LFS pointer for git-lfs.pdf]

pass:q[~/temp/git-lfs-intro$ *rm* git-lfs.pdf]
pass:q[~/temp/git-lfs-intro$ *mv* git-lfs.pdf.pt git-lfs.pdf]
pass:q[~/temp/git-lfs-intro$ *git add* git-lfs.pdf]
----

== Delete a lfs file

[CAUTION]
=====
The files exchanged by a pointer file are removed from the repository, but not from disk.
=====

To remove the original binary (tracked by git LFS) locate the file you wish to remove at `.git/lfs/objects` and delete it there.

NOTE: Now, if you want to get the binary again, simply enter `git lfs pull --include=filename`.

You can use the `oid` from the pointer file, to print the location of the binary file to `stdout` or delete the file "automatically".

.Read the oid from pointer file
[subs="verbatim,macros"]
-----

pass:q[~/temp/git-lfs-intro$ *cat* git-lfs.pdf]
pass:q[version https://git-lfs.github.com/spec/v1]
pass:q[oid sha256:dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]
pass:q[size 19425]

pass:q[~/temp/git-lfs-intro$ *cat* git-lfs.pdf | *grep* oid]
pass:q[oid sha256:dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]

pass:q[~/temp/git-lfs-intro$ *cat* git-lfs.pdf | *grep* oid | *cut* -d ":" -f 2]
pass:q[dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]

-----

.Print binary file location to terminal
[subs="verbatim,macros"]
-----
pass:q[~/temp/git-lfs-intro$ *find* . | *grep* $(*cat* git-lfs.pdf | *grep* oid | *cut* -d ":" -f 2)]
pass:q[./.git/lfs/objects/dc/26/dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]
-----

You could also use following short-cut, but be carefull.
The commands need to be entered subsequently.

.Print binary file location to terminal (short cut)
[subs="verbatim,macros"]
-----
pass:q[~/temp/git-lfs-intro$ *cat* git-lfs.pdf | *grep* oid | *cut* -d ":" -f 2]
pass:q[dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]

pass:q[~/temp/git-lfs-intro$ *find* . | *grep* $(!!)]
pass:q[find . | grep $(cat git-lfs.pdf | grep oid | cut -d ":" -f 2)]
pass:q[./.git/lfs/objects/dc/26/dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]
-----

[NOTE]
=====
The location of the binary, or the names of the folders where it is stored matches a pattern of the oid hash value.
=====

.Delete binary file automatically
[subs="verbatim,macros"]
-----
pass:q[~/temp/git-lfs-intro$ *rm* $(*find* . | *grep* $(*cat* git-lfs.pdf | *grep* oid | *cut* -d ":" -f 2))]
-----

or with a short cut, just like above:

.Delete binary file automatically (short cut)
[subs="verbatim,macros"]
-----
pass:q[~/temp/git-lfs-intro$ *cat* git-lfs.pdf | *grep* oid | *cut* -d ":" -f 2]
pass:q[dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]

pass:q[~/temp/git-lfs-intro$ *find* . | grep $(!!)]
pass:q[find . | grep $(cat git-lfs.pdf | grep oid | cut -d ":" -f 2)]
pass:q[./.git/lfs/objects/dc/26/dc26a22ac0dceb6ce27dd870a1a9f6791f45d4fbc75499093779de3d30b7b5ba]

pass:q[~/temp/git-lfs-intro$ *rm* $(!!)]
pass:q[rm $(find . | grep $(cat git-lfs.pdf | grep oid | cut -d ":" -f 2))]

~/temp/git-lfs-intro$
-----