Git::Bunch - Manage gitbunch directory (directory which contain git repos)
This document describes version 0.50 of Git::Bunch (from Perl distribution Git-Bunch), released on 2015-11-05.
To check the status of bunch (will do a 'git status' for each git repo inside the bunch and report which repos are 'unclean', e.g. needs commit, has untracked files, etc):
% gitbunch check ~/repos
To synchronize bunch to another (will do a 'git pull/push' for each git repo, and do an rsync for everything else):
% gitbunch sync ~/repos /mnt/laptop/repos
A gitbunch or bunch directory is just a term I coined to refer to a directory which contains, well, a bunch of git repositories. It can also contain other stuffs like files and non-git repositories (but they must be dot-dirs). Example:
repos/ -> a gitbunch dir proj1/ -> a git repo proj2/ -> ditto perl-Git-Bunch/ -> ditto ... .foo/ -> a non-git dir README.txt -> file
A little bit of history: after git got popular, in 2008 I started using it for software projects, replacing Subversion and Bazaar. Soon, I moved everything to git: notes & writings, Emacs .org agenda files, configuration, even temporary downloads/browser-saved HTML files. Currently, except large media files, all my personal data resides in git repositories. I put them all in ~/repos (and add symlinks to various places for convenience). This setup makes it easy to sync to laptops, backup to disk, etc. Git::Bunch is the library/script I wrote to do this.
See also File::RsyBak, which I wrote to backup everything else.
Check status of git repositories inside gitbunch directory.
Will perform a 'git status' for each git repositories inside the bunch and report which repositories are clean/unclean.
Will die if can't chdir into bunch or git repository.
This function is not exported by default, but exportable.
Arguments ('*' denotes required arguments):
exclude_files => bool
Exclude files from processing.
This only applies to sync_bunch operations. Operations like check_bunch and exec_bunch already ignore these and only operate on git repos.
sync_bunch
check_bunch
exec_bunch
exclude_non_git_dirs => bool
Exclude non-git dirs from processing.
This only applies to and sync_bunch operations. Operations like check_bunch and exec_bunch already ignore these and only operate on git repos.
exclude_repos => array[str]
Exclude some repos from processing.
exclude_repos_pat => str
Specify regex pattern of repos to exclude.
include_repos => array[str]
Specific git repos to sync, if not specified all repos in the bunch will be processed.
include_repos_pat => str
Specify regex pattern of repos to include.
repo => str
Only process a single repo.
sort => str (default: "-commit-timestamp")
Order entries in bunch.
If sorting is enabled, the repos will be sorted first by some ordering. One use-case for this is to allow more recently committed-to repos to be processed first (using -commit-timestamp or -db-commit-timestamp).
-commit-timestamp
-db-commit-timestamp
db-commit-timestamp (or -db-commit-timestamp) reads SQLite database file repos.db in the source directory and to get last commit timestamp information (in the repos table, the commit_timestamp column). You will need to create and maintain this database, e.g. in your post-commit script. Repos or dirs not having the last commit information in the database will be processed later. This method is faster than commit-timestamp (or -commit-timestamp, see next paragraph) if your source directory contains lots (e.g. hundreds or thousands) of repos because you avoid having to stat() each .git/commit-timestamp file in each repo.
db-commit-timestamp
repos.db
repos
commit_timestamp
commit-timestamp
.git/commit-timestamp
commit-timestamp (or -commit-timestamp) compares the timestamp of .git/commit-timestamp file in each repo. Repos or dirs not having this file will be processed later. You can touch these .git/commit-timestamp files in your post-commit script, for example. This allows sorting recently committed repos more cheaply (compared to doing git log -1).
git log -1
mtime (or -mtime) compares the timestamp or the repo dirs. This might not give the result you want if you expect to process more recently updated repos first, because files in a repo might be updated in the subdirectories of the repo instead of in the top-level dir.
mtime
-mtime
name (or -name) simply compares the repos' names. This is one of the fastest methods.
name
-name
rand randomizes the order of repos, so you get different ordering in each run.
rand
source* => str
Directory to check.
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200 means OK, 4xx caller error, 5xx function error). Second element (msg) is a string containing error message, or 'OK' if status is 200. Third element (result) is optional, the actual result. Fourth element (meta) is called result metadata and is optional, a hash that contains extra information.
Return value: (any)
Execute a command for each repo in the bunch.
For each git repository in the bunch, will chdir to it and execute specified command.
command* => str
Command to execute.
Synchronize bunch to another bunch.
For each git repository in the bunch, will perform a 'git pull/push' for each branch. If repository in destination doesn't exist, it will be rsync-ed first from source. When 'git pull' fails, will exit to let you fix the problem manually.
For all other non-git repos, will simply synchronize by one-way rsync.
backup => bool
Whether doing backup to target.
This setting lets you express that you want to perform synchronizing to a backup target, and that you do not do work on the target. Thus, you do not care about uncommitted or untracked files/dirs in the target repos (might happen if you also do periodic copying of repos to backup using cp/rsync). When this setting is turned on, the function will first do a git clean -f -d (to delete untracked files/dirs) and then git checkout . (to discard all uncommitted changes). This setting will also implicitly turn on create_bare setting (unless that setting has been explicitly enabled/disabled).
git clean -f -d
git checkout .
create_bare
create_bare_target => bool
Whether to create bare git repo when target does not exist.
When target repo does not exist, gitbunch can either copy the source repo using rsync (the default, if this setting is undefined), or it can create target repo with git init --bare (if this setting is set to 1), or it can create target repo with git init (if this setting is set to 0).
rsync
git init --bare
git init
Bare git repositories contain only contents of the .git folder inside the directory and no working copies of your source files.
Creating bare repos are apt for backup purposes since they are more space-efficient.
Non-repos will still be copied/rsync-ed.
delete_branch => bool (default: 0)
Whether to delete branches in dest repos not existing in source repos.
rsync_del => bool
Whether to use --del rsync option.
When rsync-ing non-repos, by default --del option is not used for more safety because rsync is a one-way action. To add rsync --del option, enable this option.
--del
rsync_opt_maintain_ownership => bool (default: 0)
Whether or not, when rsync-ing from source, we use -a (= -rlptgoD) or -rlptD (-a minus -go).
Sometimes using -a results in failure to preserve permission modes on sshfs-mounted filesystem, while -rlptD succeeds, so by default we don't maintain ownership. If you need to maintain ownership (e.g. you run as root and the repos are not owned by root), turn this option on.
target* => str
Destination bunch.
mr, http://joeyh.name/code/mr/ . You probably want to use this instead. mr supports other control version software aside from git, doesn't restrict you to put all your repos in one directory, supports more operations, and has been developed since 2007. Had I known about mr, I probably wouldn't have started Git::Bunch. On the other hand, Git::Bunch is simpler (I think), doesn't require any config file, and can copy/sync files/directories not under source control. I mainly use Git::Bunch to quickly: 1) check whether there are any of my repositories which have uncommitted changes; 2) synchronize (pull/push) to other locations. I put all my data in one big gitbunch directory; I find it simpler. Git::Bunch works for me and I use it daily.
Please visit the project's homepage at https://metacpan.org/release/Git-Bunch.
Source repository is at https://github.com/perlancar/perl-Git-Bunch.
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Git-Bunch
When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.
perlancar <perlancar@cpan.org>
This software is copyright (c) 2015 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Git::Bunch, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Git::Bunch
CPAN shell
perl -MCPAN -e shell install Git::Bunch
For more information on module installation, please visit the detailed CPAN module installation guide.