Published 2024-12-12.
Last modified 2024-12-30.
Time to read: 2 minutes.
git
collection.
Ever have git push
choke on a large file, for example, a file over 2 GB?
Wouldn't it be nice for the names of overly large files to automagically be added to .gitignore
instead of having to look up how git undo
works again?
I have maintained a series of streamlined commit
scripts for CVS, SVN and Git for
19 years.
I removed the CVS and SVN support several years ago, so only Git is supported now.
Originally written in bash, the current version is written in Ruby,
and published as a Ruby gem.
It uses the rugged
gem.
The Ruby language binding to libgit2
that rugged
provides
allows for more advanced features than
Git porcelain commands can offer.
High-Level Functionality
The commit
scripts perform the following:
git add
git commit
git push
Ruby Version
This is the latest version, and is the only version with the ability to handle large files. Using this version means you no longer have to worry about getting tangled up in undoing commits that failed because they included a large file.
The Ruby version has two important features that are possible because it examines the sizes of the files that are about to be added to the commit:
-
It ensures that files over 100 MB are added to
.gitignore
instead of causinggit push
to fail. A message is displayed, so the user is informed when large files are ignored. A future version will send those files to Git LFS instead, of the repository is configured for Git Large File Storage (LFS). - When the amount of data being added gets close to the maximum pack size of 2 GB, the commit and subsequent push are performed in stages. This trades off a perfectly groomed Git history for error-free Git operation and better manageability. This feature is especially useful for large files, such as those that require a Git LFS.
This version requires that Ruby is set up properly on your computer. If you do not want to set up Ruby, you can run the older bash version of commit instead, but that version does not include the large file handling features.
At present, Git LFS has not yet been implemented,
so the largest file that can be handled before it must be
included in .gitignore
is 100 MB.
I am working on it - 12 articles are in progress on this subject right now.
The mice are pedaling as fast as they can.
Installation
- Follow the directions in Setting Up a Ruby Development Environment.
-
Install the
rugged
gem. -
Install the
commit
gem:
Shell$ gem install commit
Help Message
$ commit -h Runs git commit without prompting for a message. Files larger than 2 GB are added to .gitignore instead of being committed. Usage: commit [options] [file...] Where options are: -a "tag message" -m "commit message" -v 0 # Minimum verbosity -v 1 # Default verbosity -v 2 # Maximum verbosity Examples: commit # The default commit message is just a single dash (-) commit -v 0 commit -m "This is a commit message" commit -v 0 -m "This is a commit message" commit -a 0.1.2
Source Code
The source code for the Ruby version of commit
is provided on GitHub.
The Walk Through Git’s Dirty Files section of the
Working With Git Repos Using Ruby's Rugged Gem article discusses how the central portion of the code works.
Sample Usage
$ commit Adding my_new_file.txt Not adding 'video.mp4' because the git file size limit is 2 GB, however the file is 2.12 GB. The file will be added to .gitignore.
Pushing to origin master
$ commit No changes were detected to this git repository.
Older Bash Version
The bash version installs more easily than the Ruby version,
but it cannot prevent big files from causing git push
to choke and fail.
Installation
-
Download the bash script to a directory on your
PATH
, for example,/usr/local/bin/
, the standard Ubuntu directory for user scripts~/.local/bin/
-
Make the script executable:
Shell$ chmod a+x /usr/local/bin/commit
Help Message
$ commit -h Runs git commit without prompting for a message. Usage: commit [options] [file...] Where options are: -a "tag message" -d # enables debug mode -m "commit message" Examples: commit # The default commit message is just a single dash (-) commit -m "This is a commit message" commit -a 0.1.2
Source Code
#!/bin/bash # Originally written 2005-09-05 by Mike Slinn for CVS, then SVN, then git. function help { echo "Runs git commit without prompting for a message." echo "Usage: commit [options] [file...]" echo " Where options are:" echo " -a \"tag message\"" echo " -d # enables debug mode" echo " -m \"commit message\"" echo "Examples:" echo " commit # The default commit message is just a single dash (-)" echo " commit -m \"This is a commit message\"" echo " commit -a 0.1.2" exit 1 } function isGitProject { cd "$( git rev-parse --git-dir )/.." || exit 2 [ -d .git ] } BRANCH="$(git rev-parse --abbrev-ref HEAD)" MSG="" while getopts "a:dhm:?" opt; do case $opt in a ) TAG="$OPTARG" git tag -a "$TAG" -m "v$TAG" git push origin --tags exit ;; d ) set -xv ;; m ) MSG="$OPTARG" ;; h ) help ;; \?) help ;; esac done shift "$((OPTIND-1))" for o in "$@"; do if [ "$o" == "-m" ]; then unset MSG; fi done if isGitProject; then if [ "$@" ]; then git add -A "$@" else git add -A . fi shift if [ "$MSG" == "" ]; then MSG="-"; fi git commit -m "$MSG" "$@" 3>&1 1>&2 2>&3 | sed -e '/^X11/d' | sed -e '/^Warning:/d' git push origin "$BRANCH" --tags 3>&1 1>&2 2>&3 | sed -e '/^X11/d' | sed -e '/^Warning:/d' else echo "Error: '$( pwd )' is not a git project" fi if [ -f 0 ]; then rm -f 0; fi