B<mr> is a Multiple Repository management tool. It can checkout, update, or
perform other actions on a set of repositories as if they were one combined
repository. It supports any combination of subversion, git, cvs, mercurial,
-bzr and darcs repositories, and support for other revision control systems can
-easily be added.
+bzr, darcs and fossil repositories, and support for other revision
+control systems can easily be added.
B<mr> cds into and operates on all registered repositories at or below your
working directory. Or, if you are in a subdirectory of a repository that
=back
-=head1 "MRCONFIG FILES"
+=head1 MRCONFIG FILES
Here is an example .mrconfig file:
or even to add other commands for 'mr online' to run. If the file is
present, mr assumes it is in offline mode.
-=head1 "UNTRUSTED MRCONFIG FILES"
+=head1 UNTRUSTED MRCONFIG FILES
Since mrconfig files can contain arbitrary shell commands, they can do
-anything. This flexability is good, but it also allows a malicious mrconfig
+anything. This flexibility is good, but it also allows a malicious mrconfig
file to delete your whole home directory. Such a file might be contained
inside a repository that your main ~/.mrconfig checks out and chains to. To
avoid worries about evil commands in a mrconfig file, mr
=head1 AUTHOR
-Copyright 2007-2009 Joey Hess <joey@kitenet.net>
+Copyright 2007-2010 Joey Hess <joey@kitenet.net>
Licensed under the GNU GPL version 2 or higher.
} @list;
}
+sub repodir {
+ my $repo=shift;
+ my $topdir=$repo->{topdir};
+ my $subdir=$repo->{subdir};
+ my $ret=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
+ $ret=~s/\/\.$//;
+ return $ret;
+}
+
# figure out which repos to act on
sub selectrepos {
my @repos;
my $subdir=$repo->{subdir};
next if $subdir eq 'DEFAULT';
- my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
+ my $dir=repodir($repo);
my $d=$directory;
$dir.="/" unless $dir=~/\/$/;
$d.="/" unless $d=~/\/$/;
my $subdir=$repo->{subdir};
next if $subdir eq 'DEFAULT';
- my $dir=($subdir =~/^\//) ? $subdir : $topdir.$subdir;
+ my $dir=repodir($repo);
my $d=$directory;
$dir.="/" unless $dir=~/\/$/;
$d.="/" unless $d=~/\/$/;
}
}
$section=expandenv($section) if $trusted;
+ if ($section ne 'ALIAS' &&
+ ! exists $config{$dir}{$section} &&
+ exists $config{$dir}{DEFAULT}) {
+ # copy in defaults
+ $config{$dir}{$section}={ %{$config{$dir}{DEFAULT}} };
+ }
}
elsif (/^(\w+)\s*=\s*(.*)/) {
my $parameter=$1;
if (! defined $section) {
die "$f line $.: parameter ($parameter) not in section\n";
}
- if ($section ne 'ALIAS' &&
- ! exists $config{$dir}{$section} &&
- exists $config{$dir}{DEFAULT}) {
- # copy in defaults
- $config{$dir}{$section}={ %{$config{$dir}{DEFAULT}} };
- }
if ($section eq 'ALIAS') {
$alias{$parameter}=$value;
}
eval q{use File::Temp};
die $@ if $@;
my $tmpconfig=File::Temp->new();
- my @curlargs = ("curl", "-A", "mr", "-s", $url, "-o", $tmpconfig);
+ my @curlargs = ("curl", "-A", "mr", "-L", "-s", $url, "-o", $tmpconfig);
push(@curlargs, "-k") if $insecure;
my $curlstatus = system(@curlargs);
die "mr bootstrap: invalid SSL certificate for $url (consider -k)\n" if $curlstatus >> 8 == 60;
if [ -z "$1" ] || [ -z "$2" ]; then
error "mr: usage: hours_since action num"
fi
- for dir in .git .svn .bzr CVS .hg _darcs; do
+ for dir in .git .svn .bzr CVS .hg _darcs _FOSSIL_; do
if [ -e "$MR_REPO/$dir" ]; then
flagfile="$MR_REPO/$dir/.mr_last$1"
break
fi
delta=`perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile"`
if [ "$delta" -lt "$2" ]; then
- exit 0
+ return 1
else
touch "$flagfile"
- exit 1
+ return 0
fi
}
bzr_test = test -d "$MR_REPO"/.bzr
cvs_test = test -d "$MR_REPO"/CVS
hg_test = test -d "$MR_REPO"/.hg
-darcs_test = test -d "$MR_REPO"/_darcs
+fossil_test = test -f "$MR_REPO"/_FOSSIL_
git_bare_test =
test -d "$MR_REPO"/refs/heads && test -d "$MR_REPO"/refs/tags &&
test -d "$MR_REPO"/objects && test -f "$MR_REPO"/config &&
test "`GIT_CONFIG="$MR_REPO"/config git config --get core.bare`" = true
+darcs_test = test -d "$MR_REPO"/_darcs
svn_update = svn update "$@"
git_update = git pull "$@"
cvs_update = cvs update "$@"
hg_update = hg pull "$@" && hg update "$@"
darcs_update = darcs pull -a "$@"
+fossil_update = fossil pull "$@"
svn_status = svn status "$@"
-git_status = git status "$@" || true
-bzr_status = bzr status "$@"
+git_status = git status -s "$@" || true
+bzr_status = bzr status --short "$@"
cvs_status = cvs status "$@"
hg_status = hg status "$@"
darcs_status = darcs whatsnew -ls "$@" || true
+fossil_status = fossil changes "$@"
svn_commit = svn commit "$@"
git_commit = git commit -a "$@" && git push --all
cvs_commit = cvs commit "$@"
hg_commit = hg commit -m "$@" && hg push
darcs_commit = darcs record -a -m "$@" && darcs push -a
+fossil_commit = fossil commit "$@"
git_record = git commit -a "$@"
bzr_record = bzr commit "$@"
hg_record = hg commit -m "$@"
darcs_record = darcs record -a -m "$@"
+fossil_record = fossil commit "$@"
svn_push = :
git_push = git push "$@"
cvs_push = :
hg_push = hg push "$@"
darcs_push = darcs push -a "$@"
+fossil_push = fossil push "$@"
svn_diff = svn diff "$@"
git_diff = git diff "$@"
cvs_diff = cvs diff "$@"
hg_diff = hg diff "$@"
darcs_diff = darcs diff -u "$@"
+fossil_diff = fossil diff "$@"
svn_log = svn log "$@"
git_log = git log "$@"
hg_log = hg log "$@"
darcs_log = darcs changes "$@"
git_bare_log = git log "$@"
+fossil_log = fossil timeline "$@"
svn_register =
url=`LC_ALL=C svn info . | grep -i '^URL:' | cut -d ' ' -f 2`
fi
echo "Registering git url: $url in $MR_CONFIG"
mr -c "$MR_CONFIG" config "`pwd`" checkout="git clone --bare '$url' '$MR_REPO'"
+fossil_register =
+ url=`fossil remote-url`
+ repo=`fossil info | grep repository | sed -e s/repository:*.//g -e s/\ //g`
+ echo "Registering fossil repository $url in $MR_CONFIG"
+ mr -c "$MR_CONFIG" config "`pwd`" checkout="mkdir -p '$MR_REPO' && cd '$MR_REPO' && fossil open '$repo'"
svn_trusted_checkout = svn co $url $repo
svn_alt_trusted_checkout = svn checkout $url $repo
hg_trusted_checkout = hg clone $url $repo
darcs_trusted_checkout = darcs get $url $repo
git_bare_trusted_checkout = git clone --bare $url $repo
+# fossil: messy to do
help =