Prerequisites: having Git installed. For installation and configuration instruction, please refer to Installing Git.
Overview and Online Documentation
http://rogerdudler.github.io/git-guide/: The simple guide
http://git-scm.com/documentation: Very complete documentation (reference, cheat sheets, books).
https://git.wiki.kernel.org/index.php/InterfacesFrontendsAndTools: Interfaces, frontends and tools listing.
Git Commands
Most Useful Commands
To clone a repository, do:
git clone git://github.com/nuxeo/nuxeo.git
To retrieve remote changes, do:
git fetch
To update your repository according to remote changes, do:
git pull --rebase
This is equivalent to:
git fetch && git rebase
To view the current status of your repository, do:
git status
To commit local changes to a file, do:
git commit -m "NXP-xxxx: my commit message" myfile.txt
or, to commit all modified files at once:
git commit -m "NXP-xxxx: my commit message" -a
To push those changes remotely, do:
git push
To view the changeset of a given commit, do:
git show <commit_identifier>
To apply a given changeset to another branch, do:
git cherry-pick <commit_identifier>
To edit the last commit:
git commit --amend [...]
Suppose you made a mistake and made a commit with a bad content, and you forgot to reference the JIRA issue in the message:
echo "my awesome content, i hope i did not make any missstake" > some_file.txt
git commit -m "adding my awesome information" some_file.txt
To fix it just edit the file to replace the faulty line:
echo "my awesome content, i hope i did not make any mistake" > some_file.txt
Then redo the commit with the right commit message:
git commit --amend -m "NXP-xxxx: adding my awesome information" some_file.txt
To undo the last commit (without having pushed anything to public repo), do:
# Cancel last commit but keep changes to be commited
git reset --soft HEAD~
# Cancel last commit and keep changes but not marked for commit
git reset --mixed HEAD~
# Cancel last commit and discard changes
git reset --hard HEAD~
To merge a branch
git merge <branch> [--no-ff]
To rebase the current branch with its upstream branch The local commits can be reworked (squash, edit, move...) during the interactive mode.
git rebase [-i] <upstream>
To revert some changes
git revert <commit>...
Useful Aliases
# Before Git 1.8.3 (May 24, 2013), remove the occurrences of `%C(auto)` or replace them with fixed colors such as `%Cgreen`, `%C(bold blue)`...
# Simple shortcuts
ls = "ls-tree --name-only"
ll = "ls-tree -l"
st = status -sb
ci = commit
co = checkout
br = branch
branches = branch -a
di = diff
dic = diff --staged
id = show -s --pretty=format:'%C(auto)%h%d'
rollback = git reset --soft HEAD^
# Because "pull --rebase" and "rebase" are finally more used than "pull" and "merge"
pullr = "!git fetch \"$@\" && git rebase --autostash @{push}"
# Because we sometimes really want a merge
pullnor = pull --no-rebase
# Amend a changeset (less powerful but quicker and easier than the interactive rebase)
fix = "!_() { c=$(git rev-parse $1) && git commit --fixup $c && git -c core.editor=cat rebase -i --autosquash --keep-empty --autostash $c~; }; _"
# Using ref to upstream branch available since Git 1.7 (@{upstream})
# Incoming changes
in = "!git remote update -p; git log ..@{u}"
# Outgoing changes
out = log @{u}..
# Outgoing changes on all remote-tracked branches
outall = log --branches --not --remotes=origin
# Branch fork point (aka oldest ancestor)
oldest-ancestor = !bash -c 'diff -u1 <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\"' -
# Various log display
lg = log --graph --pretty=format:'%C(auto)%h -%d %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
glog = log --graph --abbrev-commit --date=relative
logone = log --pretty=format:'%C(auto)%m %h %Cgreen%ad %C(blue)%<(20)%aN %Creset%s %N %C(auto)%d' --left-right --cherry-pick --date=short
# Latests changes since last pull
lc = log --pretty=oneline --abbrev-commit --graph --decorate ORIG_HEAD.. --stat --no-merges
# Latest updated branches
latest = for-each-ref --count=10 --sort=-committerdate --format='%(committerdate:short) %(refname:short)'
# Latest updated local branches
latestl = for-each-ref --count=10 --sort=-committerdate refs/heads --format='%(committerdate:short) %(refname:short)'
# Commits per user
who = "shortlog -ne --format='%h %s'"
# LoC per user (BSD)
authorship = "!git ls-files -z|xargs -0 -n1 -E'\n' -J {} git blame --date short -wCMcp '{}'| perl -pe 's/^.*?\\((.*?) +\\d{4}-\\d{2}-\\d{2} +\\d+\\).*/\\1/'| sort | uniq -c | sort -rn"
# LoC per user (GNU)
authorship = "!git ls-files -z|xargs -0 -n1 -E'\n' | git blame --date short -wCMcp -- | perl -pe 's/^.*?\\((.*?) +\\d{4}-\\d{2}-\\d{2} +\\d+\\).*/\\1/'| sort | uniq -c | sort -rn"
rbranch-rename = "!_() { [ \"$#\" -lt 2 ] && echo 'Usage: rbranch-rename [remote] old_branch_name new_branch_name' && exit 1; \
if [ \"$#\" -gt 2 ]; then REMOTE=$1; shift; else REMOTE=origin; fi; git push $REMOTE $REMOTE/$1:refs/heads/$2 :$1; }; _"
# See https://gist.github.com/jcarsique/24f8dd46d176bb67253e for more aliases.
Command Mappings for a Mercurial User
Here are simple commands and correspondences between Mercurial (we were used to) and Git:
See Git Hg rosetta stone.
git show ref[:file]...
git cherry-pick <commit>...
git reset --soft HEAD~1
Nuxeo Common Usage and Best Practices
Convenient Shell Scripts
At root of the Nuxeo Platform, the script scripts/gitfunctions.sh provides some convenient Shell functions for use on Nuxeo projects version controlled under Git.
source <(curl -s https://raw.githubusercontent.com/nuxeo/nuxeo/stable/scripts/gitfunctions.sh)
# or source /path/to/nuxeo/scripts/gitfunctions.sh
gitf -?
Usage: gitf [-r] [-q] [-h|-?] <[--] Git instructions>
Recursively executes the given Git command on the current and its direct children Git repositories.
-h,-? Show this help message and exit.
-q Quiet mode (default is verbose).
-r The recurse will continue on all children Git repositories.
-- Optional separator between the options and the instructions which may start with a dash.
gitfa -?
Usage: gitfa [-q] [-h|-?] <[--] Git instructions>
Recursively executes the given Git command on the current, its direct children Git repositories and browse the child Maven modules of $PARENT_MODULES directories.
-h,-? Show this help message and exit.
-q Quiet mode (default is verbose).
-- Optional separator between the options and the instructions which may start with a dash.
PARENT_MODULES Environment variable. Defaults to 'addons addons-core' if not set.
LIST_<parent module> Environment variable that can be set to restrict the children modules to a fixed list. For instance: LIST_ADDONS_CORE="nuxeo-core-storage-marklogic" or LIST_ADDONS="nuxeo-shell nuxeo-quota".
shr -?
Usage: shr [-a] [-q] [-h|-?] <[--] Shell instructions>
Recursively executes the given Shell command on the current and its direct children Git repositories.
-h,-? Show this help message and exit.
-a The recurse will continue on the child Maven modules of $PARENT_MODULES directories.
-q Quiet mode (default is verbose).
-- Optional separator between the options and the instructions which may start with a dash.
PARENT_MODULES Environment variable. Defaults to 'addons addons-core' if not set.
LIST_<parent module> Environment variable that can be set to restrict the children modules to a fixed list. For instance: LIST_ADDONS_CORE="nuxeo-core-storage-marklogic" or LIST_ADDONS="nuxeo-shell nuxeo-quota".
Main Rules and Good Practices
- Do not rewrite Git history on development and maintenance branches.
- Branch naming
- Strictly follow Nuxeo naming policy for branches and tags
- Tags are named
release-<semver>
- Create working branches named as
<TYPE>-<REFERENCE>-<SHORT_DESC>
:fix-NXP-1234-some-expected-behavior
or "feature-NXP-1234-some-new-feature
- Use the same name for a local branch than its corresponding remote branch.
- Commits
- Reference JIRA issues in the head of commit comment.
- Comment with a first short line, then add optionally an empty line, then as much details as you consider useful
- When squashing other author's commits, typically during a PR, mentions are welcome in the commit comment body.
For instance:
Co-authored-by: @username <[email protected]> Reviewed-by: @reviewer_username <[email protected]>
- Commit as a valid author (i.e. "Firstname Lastname \
" with the email address being configured in your GitHub account, no matter if it's public or private).
- Merging work
- Rebase against the upstream then ask for code review with a Pull Request
- Consider reworking the branch before review: isolate code cleanup, squash related commits, etc.
- When your work is achieved, rebase again then merge the branch (see Isolated testing with ondemand-testandpush jobs).
- Unique and very few commits can be merged as fast-forward, else creating a merge commit is recommended for readability.
- Optionally delete the remaining branch, else it will be automatically done after a short while once the related JIRA ticket is resolved.
Advanced Usage and Specific Use Cases
Some Useful Commands
git remote add origin [email protected]:nuxeo/nuxeo.git
git push -u origin master
# Rename local branch
git branch -m <oldname> <newname>
# Rename remote branch. See 'rbranch-rename' alias.
git push origin origin/<oldname>:refs/heads/<newname> :<oldname>
git branch -d branch_name
# Old way
git push origin :branch_name
# New way
git push --delete branch_name
git remote prune <remote_repository_alias>
git tag -a <tag_name> <sha1> -m"<tag_message>"
git tag -d <tag_name>
git push <remote_repository_alias> <tag_name>
git push <remote_repository_alias> :refs/tags/<tag_name>
Checking Out Pull Request Locally
Sometimes, a pull request needs local changes (to resolve merge or rebase conflicts, to fix or complete the commits, to run tests...). You can get GitHub instructions at the bottom of the pull request page, near the merge button: click on "command line instructions". Here is a summary of those instructions and some alternate commands.
Let's assume that the user name is contributor
and he's issuing the pull request number #67
from the branch fix-NXP-12345-some-stuff
in his forked repository https://github.com/contributor/nuxeo.git to branch master in http://github.com/nuxeo/nuxeo.git.
As a Simple Patch
For simple cases, you can locally apply the pull-request as a patch (see GitHub documentation):
git checkout -b fix-NXP-12345-some-stuff master
curl -L https://github.com/nuxeo/nuxeo/pull/67.patch | git am
As a Branch
# Fetch details are needed only if you didn't configure remote.origin.fetch at global or repository level
git fetch origin +pull/67/head:pull/67
# Pull requests can be checked out like a standard branch
git checkout pull/67
# You can list the modified files and open them in your preferred IDE (here using Eclipse for a PR on master)
git diff origin/master --name-only --format="" --diff-filter=d | xargs eclipse
Fetch the Pull Request Changes
git checkout -b fix-NXP-12345-some-stuff master
git pull origin pull/67/head
Fetch the Pull Request Changes (Alternative)
git checkout -b fix-NXP-12345-some-stuff master
git pull https://github.com/contributor/nuxeo.git fix-NXP-12345-some-stuff
Removing Content From Git History
This action modifies the Git history! All commits previously containing the unwanted files will be rewritten.
git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch files_to_remove' HEAD
git rm -r --cached files_to_remove
git commit
See also BFG Repo-Cleaner which provides very much faster and somehow simpler (user-friendlier) commands for a few high-level features.
Converting a Mercurial Repository to a Git Repository
The conversion makes use of hg-fast-export
:
git clone git://repo.or.cz/fast-export.git
git -C fast-export checkout v180317 # Backward compatibility with Mercurial < 4.6
git init new-git-repository
cd new-git-repository
/path/to/fast-export/hg-fast-export.sh -r /path/to/old-hg-repository
More info in this blog post.
for i in `git branch | grep -v master`; do git log -1 --pretty="format:$i%x09%s%n" $i | grep '[Tt]ag[g ]' | cut -f 1; done | while read i; do (git branch -d $i||true); done
git checkout master # the current working branch is out of date after conversion
Notes/tips:
"default" Mercurial branch will be mapped to "master" Git branch. If you were not using the "default" branch but for instance "5.5" or if the "master" should start pointing at "5.5", do:
git checkout -B master 5.5 # Optionally commit the new branch creation after having updated its content (see below).
Moving .hgignore to .gitignoregit mv .hgignore .gitignore # Edit and remove non-Git configuration from .gitignore, such as "syntax:glob". git commit -m"NXP-XXXX: migrate from Hg to Git" -a
Adding remote repository; pushing branches and tagsgit remote add origin [email protected]:nuxeo/some_repository.git git push --all origin git push --tags git branch --set-upstream-to=origin/master master
- Set the Mercurial repository as deprecated.
- Activate GitHub hooks after having pushed the migration.
Extracting Part(s) of an Existing Repository to a New Repository
Clone the repository, then:
For one directory:
git filter-branch --subdirectory-filter dir-to-extract --tag-name-filter cat --prune-empty -- --all
For multiple directories:
git filter-branch --index-filter 'git rm --ignore-unmatch --cached -qr -- . && git reset -q $GIT_COMMIT -- dir1-to-extract dir2-to-extract dir3-to-extract' --tag-name-filter cat --prune-empty -- --all
Finally:
for i in $(git branch -r | sed "s/.*origin\///"); do git branch -t $i origin/$i; done
git remote rm origin
git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --aggressive --prune=now
The new repository is ready for push.
You can remove the extracted directory from the old repository (git rm ...
).
Merging Two Repositories
See for a workaround to the issue https://github.com/robinst/git-merge-repos/issues/3
Prepare script is available: https://gist.github.com/jcarsique/29ca0df9166926183e2f
If you work on a local clone, you must remove all local branches or ensure that they are up-to-date. See http://aanandprasad.com/git-up/.
There are two main merging solutions:
- Merge history for paths: the commits are rewrote so that everything is as if the two repositories were merged since their beginning.
- Merge branch heads: the commit IDs are unchanged. The branches existing in the two repositories are merged at their HEAD. History for each repository is kept unchanged.
On open source projects, with commit IDs referenced from public issues, the latter solution is preferred.
Clone https://github.com/robinst/git-merge-repos
Run ./run.sh /path/to/repo1:. /path/to/repo2:.
.
The result is in a sub-directory named merged-repo
. Add the remote and push the branches without force option, then the tags.
# Update .gitignore and remove those in sub-directories
git remote add origin ...
# Optimize repository
git reflog expire --expire=now --all
git gc --aggressive --prune=now
git fsck
# Check outgoing changes
git push --all -n origin 2>&1 | grep -E "deleted|rejected"
# Merge remote changes per branch if necessary; see also git-up command to update all local branches
# Push changes
git push --all origin
git push --tags -f origin
If you need to rebase
(or pull --rebase
) some local branch (after repositories merge), then you must use the rebase --preserve-merges
option (or pull --rebase=preserve
).
Please disable GitHub email notifications before push and re-enable after push.
After the merge, the Jenkins job running on your repository will probably add comments on JIRA issues referenced in the rewritten history: these comments could be nice to have, but if you do not want them, you should disable the "Update relevant JIRA issues" options on the job, at its first run after the merge.
Using Another Local Clone as Staging
You may want to push from merged-repo
to a local clone of foo
:
cd /path/to/foo
git checkout --detach
git fetch --tags /path/to/merged-repo
cd /path/to/merged-repo
git push --all /path/to/foo
The foo
repository is now ready for push to remote. Of course, you will often want to finalize the merge first (add modules to a common POM, remove useless .gitignore
...)
If you had local changes in foo
, then you may encounter conflicts at push:
To /path/to/foo ! [rejected] some-conflicting-branch -> some-conflicting-branch (fetch first) error: failed to push some refs to '/path/to/foo' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
In that case, you will have to manually solve the conflict: choosing the branch to keep, optionally merging/cherry-picking some commits...
For instance, to forget the local changes:
cd /path/to/foo
git fetch -f /path/to/merged-repo some-conflicting-branch:some-conflicting-branch
Walking Through History After Merge
After merge, the resulting repository will have two distinct history trees that converge into the future unique history. The drawback is that it is not easy to browse the old history of the imported repository.
In the following example, we have merged a repository B
under a new folder repo-b/
of the repository A
.
$ tree -L 2
.
├── repo-b/ # Imported content of B, shifted.
│ ├── pom.xml
│ └── ...
├── pom.xml
└── ... # Original content of A, unchanged.
$ git show --summary
commit eb9a482ef762372b7ebc868045aa210a8b553d24
Merge: cafb9624c 943add6f0
Merge branch 'master' from multiple repositories
Repositories:
A
B
# cafb9624c is the HEAD of the original content (repo A)
# 943add6f0 is the HEAD of the imported content (repo B)
$ git log --graph --pretty=format:'%h -%d %s' --simplify-by-decoration
* eb9a482ef - (HEAD -> master) Merge branch 'master' from multiple repositories
|\
| * 3d3ebc4a0 - first commit on B
* cafb9624c - (origin/master) last commit on A
Here are some history browsing Git commands with their behavior regarding the "old" history (before the merge of repositories)
# To walk through both trees, use --follow starting from a commit post-merge
$ git log --oneline --follow -- pom.xml|grep 3d3ebc4a0
3d3ebc4a0 NXP-14853: First commit.
$ git log --oneline --follow -- repo-b/pom.xml|grep 3d3ebc4a0
3d3ebc4a0 NXP-14853: First commit.
$ git log --oneline --follow -- repo-b/pom.xml|wc -l
476
$ git log --oneline --follow -- pom.xml|wc -l
476
# To walk through the old trees, use a pre-merge commit: cafb9624c for repo A and 943add6f0 for repo B
$ git log --oneline cafb9624c --follow -- pom.xml|wc -l
445
$ git log --oneline 943add6f0 --follow -- pom.xml|wc -l
30
# 3d3ebc4a0 is not in the old tree A but in tree B
$ git log --oneline cafb9624c --follow -- pom.xml|grep 3d3ebc4a0
$ git log --oneline 943add6f0 --follow -- pom.xml|grep 3d3ebc4a0
3d3ebc4a0 NXP-14853: First commit.
Normalize End of Lines
Per-Branch Normalization
Git allows to apply automatic checks on end of lines depending on the file attributes (see http://git-scm.com/docs/gitattributes/).
# End-of-line conversion like in https://raw.githubusercontent.com/nuxeo/nuxeo/master/.gitattributes
echo "*.sh eol=lf" >>.gitattributes
echo "*.bat eol=crlf" >>.gitattributes
rm .git/index
git reset
git add -u
git add .gitattributes
git ci -m'Introduce end-of-line normalization'
That will automatically convert end of lines in *.sh
and *.bat
files in the branch containing the .gitattributes
file.
Per-Repository Normalization
You can set such an automatic conversion on all branches with the following:
echo "*.sh eol=lf" >>.git/info/attributes
echo "*.bat eol=crlf" >>.git/info/attributes
The .git/info/attributes
file is not committed but local to the repository.
Note however that this configuration will likely cause conflicts on merge (or rebase). In such a case, the easier solution is to temporarily rename .git/info/attributes
, end the merge (or rebase), then put back the attributes file.
Global Enforcement
See Installing Git / Git Global Configuration for a setting core.autocrlf
, core.safecrlf
... parameters to enforce the EOL checks on all Git repositories.
Useful Tools
The following commands are very useful for dealing with EOL: file
, unix2dos
and dos2unix
.
Diff on Binary Files
It is possible to tell Git how to convert binary data to a text format that can be compared via the normal diff.
PNG and DOCX
Here is a sample configuration for .docx
and .png
files (from http://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes):
- Install
docx2txt
andexiftool
Create a
docx2txt
wrapper script and mark it as executable:~/bin/docx2txt#!/bin/bash docx2txt.pl $1 -
chmod a+x ~/bin/docx2txt
Tell Git which binary files to convert:
Use
.git/info/attributes
if you don’t want the attributes file committed with your project, else use.gitattributes
.git/info/attributes or .gitattributes*.docx diff=word *.png diff=exif
Tell Git how to convert:
git config --global diff.word.textconv docx2txt git config --global diff.exif.textconv exiftool
Here are the outputs with and without the above Git attributes:
$ git show 281e4f470bb0e8fc1d43b9350e72063030d15f66 --oneline -- nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx
281e4f4 NXP-9331: Get rid of cyclic dependency by isolating tests in nuxeo-core-convert-plugins-test
diff --git a/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx b/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx
new file mode 100644
index 0000000..ad1b4af
Binary files /dev/null and b/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx differ
$ git show 281e4f470bb0e8fc1d43b9350e72063030d15f66 --oneline -- nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx
281e4f4 NXP-9331: Get rid of cyclic dependency by isolating tests in nuxeo-core-convert-plugins-test
diff --git a/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx b/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx
new file mode 100644
index 0000000..ad1b4af
--- /dev/null
+++ b/nuxeo-core-convert-plugins-test/src/test/resources/test-docs/hello.docx
@@ -0,0 +1 @@
+Hello world !
$ git show 025a2bda872a228d2ee07b8830e2472088ae43a5 --oneline -- nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
025a2bd NXP-15048: Update logo, flavors and login page for new branding
diff --git a/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png b/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
index a28e89d..b38c0e0 100644
Binary files a/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png and b/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png differ
$ git show 025a2bda872a228d2ee07b8830e2472088ae43a5 --oneline -- nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
025a2bd NXP-15048: Update logo, flavors and login page for new branding
diff --git a/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png b/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
index a28e89d..b38c0e0 100644
--- a/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
+++ b/nuxeo-platform-webapp/src/main/resources/web/nuxeo.war/img/nuxeo_logo.png
@@ -1,15 +1,15 @@
ExifTool Version Number : 9.69
-File Name : QoqEHp_nuxeo_logo.png
+File Name : EYPa9v_nuxeo_logo.png
Directory : /tmp
-File Size : 4.9 kB
+File Size : 8.0 kB
File Modification Date/Time : 2015:01:30 15:39:32+01:00
File Access Date/Time : 2015:01:30 15:39:32+01:00
File Inode Change Date/Time : 2015:01:30 15:39:32+01:00
File Permissions : rw-------
File Type : PNG
MIME Type : image/png
-Image Width : 236
-Image Height : 52
+Image Width : 227
+Image Height : 40
Bit Depth : 8
Color Type : RGB with Alpha
Compression : Deflate/Inflate
@@ -18,8 +18,8 @@ Interlace : Noninterlaced
Software : Adobe ImageReady
XMP Toolkit : Adobe XMP Core 5.3-c011 66.145661, 2012/02/06-14:56:27
Creator Tool : Adobe Photoshop CS6 (Macintosh)
-Instance ID : xmp.iid:659F991F084311E4A7D7A0843068B9FA
-Document ID : xmp.did:659F9920084311E4A7D7A0843068B9FA
-Derived From Instance ID : xmp.iid:659F991D084311E4A7D7A0843068B9FA
-Derived From Document ID : xmp.did:659F991E084311E4A7D7A0843068B9FA
-Image Size : 236x52
+Instance ID : xmp.iid:394FADE624C911E48679ADB8C76F05E6
+Document ID : xmp.did:394FADE724C911E48679ADB8C76F05E6
+Derived From Instance ID : xmp.iid:EBA4519B23A511E48679ADB8C76F05E6
+Derived From Document ID : xmp.did:EBA4519C23A511E48679ADB8C76F05E6
+Image Size : 227x40
ZIP
```
git config --global diff.zip.textconv "unzip -c -a"
echo "*.zip diff=zip" >> .gitattributes
```
Git Large File Storage
GitHub will warn you when pushing files larger than 50 MB. You will not be allowed to push files larger than 100 MB. Actually, storing binaries in Git is a bad practice. The usage pattern should be reviewed in order to fetch external data from Nexus for instance.
However, if you think you legitimately need to store (fat) binaries in Git, then there are solutions reducing the inconveniences: git-annex
, git-fat
, Git LFS
, git-bigfiles
, git-media
, git-bigstor
, git-sym
... The three firsts being the most promising.
Nuxeo choose Git LFS: https://git-lfs.github.com/
Configuration
The following should avoid running git lfs install
on each Git repository.
git config --global filter.lfs.required true
git config --global filter.lfs.clean "git-lfs clean %f"
git config --global filter.lfs.smudge "git-lfs smudge %f"
Batch Download
LFS has the batch mode for downloading files from a server. But it does not work on clone and checkout due to limitation of Git’s smudge filters. You can skip LFS’s smudge filter and fetch LFS objects on demand:
# change the smudge filter configuration
git config --global filter.lfs.smudge "git-lfs smudge --skip %f"
# check
git lfs env
# fetch LFS objects after checkout or clone:
git lfs fetch # downloads objects with batch mode
git lfs checkout # changes objects to binary files
Issues
Commands naming is not consistent between Git and Git LFS!
Git LFS does not seem very stable yet and it has some inconsistencies with Git when mixing LFS and Git-native binaries. You may encounter modified or untracked binaries while you didn't change them.
See https://shuhrat.github.io/programming/git-lfs-tips-and-tricks.html, https://github.com/tarmolov/git-hooks-js to configure and share a safety pre-commit hook.
See https://github.com/bozaro/git-lfs-migrate to migrate an existing repository.