[Bps-public-commit] git-sync branch, master, updated. 784b144a03a0246a1a9c2832e90c8fc5b7766e57
Alex M Vandiver
alexmv at bestpractical.com
Sat Nov 21 16:29:45 EST 2009
The branch, master has been updated
discards 8dc5a06a6a5aeb3d73a79b02541a84f6d851d5bf (commit)
via 784b144a03a0246a1a9c2832e90c8fc5b7766e57 (commit)
via 3263bd94a7df0abeaad95d0753606b0b477ad507 (commit)
via 4273ad2c115a8f45670e70ef01509698fc120c77 (commit)
via ae7281dfd903beb1a3f00447c52fa5f76ba70822 (commit)
via ce8e6164f47ec942425ea610bb2dbede1d1dd15f (commit)
via c1e8123a27c728238ffd5522799c93c40abb4df2 (commit)
via 8bf9e5d5ec7c26432462e37ba7ab47f520a04558 (commit)
via 9da5111cb94e7af084b0390f0017f6fedc34731f (commit)
via 73952e2eebf3028d87a68b54103dbe83e1fb03c2 (commit)
via c09a8c304e976248db439b61e73f1e40f45ab059 (commit)
via 4c5330f3b3bdfcef2d1b5b0e830ebefa9f9c3191 (commit)
via 766f06d02f1cecc51c7ae8746022f2cd9c03112a (commit)
via 24d13afd79710e21772debd454f3137ac1f44756 (commit)
via abd5dac38563a8a84f1b95fd7653a91b8d451e9d (commit)
via 2b3f7d3f2caba8bd58943992a7fd1e763d7a2ff4 (commit)
via 4deb40589848d22e055d08612d420fcbef7220db (commit)
via 59123d1e1a8c39f21ae9afc0c77d60d8b1571908 (commit)
via e46b1a09d255e660a0358032e21d43455cd02a0d (commit)
via 7d9fcfc0dc554634956634c8c11901d37be4b553 (commit)
via 10514f8140e6e39b43b777433a296603fd824d96 (commit)
via 8cc12fb673f3e31d019af1eb6ae5bcb802572539 (commit)
via aa447f1835ee15f2343fedad3c6380c8125c8a5d (commit)
via 0754d02e75acab9fe3fcd3b5ccdc3787c92209ab (commit)
via 279fa342d7a6964b1ad65cb2bd4e4a590fc124a8 (commit)
via 885dcf7aaa29fa4f756c9560d9e18ce22a23f4d6 (commit)
via ba4be5a9d02dcedcc655112ea2e3f74ff2d8e0ed (commit)
via 8ed04d08b7d12179db4384c65e05fdff36b8ad1b (commit)
via 9fd8b54b557396137b29b67b6c61b5edcb4b1120 (commit)
via 314dca3448f468b3b59c44c3c544b36d81481a89 (commit)
via 595d4b6e39eed6c8ebd7a9cdcceaea4ca6e02642 (commit)
via e46db7470958385f8c7639e4ac588ac55c7bbe15 (commit)
via d3ba93894d9a5a69de5fd96943a168cbdb85e425 (commit)
via ce7538335f3eb09493cdb41fcbbf2eadeeff4c6f (commit)
via 0eeb0c7862856af8259a3a9c084d86326b361479 (commit)
via 4bd151873725406a7c10dffa0e68dd8aea02ea4e (commit)
via 2cbd74eaf34350fc1162cec97ed8557bb18f4daf (commit)
via 92c71761417cb97090f0056ebb70ecd4e966f920 (commit)
via cf91430d27ca2098e87c55cbcac04343323735a3 (commit)
via a9be3ddcf0153c79535b45afd236d4fd9ade37a1 (commit)
via 2462f7ff0c80e189c941c3381c9ff618d5666928 (commit)
via 6dc8b1cd097f69b8367b982e6c92413d153c443d (commit)
via 0e2352ee036e46a3e92c565e96308c78b39b30b9 (commit)
via 36d1b9d95260b01028ad05ff6f5e33ae07f615db (commit)
via 09f8873bc027ef1ffc79a56f1e9c07ec4b92af27 (commit)
via 135fe9911c4f1249a2b20b77b0650cd7b85ba3e1 (commit)
via d0131e559d473bf328d7bf289487c5f11eb17faa (commit)
via 4c1040f93580634383011e8a5ea62a0056a308d2 (commit)
via 2fc211e1ea297ca020a0cd437e2c0c497196202a (commit)
via 48b5a3eea425c64fde8ad3b2892997058a8409d2 (commit)
via b1f609ee2c2fb3f07c908cc20d3873e98e03f694 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (8dc5a06a6a5aeb3d73a79b02541a84f6d851d5bf)
\
N -- N -- N (784b144a03a0246a1a9c2832e90c8fc5b7766e57)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Summary of changes:
git-sync | 311 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 311 insertions(+), 0 deletions(-)
create mode 100755 git-sync
- Log -----------------------------------------------------------------
commit b1f609ee2c2fb3f07c908cc20d3873e98e03f694
Author: jesse <jesse at bestpractical.com>
Date: Tue Apr 14 23:54:22 2009 -0400
First post
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
commit 48b5a3eea425c64fde8ad3b2892997058a8409d2
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Jul 10 18:13:06 2009 -0400
Add smarter sync script
diff --git a/git-sync b/git-sync
new file mode 100644
index 0000000..2bc7d10
--- /dev/null
+++ b/git-sync
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+use Config::GitLike::Git;
+use Git;
+use strict;
+use warnings;
+
+my %conf = Config::GitLike::Git->new->load;
+
+my %sync;
+for (keys %conf) {
+ next unless /^sync\.(?:(.*?)\.)?(.*)$/;
+ my ($section, $var) = ($1, $2);
+ $section = "" unless defined $section;
+ $sync{$section}{$var} = $conf{$_};
+}
+
+my %seen;
+for my $name (keys %sync) {
+ print "Syncing" . (length $name ? " $name" : "")."\n";
+ unless ($sync{$name}{host}) {
+ warn "No 'host' set, skipping!\n";
+ next;
+ }
+ unless ($sync{$name}{path}) {
+ warn "No 'path' set, skipping!\n";
+ next;
+ }
+ unless ($sync{$name}{into}) {
+ warn "No 'into' set, skipping!\n";
+ next;
+ }
+ my @paths = ref $sync{$name}{path} ? @{$sync{$name}{path}} : ($sync{$name}{path});
+ for my $path (@paths) {
+ my @list = `ssh $sync{$name}{host} ls $path`;
+ warn("Listing returned ".($? >> 8).", skipping!\n") and next if $?;
+ for my $reponame (@list) {
+ $reponame =~ s/(\.git)?\n?$//;
+ my $root = "$sync{$name}{into}/$reponame";
+ if ($seen{$root}) {
+ warn "Duplicate repository sync location: $seen{$root} and $path/$reponame\n";
+ next;
+ }
+ $seen{$root} = "$path/$reponame";
+
+ if (-e $root) {
+ # Already exists, fetch and possibly rebase
+ my $repo = eval { Git->repository(Directory => $root) };
+ warn("$root not a git repository? $@\n") and next unless $repo;
+
+ warn "Fetching $reponame\n";
+ eval { $repo->command( "fetch" ); };
+ next if $@;
+
+ my $status = "";
+ my ($fh, $ctx) = $repo->command_output_pipe('status');
+ $status .= $_ while (<$fh>);
+ eval {$repo->command_close_pipe($fh, $ctx);};
+
+ # Rebase if there are no changes, it is on a tracking
+ # branch, and the result would be a fast-forward
+ if ($status =~ /^# Your branch is behind '.*?' by \d commits, and can be fast-forwarded/m
+ and $status =~ /^nothing to commit/m) {
+ warn "Pulling local working copy\n";
+ # git-pull is a shell script, unfortunately, and
+ # thus can't be run via $repo->command( "pull" )
+ chdir($root);
+ system("git pull");
+ }
+ } else {
+ Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
+ Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
+ if $sync{$name}{email};
+ }
+ }
+ }
+}
+
+__END__
+[sync "bps"]
+ host = fsck.com
+ path = /git
+ path = /git-private
+ into = /home/chmrr/work/bps/git
+ email = alexmv at bestpractical.com
commit 2fc211e1ea297ca020a0cd437e2c0c497196202a
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Mon Jul 13 14:06:08 2009 -0400
don't hardcode perl path
diff --git a/git-sync b/git-sync
old mode 100644
new mode 100755
index 2bc7d10..8c62107
--- a/git-sync
+++ b/git-sync
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
use Config::GitLike::Git;
use Git;
commit 4c1040f93580634383011e8a5ea62a0056a308d2
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Mon Jul 13 14:14:57 2009 -0400
normalize spacing
diff --git a/git-sync b/git-sync
index 8c62107..4e1b238 100755
--- a/git-sync
+++ b/git-sync
@@ -78,8 +78,8 @@ for my $name (keys %sync) {
__END__
[sync "bps"]
- host = fsck.com
- path = /git
- path = /git-private
- into = /home/chmrr/work/bps/git
- email = alexmv at bestpractical.com
+ host = fsck.com
+ path = /git
+ path = /git-private
+ into = /home/chmrr/work/bps/git
+ email = alexmv at bestpractical.com
commit d0131e559d473bf328d7bf289487c5f11eb17faa
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Mon Jul 13 14:19:28 2009 -0400
Allow 'git sync foo' to only sync some of your repos
diff --git a/git-sync b/git-sync
index 4e1b238..76e1269 100755
--- a/git-sync
+++ b/git-sync
@@ -15,8 +15,11 @@ for (keys %conf) {
$sync{$section}{$var} = $conf{$_};
}
+my $synconly = shift ||'';
+
my %seen;
for my $name (keys %sync) {
+ next if ($synconly && $name ne $synconly);
print "Syncing" . (length $name ? " $name" : "")."\n";
unless ($sync{$name}{host}) {
warn "No 'host' set, skipping!\n";
commit 135fe9911c4f1249a2b20b77b0650cd7b85ba3e1
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Tue Jul 14 10:16:16 2009 -0400
tiny bit of usage doc
diff --git a/git-sync b/git-sync
index 76e1269..69ddcf1 100755
--- a/git-sync
+++ b/git-sync
@@ -1,5 +1,15 @@
#!/usr/bin/env perl
+# Simple usage:
+# add the config found after __END__ to your config
+# the script will search like git does, so
+# ./.git/config, ~/.gitconfig, /etc/gitconfig
+#
+# $ git sync
+# syncs all sync sections of your config
+# $ git sync bps
+# syncs only one of the sections
+
use Config::GitLike::Git;
use Git;
use strict;
commit 09f8873bc027ef1ffc79a56f1e9c07ec4b92af27
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Thu Jul 23 14:21:11 2009 -0400
If you have a local bare repo, don't do anything other than fetch in it
diff --git a/git-sync b/git-sync
index 69ddcf1..8601b3d 100755
--- a/git-sync
+++ b/git-sync
@@ -65,6 +65,8 @@ for my $name (keys %sync) {
eval { $repo->command( "fetch" ); };
next if $@;
+ next if $repo->config_bool('core.bare');
+
my $status = "";
my ($fh, $ctx) = $repo->command_output_pipe('status');
$status .= $_ while (<$fh>);
commit 36d1b9d95260b01028ad05ff6f5e33ae07f615db
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Wed Jul 29 15:06:38 2009 -0400
Be extra chatty when fetching changes
diff --git a/git-sync b/git-sync
index 8601b3d..c288425 100755
--- a/git-sync
+++ b/git-sync
@@ -80,7 +80,7 @@ for my $name (keys %sync) {
# git-pull is a shell script, unfortunately, and
# thus can't be run via $repo->command( "pull" )
chdir($root);
- system("git pull");
+ system("git pull --stat");
}
} else {
Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
commit 0e2352ee036e46a3e92c565e96308c78b39b30b9
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Wed Jul 29 15:21:14 2009 -0400
Before syncing a repo, check that we've not set sync.ignore
useful for repos that we only want to live on diesel becuase we'll be
using git remote to add references
diff --git a/git-sync b/git-sync
index c288425..0befa68 100755
--- a/git-sync
+++ b/git-sync
@@ -83,6 +83,8 @@ for my $name (keys %sync) {
system("git pull --stat");
}
} else {
+ chomp(my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`);
+ next if $ignore eq 'true';
Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
if $sync{$name}{email};
commit 6dc8b1cd097f69b8367b982e6c92413d153c443d
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Mon Aug 3 14:36:28 2009 -0400
clean up warnings
git config --bool doesnt.exist will return an empty value rather
than false.
diff --git a/git-sync b/git-sync
index 0befa68..072b7a3 100755
--- a/git-sync
+++ b/git-sync
@@ -83,8 +83,8 @@ for my $name (keys %sync) {
system("git pull --stat");
}
} else {
- chomp(my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`);
- next if $ignore eq 'true';
+ my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
+ next if $ignore && chomp($ignore) eq 'true';
Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
if $sync{$name}{email};
commit 2462f7ff0c80e189c941c3381c9ff618d5666928
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon Aug 3 15:07:04 2009 -0400
chomp returns number of newlines removed, not new string
diff --git a/git-sync b/git-sync
index 072b7a3..e4ad7e0 100755
--- a/git-sync
+++ b/git-sync
@@ -84,7 +84,8 @@ for my $name (keys %sync) {
}
} else {
my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
- next if $ignore && chomp($ignore) eq 'true';
+ chomp $ignore if defined $ignore;
+ next if defined $ignore and $ignore eq 'true';
Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
if $sync{$name}{email};
commit a9be3ddcf0153c79535b45afd236d4fd9ade37a1
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Thu Aug 20 14:34:34 2009 -0400
Match git's status better
You can be more than 9 commits behind
If you were 1 commit behind, we wouldn't pull
diff --git a/git-sync b/git-sync
index e4ad7e0..53d97ea 100755
--- a/git-sync
+++ b/git-sync
@@ -74,7 +74,7 @@ for my $name (keys %sync) {
# Rebase if there are no changes, it is on a tracking
# branch, and the result would be a fast-forward
- if ($status =~ /^# Your branch is behind '.*?' by \d commits, and can be fast-forwarded/m
+ if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
and $status =~ /^nothing to commit/m) {
warn "Pulling local working copy\n";
# git-pull is a shell script, unfortunately, and
commit cf91430d27ca2098e87c55cbcac04343323735a3
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Thu Aug 27 14:39:21 2009 -0400
Purge old remote branches after sync
diff --git a/git-sync b/git-sync
index 53d97ea..2ddfa84 100755
--- a/git-sync
+++ b/git-sync
@@ -82,6 +82,9 @@ for my $name (keys %sync) {
chdir($root);
system("git pull --stat");
}
+
+ # Purge old tracking branches
+ $repo->command( qw/remote prune origin/ );
} else {
my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
chomp $ignore if defined $ignore;
commit 92c71761417cb97090f0056ebb70ecd4e966f920
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Mon Oct 5 12:05:04 2009 -0400
If you have local untracker/ignored files, still pull
If there is a conflict, at least you'll be up to date (rather than 83
commits behind)
diff --git a/git-sync b/git-sync
index 2ddfa84..60ecc85 100755
--- a/git-sync
+++ b/git-sync
@@ -75,7 +75,7 @@ for my $name (keys %sync) {
# Rebase if there are no changes, it is on a tracking
# branch, and the result would be a fast-forward
if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
- and $status =~ /^nothing to commit/m) {
+ and $status =~ /^nothing (?:added )?to commit/m) {
warn "Pulling local working copy\n";
# git-pull is a shell script, unfortunately, and
# thus can't be run via $repo->command( "pull" )
commit 2cbd74eaf34350fc1162cec97ed8557bb18f4daf
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Oct 16 22:08:13 2009 -0400
Use pretty colors to make status of repositories clearer
diff --git a/git-sync b/git-sync
index 60ecc85..f8aa4ff 100755
--- a/git-sync
+++ b/git-sync
@@ -14,35 +14,66 @@ use Config::GitLike::Git;
use Git;
use strict;
use warnings;
+use Term::ANSIColor;
my %conf = Config::GitLike::Git->new->load;
my %sync;
for (keys %conf) {
- next unless /^sync\.(?:(.*?)\.)?(.*)$/;
- my ($section, $var) = ($1, $2);
- $section = "" unless defined $section;
- $sync{$section}{$var} = $conf{$_};
+ next unless /^sync\.(.*?)\.(.*)$/;
+ $sync{$1}{$2} = $conf{$_};
}
-my $synconly = shift ||'';
+my @categories;
+if (@ARGV) {
+ for my $name (@ARGV) {
+ die qq{Can't find sync named "$name"\n} unless exists $sync{$name};
+ push @categories, $name;
+ }
+} else {
+ @categories = sort {exists $sync{$a}{local} <=> exists $sync{$b}{local} or $a cmp $b} keys %sync;
+}
my %seen;
-for my $name (keys %sync) {
- next if ($synconly && $name ne $synconly);
- print "Syncing" . (length $name ? " $name" : "")."\n";
- unless ($sync{$name}{host}) {
- warn "No 'host' set, skipping!\n";
+for my $name (@categories) {
+ print colored("Syncing" . (length $name ? " $name" : "")."\n", "bold");
+
+ unless ($sync{$name}{into}) {
+ print colored(" No 'into' set, skipping!\n", "red");
next;
}
- unless ($sync{$name}{path}) {
- warn "No 'path' set, skipping!\n";
- next;
+ if (exists $sync{$name}{local}) {
+ sync_all_local($name);
+ } else {
+ unless ($sync{$name}{host}) {
+ print colored(" No 'host' set, skipping!\n", "red");
+ next;
+ }
+ unless ($sync{$name}{path}) {
+ print colored(" No 'path' set, skipping!\n", "red");
+ next;
+ }
+ sync_all_remote($name);
}
- unless ($sync{$name}{into}) {
- warn "No 'into' set, skipping!\n";
- next;
+ print " "x45,"\n";
+}
+
+sub sync_all_local {
+ my $name = shift;
+ for my $root (grep {-d} <$sync{$name}{into}/*>) {
+ $root =~ m{/([^/]+)(?:\.git)?$};
+ printf " %-40s ", $1;
+ if (exists $seen{$root}) {
+ print "\r";
+ next;
+ }
+ update($root, 0);
+ $seen{$root} = "";
}
+}
+
+sub sync_all_remote {
+ my $name = shift;
my @paths = ref $sync{$name}{path} ? @{$sync{$name}{path}} : ($sync{$name}{path});
for my $path (@paths) {
my @list = `ssh $sync{$name}{host} ls $path`;
@@ -50,53 +81,108 @@ for my $name (keys %sync) {
for my $reponame (@list) {
$reponame =~ s/(\.git)?\n?$//;
my $root = "$sync{$name}{into}/$reponame";
+
+ printf " %-40s ", $reponame;
if ($seen{$root}) {
- warn "Duplicate repository sync location: $seen{$root} and $path/$reponame\n";
+ print colored( "[ Already synchronized! ]\n", "red");
+ next;
+ } elsif (exists $seen{$root}) {
+ print "\r";
next;
}
- $seen{$root} = "$path/$reponame";
-
+ $seen{$root} = $name;
if (-e $root) {
- # Already exists, fetch and possibly rebase
- my $repo = eval { Git->repository(Directory => $root) };
- warn("$root not a git repository? $@\n") and next unless $repo;
-
- warn "Fetching $reponame\n";
- eval { $repo->command( "fetch" ); };
- next if $@;
-
- next if $repo->config_bool('core.bare');
-
- my $status = "";
- my ($fh, $ctx) = $repo->command_output_pipe('status');
- $status .= $_ while (<$fh>);
- eval {$repo->command_close_pipe($fh, $ctx);};
-
- # Rebase if there are no changes, it is on a tracking
- # branch, and the result would be a fast-forward
- if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
- and $status =~ /^nothing (?:added )?to commit/m) {
- warn "Pulling local working copy\n";
- # git-pull is a shell script, unfortunately, and
- # thus can't be run via $repo->command( "pull" )
- chdir($root);
- system("git pull --stat");
- }
-
- # Purge old tracking branches
- $repo->command( qw/remote prune origin/ );
+ update($root, 1);
} else {
- my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
- chomp $ignore if defined $ignore;
- next if defined $ignore and $ignore eq 'true';
- Git::command_noisy( clone => "$sync{$name}{host}:$path/$reponame", $root );
- Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
- if $sync{$name}{email};
+ new($root => $name => $reponame => $path);
}
}
}
}
+sub update {
+ my ($root, $force) = @_;
+
+ # Already exists, fetch and possibly rebase
+ my $repo = eval { Git->repository(Directory => $root) };
+ unless ($repo) {
+ print $force ? colored("[ Not a git repository! ]\n", "red") : "\r";
+ return;
+ }
+
+ my $gitsvn = -d $repo->repo_path . "/svn/git-svn";
+ if ($gitsvn) {
+ print colored( "[ svn ] ", "dark blue" );
+ # git-svn doesn't work with $repo->command, hate
+ `git --git-dir @{[$repo->repo_path]} svn fetch -q`;
+ } else {
+ eval { $repo->command( ["fetch"], STDERR => 0 ); } if 0;
+ }
+ print colored("[ Fetch failed! $@]\n", "red") and return if $@;
+
+ print colored("[ Bare repository ]\n", "green") and return if $repo->config_bool('core.bare');
+
+ my $status = "";
+ my ($fh, $ctx) = $repo->command_output_pipe('status');
+ $status .= $_ while (<$fh>);
+ eval {$repo->command_close_pipe($fh, $ctx);};
+
+ # Rebase if there are no changes, it is on a tracking
+ # branch, and the result would be a fast-forward
+ my ($branch) = $status =~ /^# On branch (.*)/m;
+ if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
+ and $status =~ /^nothing (?:added )?to commit/m) {
+ # git-pull is a shell script, unfortunately, and
+ # thus can't be run via $repo->command( "pull" )
+ chdir($root);
+ print colored( "[ Pulled ($branch) ]\n", "bold green" );
+ my $pull = `git pull --stat`;
+ # Indent, and colorize (git doesn't, because we're not a tty)
+ $pull =~ s/^/ /gm;
+ $pull =~ s/^( .*?)(\+*)(-*)$/$1.colored($2,"green").colored($3,"red")/gme;
+ print $pull;
+ } else {
+ if ($status =~ /^# Your branch and '.*?' have diverged.*?(\d+) and (\d+) different commit/sm) {
+ print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold blue" );
+ } elsif ($status =~ /^# Your branch is ahead /m) {
+ print colored( "[ Ahead ($branch) ]", "bold blue");
+ } else {
+ print colored( "[ Up-to-date ($branch) ]", "green");
+ }
+ if ($status !~ /^nothing (?:added )?to commit/m) {
+ print colored( " [ Dirty ]", "yellow");
+ }
+ print "\n";
+ }
+
+ # Purge old tracking branches
+ $repo->command( qw/remote prune origin/ ) unless $gitsvn;
+}
+
+sub new {
+ my ($root, $name, $reponame, $path) = @_;
+ `ssh $sync{$name}{host} [ -e $path/${reponame}.git/config ]`;
+ if ($?) {
+ print "\r";
+ return;
+ }
+ my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
+ chomp $ignore if defined $ignore;
+ if (defined $ignore and $ignore eq 'true') {
+ print "\r";
+ return;
+ }
+
+ eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
+ if ($@) {
+ print colored( "[ Clone failed! ]\n", "red");
+ return;
+ }
+ Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
+ if $sync{$name}{email};
+ print colored( "[ Cloned! ]\n", "bold green");
+}
+
__END__
[sync "bps"]
host = fsck.com
commit 4bd151873725406a7c10dffa0e68dd8aea02ea4e
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 02:30:15 2009 -0400
Existence of .git/svn/.metadata is better for detecting git-svn checkouts
diff --git a/git-sync b/git-sync
index f8aa4ff..a4a3e30 100755
--- a/git-sync
+++ b/git-sync
@@ -110,7 +110,7 @@ sub update {
return;
}
- my $gitsvn = -d $repo->repo_path . "/svn/git-svn";
+ my $gitsvn = -e $repo->repo_path . "/svn/.metadata";
if ($gitsvn) {
print colored( "[ svn ] ", "dark blue" );
# git-svn doesn't work with $repo->command, hate
commit 0eeb0c7862856af8259a3a9c084d86326b361479
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 02:33:47 2009 -0400
Show how many commits ahead the branch is
diff --git a/git-sync b/git-sync
index a4a3e30..3156b31 100755
--- a/git-sync
+++ b/git-sync
@@ -144,8 +144,8 @@ sub update {
} else {
if ($status =~ /^# Your branch and '.*?' have diverged.*?(\d+) and (\d+) different commit/sm) {
print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold blue" );
- } elsif ($status =~ /^# Your branch is ahead /m) {
- print colored( "[ Ahead ($branch) ]", "bold blue");
+ } elsif ($status =~ /^# Your branch is ahead of '(?:.*?)' by (\d+) commit/m) {
+ print colored( "[ Ahead by $1 ($branch) ]", "bold blue");
} else {
print colored( "[ Up-to-date ($branch) ]", "green");
}
commit ce7538335f3eb09493cdb41fcbbf2eadeeff4c6f
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Sat Oct 17 09:49:28 2009 -0400
Squelch a warning when you're not on a branch
If you git checkout an unannotated tag, you won't be on a branch
diff --git a/git-sync b/git-sync
index 3156b31..7dbcb6f 100755
--- a/git-sync
+++ b/git-sync
@@ -130,6 +130,7 @@ sub update {
# Rebase if there are no changes, it is on a tracking
# branch, and the result would be a fast-forward
my ($branch) = $status =~ /^# On branch (.*)/m;
+ $branch ||= 'Not currently on any branch';
if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
and $status =~ /^nothing (?:added )?to commit/m) {
# git-pull is a shell script, unfortunately, and
commit d3ba93894d9a5a69de5fd96943a168cbdb85e425
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Sat Oct 17 10:27:47 2009 -0400
into can be set multiple times in a config section
diff --git a/git-sync b/git-sync
index 7dbcb6f..6c276ae 100755
--- a/git-sync
+++ b/git-sync
@@ -60,15 +60,17 @@ for my $name (@categories) {
sub sync_all_local {
my $name = shift;
- for my $root (grep {-d} <$sync{$name}{into}/*>) {
- $root =~ m{/([^/]+)(?:\.git)?$};
- printf " %-40s ", $1;
- if (exists $seen{$root}) {
- print "\r";
- next;
+ foreach my $into ( ref $sync{$name}{into} ? @{$sync{$name}{into}} : $sync{$name}{into} ) {
+ for my $root (grep {-d} <$into/*>) {
+ $root =~ m{/([^/]+)(?:\.git)?$};
+ printf " %-40s ", $1;
+ if (exists $seen{$root}) {
+ print "\r";
+ next;
+ }
+ update($root, 0);
+ $seen{$root} = "";
}
- update($root, 0);
- $seen{$root} = "";
}
}
commit e46db7470958385f8c7639e4ac588ac55c7bbe15
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Sat Oct 17 10:33:38 2009 -0400
document how to have a local set of repos
diff --git a/git-sync b/git-sync
index 6c276ae..c1415b2 100755
--- a/git-sync
+++ b/git-sync
@@ -193,3 +193,6 @@ __END__
path = /git-private
into = /home/chmrr/work/bps/git
email = alexmv at bestpractical.com
+[sync "localrepos"]
+ into = /home/chmrr/gitprojects
+ local = true
commit 595d4b6e39eed6c8ebd7a9cdcceaea4ca6e02642
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:04:33 2009 -0400
Add --verbose argument
diff --git a/git-sync b/git-sync
index c1415b2..aa4a2ad 100755
--- a/git-sync
+++ b/git-sync
@@ -15,6 +15,12 @@ use Git;
use strict;
use warnings;
use Term::ANSIColor;
+use Getopt::Long;
+
+my ($verbose, $pretend);
+GetOptions(
+ verbose => \$verbose,
+);
my %conf = Config::GitLike::Git->new->load;
@@ -65,7 +71,7 @@ sub sync_all_local {
$root =~ m{/([^/]+)(?:\.git)?$};
printf " %-40s ", $1;
if (exists $seen{$root}) {
- print "\r";
+ print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
next;
}
update($root, 0);
@@ -89,7 +95,7 @@ sub sync_all_remote {
print colored( "[ Already synchronized! ]\n", "red");
next;
} elsif (exists $seen{$root}) {
- print "\r";
+ print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
next;
}
$seen{$root} = $name;
@@ -159,20 +165,20 @@ sub update {
}
# Purge old tracking branches
- $repo->command( qw/remote prune origin/ ) unless $gitsvn;
+ $repo->command( qw/remote prune origin/ ) unless $gitsvn or $pretend;
}
sub new {
my ($root, $name, $reponame, $path) = @_;
`ssh $sync{$name}{host} [ -e $path/${reponame}.git/config ]`;
if ($?) {
- print "\r";
+ print $verbose ? colored("[ Not a git repository ]\n", "dark") : "\r";
return;
}
my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
chomp $ignore if defined $ignore;
if (defined $ignore and $ignore eq 'true') {
- print "\r";
+ print $verbose ? colored("[ sync.ignore set ]\n", "dark") : "\r";
return;
}
commit 314dca3448f468b3b59c44c3c544b36d81481a89
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:04:55 2009 -0400
Add --pretend argument, to not actually fetch
diff --git a/git-sync b/git-sync
index aa4a2ad..fbcedc4 100755
--- a/git-sync
+++ b/git-sync
@@ -20,6 +20,7 @@ use Getopt::Long;
my ($verbose, $pretend);
GetOptions(
verbose => \$verbose,
+ pretend => \$pretend,
);
my %conf = Config::GitLike::Git->new->load;
@@ -122,12 +123,15 @@ sub update {
if ($gitsvn) {
print colored( "[ svn ] ", "dark blue" );
# git-svn doesn't work with $repo->command, hate
- `git --git-dir @{[$repo->repo_path]} svn fetch -q`;
+ `git --git-dir @{[$repo->repo_path]} svn fetch -q` unless $pretend;
} else {
- eval { $repo->command( ["fetch"], STDERR => 0 ); } if 0;
+ eval { $repo->command( ["fetch"], STDERR => 0 ); } unless $pretend;
}
+
print colored("[ Fetch failed! $@]\n", "red") and return if $@;
+ print colored("[ Fetch ] ", "dark") if $pretend;
+
print colored("[ Bare repository ]\n", "green") and return if $repo->config_bool('core.bare');
my $status = "";
commit 9fd8b54b557396137b29b67b6c61b5edcb4b1120
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:09:08 2009 -0400
Whoops -- forgot case where local is behind but dirty, and hence not pulled
diff --git a/git-sync b/git-sync
index fbcedc4..3515f1e 100755
--- a/git-sync
+++ b/git-sync
@@ -157,8 +157,10 @@ sub update {
} else {
if ($status =~ /^# Your branch and '.*?' have diverged.*?(\d+) and (\d+) different commit/sm) {
print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold blue" );
- } elsif ($status =~ /^# Your branch is ahead of '(?:.*?)' by (\d+) commit/m) {
+ } elsif ($status =~ /^# Your branch is ahead of '.*?' by (\d+) commit/m) {
print colored( "[ Ahead by $1 ($branch) ]", "bold blue");
+ } elsif ($status =~ /^# Your branch is behind '.*?' by (\d+) commit/m) {
+ print colored( "[ Behind by $1 ($branch) ]", "bold blue");
} else {
print colored( "[ Up-to-date ($branch) ]", "green");
}
commit 8ed04d08b7d12179db4384c65e05fdff36b8ad1b
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:16:27 2009 -0400
--pretend option shouldn't actually call `git pull`
diff --git a/git-sync b/git-sync
index 3515f1e..72b11a5 100755
--- a/git-sync
+++ b/git-sync
@@ -148,10 +148,10 @@ sub update {
# git-pull is a shell script, unfortunately, and
# thus can't be run via $repo->command( "pull" )
chdir($root);
- print colored( "[ Pulled ($branch) ]\n", "bold green" );
- my $pull = `git pull --stat`;
+ print colored( $pretend ? "[ Would pull ($branch) ]\n" : "[ Pulled ($branch) ]\n", "bold green" );
+ my $pull = $pretend ? "" : `git pull --stat`;
# Indent, and colorize (git doesn't, because we're not a tty)
- $pull =~ s/^/ /gm;
+ $pull =~ s/^/ /gm if length $pull;
$pull =~ s/^( .*?)(\+*)(-*)$/$1.colored($2,"green").colored($3,"red")/gme;
print $pull;
} else {
commit ba4be5a9d02dcedcc655112ea2e3f74ff2d8e0ed
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:19:34 2009 -0400
Make --pretend work on new repositories that would be cloned
diff --git a/git-sync b/git-sync
index 72b11a5..166e5b8 100755
--- a/git-sync
+++ b/git-sync
@@ -188,6 +188,8 @@ sub new {
return;
}
+ print colored("[ Would clone ]\n", "bold green") and return if $pretend;
+
eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "red");
commit 885dcf7aaa29fa4f756c9560d9e18ce22a23f4d6
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:30:26 2009 -0400
Cloning fails in void context (!?)
diff --git a/git-sync b/git-sync
index 166e5b8..ab01329 100755
--- a/git-sync
+++ b/git-sync
@@ -190,7 +190,7 @@ sub new {
print colored("[ Would clone ]\n", "bold green") and return if $pretend;
- eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
+ my $ret = eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "red");
return;
commit 279fa342d7a6964b1ad65cb2bd4e4a590fc124a8
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:30:57 2009 -0400
Remove trailing newline from $@ on fetch failure
diff --git a/git-sync b/git-sync
index ab01329..3945c0e 100755
--- a/git-sync
+++ b/git-sync
@@ -128,7 +128,8 @@ sub update {
eval { $repo->command( ["fetch"], STDERR => 0 ); } unless $pretend;
}
- print colored("[ Fetch failed! $@]\n", "red") and return if $@;
+ my $error = $@; chomp $error;
+ print colored("[ Fetch failed! $error]\n", "red") and return if $@;
print colored("[ Fetch ] ", "dark") if $pretend;
commit 0754d02e75acab9fe3fcd3b5ccdc3787c92209ab
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 15:32:03 2009 -0400
Switch to bold red for errors
diff --git a/git-sync b/git-sync
index 3945c0e..10816a9 100755
--- a/git-sync
+++ b/git-sync
@@ -115,7 +115,7 @@ sub update {
# Already exists, fetch and possibly rebase
my $repo = eval { Git->repository(Directory => $root) };
unless ($repo) {
- print $force ? colored("[ Not a git repository! ]\n", "red") : "\r";
+ print $force ? colored("[ Not a git repository! ]\n", "bold red") : "\r";
return;
}
@@ -129,7 +129,7 @@ sub update {
}
my $error = $@; chomp $error;
- print colored("[ Fetch failed! $error]\n", "red") and return if $@;
+ print colored("[ Fetch failed! $error]\n", "bold red") and return if $@;
print colored("[ Fetch ] ", "dark") if $pretend;
@@ -193,7 +193,7 @@ sub new {
my $ret = eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
if ($@) {
- print colored( "[ Clone failed! ]\n", "red");
+ print colored( "[ Clone failed! ]\n", "bold red");
return;
}
Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
commit aa447f1835ee15f2343fedad3c6380c8125c8a5d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:41:58 2009 -0400
Add --dry-run and -v as other options
diff --git a/git-sync b/git-sync
index 10816a9..a31f985 100755
--- a/git-sync
+++ b/git-sync
@@ -19,8 +19,8 @@ use Getopt::Long;
my ($verbose, $pretend);
GetOptions(
- verbose => \$verbose,
- pretend => \$pretend,
+ 'verbose|v' => \$verbose,
+ 'pretend|dry-run' => \$pretend,
);
my %conf = Config::GitLike::Git->new->load;
commit 8cc12fb673f3e31d019af1eb6ae5bcb802572539
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:47:03 2009 -0400
Split new() into not being ssh-dependent, just cloning
diff --git a/git-sync b/git-sync
index a31f985..c9f8c00 100755
--- a/git-sync
+++ b/git-sync
@@ -103,7 +103,16 @@ sub sync_all_remote {
if (-e $root) {
update($root, 1);
} else {
- new($root => $name => $reponame => $path);
+ `ssh $sync{$name}{host} [ -e $path/${reponame}.git/config ]`;
+ print $verbose ? colored("[ Not a git repository ]\n", "dark") : "\r" and next
+ if $?;
+
+ my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
+ chomp $ignore if defined $ignore;
+ print $verbose ? colored("[ sync.ignore set ]\n", "dark") : "\r" and next
+ if defined $ignore and $ignore eq 'true';
+
+ new($root => "$sync{$name}{host}:$path/$reponame", $sync{$name}{email});
}
}
}
@@ -176,28 +185,18 @@ sub update {
}
sub new {
- my ($root, $name, $reponame, $path) = @_;
- `ssh $sync{$name}{host} [ -e $path/${reponame}.git/config ]`;
- if ($?) {
- print $verbose ? colored("[ Not a git repository ]\n", "dark") : "\r";
- return;
- }
- my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
- chomp $ignore if defined $ignore;
- if (defined $ignore and $ignore eq 'true') {
- print $verbose ? colored("[ sync.ignore set ]\n", "dark") : "\r";
- return;
- }
+ # Path to clone into, path to clone from, user
+ my ($into, $from, $email) = @_;
- print colored("[ Would clone ]\n", "bold green") and return if $pretend;
+ print colored("[ Would clone $from into $into ]\n", "bold green") and return if $pretend;
- my $ret = eval { Git::command( [clone => "$sync{$name}{host}:$path/$reponame", $root], STDERR => 0 ) };
+ my $ret = eval { Git::command( [clone => $from => $into], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "bold red");
return;
}
- Git::command( config => "--file", "$root/.git/config", "user.email", $sync{$name}{email} )
- if $sync{$name}{email};
+ Git::command( config => "--file", "$into/.git/config", "user.email", $email )
+ if $email;
print colored( "[ Cloned! ]\n", "bold green");
}
commit 10514f8140e6e39b43b777433a296603fd824d96
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:52:26 2009 -0400
Make %sync no longer referenced globally
diff --git a/git-sync b/git-sync
index c9f8c00..b42276a 100755
--- a/git-sync
+++ b/git-sync
@@ -45,29 +45,19 @@ my %seen;
for my $name (@categories) {
print colored("Syncing" . (length $name ? " $name" : "")."\n", "bold");
- unless ($sync{$name}{into}) {
+ if (not $sync{$name}{into}) {
print colored(" No 'into' set, skipping!\n", "red");
- next;
- }
- if (exists $sync{$name}{local}) {
- sync_all_local($name);
+ } elsif (exists $sync{$name}{local}) {
+ sync_all_local(%{$sync{$name}});
} else {
- unless ($sync{$name}{host}) {
- print colored(" No 'host' set, skipping!\n", "red");
- next;
- }
- unless ($sync{$name}{path}) {
- print colored(" No 'path' set, skipping!\n", "red");
- next;
- }
- sync_all_remote($name);
+ sync_all_remote(%{$sync{$name}});
}
print " "x45,"\n";
}
sub sync_all_local {
- my $name = shift;
- foreach my $into ( ref $sync{$name}{into} ? @{$sync{$name}{into}} : $sync{$name}{into} ) {
+ my %config = @_;
+ foreach my $into ( ref $config{into} ? @{$config{into}} : $config{into} ) {
for my $root (grep {-d} <$into/*>) {
$root =~ m{/([^/]+)(?:\.git)?$};
printf " %-40s ", $1;
@@ -82,37 +72,47 @@ sub sync_all_local {
}
sub sync_all_remote {
- my $name = shift;
- my @paths = ref $sync{$name}{path} ? @{$sync{$name}{path}} : ($sync{$name}{path});
+ my %config = @_;
+
+ print colored(" No 'host' set, skipping!\n", "red") and return
+ unless $config{host};
+
+ print colored(" No 'path' set, skipping!\n", "red") and return
+ unless $config{path};
+
+ print colored(" Only one value valid for 'into' when 'host' supplied!\n", "red") and return
+ if ref $config{into};
+
+ my @paths = ref $config{path} ? @{$config{path}} : ($config{path});
for my $path (@paths) {
- my @list = `ssh $sync{$name}{host} ls $path`;
+ my @list = `ssh $config{host} ls $path`;
warn("Listing returned ".($? >> 8).", skipping!\n") and next if $?;
for my $reponame (@list) {
$reponame =~ s/(\.git)?\n?$//;
- my $root = "$sync{$name}{into}/$reponame";
+ my $into = "$config{into}/$reponame";
printf " %-40s ", $reponame;
- if ($seen{$root}) {
+ if ($seen{$into}) {
print colored( "[ Already synchronized! ]\n", "red");
next;
- } elsif (exists $seen{$root}) {
+ } elsif (exists $seen{$into}) {
print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
next;
}
- $seen{$root} = $name;
- if (-e $root) {
- update($root, 1);
+ $seen{$into} = $into;
+ if (-e $into) {
+ update($into, 1);
} else {
- `ssh $sync{$name}{host} [ -e $path/${reponame}.git/config ]`;
+ `ssh $config{host} [ -e $path/${reponame}.git/config ]`;
print $verbose ? colored("[ Not a git repository ]\n", "dark") : "\r" and next
if $?;
- my ($ignore) = `ssh $sync{$name}{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
+ my ($ignore) = `ssh $config{host} git config --bool -f $path/${reponame}.git/config sync.ignore`;
chomp $ignore if defined $ignore;
print $verbose ? colored("[ sync.ignore set ]\n", "dark") : "\r" and next
if defined $ignore and $ignore eq 'true';
- new($root => "$sync{$name}{host}:$path/$reponame", $sync{$name}{email});
+ new($into => "$config{host}:$path/$reponame", $config{email});
}
}
}
commit 7d9fcfc0dc554634956634c8c11901d37be4b553
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:53:27 2009 -0400
Refactor "already seen this path"
diff --git a/git-sync b/git-sync
index b42276a..507f822 100755
--- a/git-sync
+++ b/git-sync
@@ -61,12 +61,8 @@ sub sync_all_local {
for my $root (grep {-d} <$into/*>) {
$root =~ m{/([^/]+)(?:\.git)?$};
printf " %-40s ", $1;
- if (exists $seen{$root}) {
- print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
- next;
- }
+ next if already($root => 0);
update($root, 0);
- $seen{$root} = "";
}
}
}
@@ -92,14 +88,7 @@ sub sync_all_remote {
my $into = "$config{into}/$reponame";
printf " %-40s ", $reponame;
- if ($seen{$into}) {
- print colored( "[ Already synchronized! ]\n", "red");
- next;
- } elsif (exists $seen{$into}) {
- print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
- next;
- }
- $seen{$into} = $into;
+ next if already($into => 1);
if (-e $into) {
update($into, 1);
} else {
@@ -118,6 +107,19 @@ sub sync_all_remote {
}
}
+sub already {
+ my ($path, $force) = @_;
+ if ($force and $seen{$path}) {
+ print colored( "[ Already synchronized! ]\n", "red");
+ return 1;
+ } elsif (exists $seen{$path}) {
+ print $verbose ? colored("[ Already synchronized ]\n", "dark") : "\r";
+ return 1;
+ }
+ $seen{$path} = $force;
+ return;
+}
+
sub update {
my ($root, $force) = @_;
commit e46b1a09d255e660a0358032e21d43455cd02a0d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:54:09 2009 -0400
Change a warn()ing into a colored print
diff --git a/git-sync b/git-sync
index 507f822..e3d3c11 100755
--- a/git-sync
+++ b/git-sync
@@ -82,7 +82,7 @@ sub sync_all_remote {
my @paths = ref $config{path} ? @{$config{path}} : ($config{path});
for my $path (@paths) {
my @list = `ssh $config{host} ls $path`;
- warn("Listing returned ".($? >> 8).", skipping!\n") and next if $?;
+ print colored(" Listing returned ".($? >> 8).", skipping!\n", "bold red") and next if $?;
for my $reponame (@list) {
$reponame =~ s/(\.git)?\n?$//;
my $into = "$config{into}/$reponame";
commit 59123d1e1a8c39f21ae9afc0c77d60d8b1571908
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sat Oct 17 23:54:23 2009 -0400
Github support
diff --git a/git-sync b/git-sync
index e3d3c11..d0ce57c 100755
--- a/git-sync
+++ b/git-sync
@@ -16,6 +16,7 @@ use strict;
use warnings;
use Term::ANSIColor;
use Getopt::Long;
+use LWP::Simple qw();
my ($verbose, $pretend);
GetOptions(
@@ -49,6 +50,8 @@ for my $name (@categories) {
print colored(" No 'into' set, skipping!\n", "red");
} elsif (exists $sync{$name}{local}) {
sync_all_local(%{$sync{$name}});
+ } elsif (exists $sync{$name}{github}) {
+ sync_all_github(%{$sync{$name}});
} else {
sync_all_remote(%{$sync{$name}});
}
@@ -67,6 +70,41 @@ sub sync_all_local {
}
}
+sub sync_all_github {
+ my %config = @_;
+
+ print colored(" Only one value valid for 'into' when 'guthub' supplied", "red") and return
+ if ref $config{into};
+
+ my $decoder = eval { require JSON::Any; JSON::Any->import; JSON::Any->new };
+ print colored(" GitHub sync support requires the JSON::Any module\n", "red") and return
+ if $@ or not $decoder;
+
+ my @accounts = ref $config{github} ? @{$config{github}} : ($config{github});
+ for my $acct (@accounts) {
+ my $content = LWP::Simple::get("http://github.com/api/v1/json/$acct");
+ print colored("GET of http://github.com/api/v1/json/$acct failed!\n", "bold red") and return
+ unless defined $content;
+
+ my $data = eval {$decoder->jsonToObj($content)};
+ print colored("Parsing of GitHub JSON response failed! $@\n", "bold red")."\n$content\n" and return
+ unless defined $data;
+
+ for my $repo (@{$data->{user}{repositories} || []}) {
+ my $reponame = $repo->{name};
+ my $root = "$config{into}/$reponame";
+
+ printf " %-40s ", $reponame;
+ next if already($root => 1);
+ if (-e $root) {
+ update($root, 1);
+ } else {
+ new($root => "git\@github.com:$acct/$reponame.git" => $config{email});
+ }
+ }
+ }
+}
+
sub sync_all_remote {
my %config = @_;
commit 4deb40589848d22e055d08612d420fcbef7220db
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 00:33:34 2009 -0400
Clones from github mysteriously fail without clone -q
Without the -q, repositories are cloned from github, but are left in
inconsistent state, claiming:
error: bad signature
fatal: index file corrupt
Git.pm is a sad, sad piece of business.
diff --git a/git-sync b/git-sync
index d0ce57c..f443a8a 100755
--- a/git-sync
+++ b/git-sync
@@ -230,7 +230,7 @@ sub new {
print colored("[ Would clone $from into $into ]\n", "bold green") and return if $pretend;
- my $ret = eval { Git::command( [clone => $from => $into], STDERR => 0 ) };
+ my $ret = eval { Git::command( [clone => "-q" => $from => $into], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "bold red");
return;
commit 2b3f7d3f2caba8bd58943992a7fd1e763d7a2ff4
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 00:36:16 2009 -0400
Add github example
diff --git a/git-sync b/git-sync
index f443a8a..414ab62 100755
--- a/git-sync
+++ b/git-sync
@@ -250,3 +250,6 @@ __END__
[sync "localrepos"]
into = /home/chmrr/gitprojects
local = true
+[sync "github"]
+ into = /home/chmrr/github
+ github = alexmv
commit abd5dac38563a8a84f1b95fd7653a91b8d451e9d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 00:39:17 2009 -0400
Consistent indentation on error messages
diff --git a/git-sync b/git-sync
index 414ab62..0153b3b 100755
--- a/git-sync
+++ b/git-sync
@@ -83,11 +83,11 @@ sub sync_all_github {
my @accounts = ref $config{github} ? @{$config{github}} : ($config{github});
for my $acct (@accounts) {
my $content = LWP::Simple::get("http://github.com/api/v1/json/$acct");
- print colored("GET of http://github.com/api/v1/json/$acct failed!\n", "bold red") and return
+ print colored(" GET of http://github.com/api/v1/json/$acct failed!\n", "bold red") and next
unless defined $content;
my $data = eval {$decoder->jsonToObj($content)};
- print colored("Parsing of GitHub JSON response failed! $@\n", "bold red")."\n$content\n" and return
+ print colored(" Parsing of GitHub JSON response failed! $@\n", "bold red")."\n$content\n" and next
unless defined $data;
for my $repo (@{$data->{user}{repositories} || []}) {
commit 24d13afd79710e21772debd454f3137ac1f44756
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 00:40:31 2009 -0400
Fix typo in error message
diff --git a/git-sync b/git-sync
index 0153b3b..23efd22 100755
--- a/git-sync
+++ b/git-sync
@@ -73,7 +73,7 @@ sub sync_all_local {
sub sync_all_github {
my %config = @_;
- print colored(" Only one value valid for 'into' when 'guthub' supplied", "red") and return
+ print colored(" Only one value valid for 'into' when 'github' supplied", "red") and return
if ref $config{into};
my $decoder = eval { require JSON::Any; JSON::Any->import; JSON::Any->new };
commit 766f06d02f1cecc51c7ae8746022f2cd9c03112a
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 01:01:37 2009 -0400
Add a --logs option to add output of `git log --oneline`
diff --git a/git-sync b/git-sync
index 23efd22..59161a1 100755
--- a/git-sync
+++ b/git-sync
@@ -18,10 +18,11 @@ use Term::ANSIColor;
use Getopt::Long;
use LWP::Simple qw();
-my ($verbose, $pretend);
+my ($verbose, $pretend, $log);
GetOptions(
'verbose|v' => \$verbose,
'pretend|dry-run' => \$pretend,
+ 'log|l' => \$log,
);
my %conf = Config::GitLike::Git->new->load;
@@ -193,31 +194,45 @@ sub update {
# branch, and the result would be a fast-forward
my ($branch) = $status =~ /^# On branch (.*)/m;
$branch ||= 'Not currently on any branch';
- if ($status =~ /^# Your branch is behind '.*?' by \d+ commits?, and can be fast-forwarded/m
- and $status =~ /^nothing (?:added )?to commit/m) {
+ if ($status =~ /^nothing (?:added )?to commit/m
+ and $status =~ /^# Your branch is behind '(.*?)' by (\d+) commits?, and can be fast-forwarded/m) {
+ my ($tracking, $behind) = ($1, $2);
# git-pull is a shell script, unfortunately, and
# thus can't be run via $repo->command( "pull" )
chdir($root);
- print colored( $pretend ? "[ Would pull ($branch) ]\n" : "[ Pulled ($branch) ]\n", "bold green" );
+ print colored( $pretend ?
+ "[ Would pull $behind commits ($branch) ]\n" :
+ "[ Pulled $behind commits ($branch) ]\n",
+ "bold green" );
+
+ print logs($repo, $branch => $tracking);
+
my $pull = $pretend ? "" : `git pull --stat`;
+ # This line will always be present, and is content-free
+ $pull =~ s/^First, rewinding head.*?\n//m;
# Indent, and colorize (git doesn't, because we're not a tty)
+ $pull =~ s/^( .*?)(\+*)(-*)$/$1.colored($2,"green").colored($3,"red")/gme;
$pull =~ s/^/ /gm if length $pull;
- $pull =~ s/^( .*?)(\+*)(-*)$/$1.colored($2,"green").colored($3,"red")/gme;
print $pull;
} else {
+ my $logs = "";
if ($status =~ /^# Your branch and '.*?' have diverged.*?(\d+) and (\d+) different commit/sm) {
print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold blue" );
- } elsif ($status =~ /^# Your branch is ahead of '.*?' by (\d+) commit/m) {
- print colored( "[ Ahead by $1 ($branch) ]", "bold blue");
- } elsif ($status =~ /^# Your branch is behind '.*?' by (\d+) commit/m) {
- print colored( "[ Behind by $1 ($branch) ]", "bold blue");
+ } elsif ($status =~ /^# Your branch is ahead of '(.*?)' by (\d+) commit/m) {
+ my ($tracking, $ahead) = ($1, $2);
+ print colored( "[ Ahead by $ahead ($branch) ]", "bold blue");
+ $logs = logs($repo, $tracking => $branch);
+ } elsif ($status =~ /^# Your branch is behind '(.*?)' by (\d+) commit/m) {
+ my ($tracking, $behind) = ($1, $2);
+ print colored( "[ Behind by $behind ($branch) ]", "bold blue");
+ $logs = logs($repo, $branch => $tracking);
} else {
print colored( "[ Up-to-date ($branch) ]", "green");
}
if ($status !~ /^nothing (?:added )?to commit/m) {
print colored( " [ Dirty ]", "yellow");
}
- print "\n";
+ print "\n$logs";
}
# Purge old tracking branches
@@ -240,6 +255,15 @@ sub new {
print colored( "[ Cloned! ]\n", "bold green");
}
+sub logs {
+ my ($repo, $from, $to) = @_;
+ return "" unless $log;
+ my $logmsg = $repo->command( log => "--oneline", "--reverse", "$from..$to" );
+ # Re-colorize and indent
+ $logmsg =~ s/^(\S+)/" ".colored($1,"yellow")/egm;
+ return $logmsg;
+}
+
__END__
[sync "bps"]
host = fsck.com
commit 4c5330f3b3bdfcef2d1b5b0e830ebefa9f9c3191
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Sun Oct 18 19:04:37 2009 -0400
Use different colors for ahead, behind, and diverged
diff --git a/git-sync b/git-sync
index 59161a1..c3b1f2c 100755
--- a/git-sync
+++ b/git-sync
@@ -217,14 +217,14 @@ sub update {
} else {
my $logs = "";
if ($status =~ /^# Your branch and '.*?' have diverged.*?(\d+) and (\d+) different commit/sm) {
- print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold blue" );
+ print colored( "[ Diverged by $1 and $2 commits ($branch) ]", "bold cyan" );
} elsif ($status =~ /^# Your branch is ahead of '(.*?)' by (\d+) commit/m) {
my ($tracking, $ahead) = ($1, $2);
print colored( "[ Ahead by $ahead ($branch) ]", "bold blue");
$logs = logs($repo, $tracking => $branch);
} elsif ($status =~ /^# Your branch is behind '(.*?)' by (\d+) commit/m) {
my ($tracking, $behind) = ($1, $2);
- print colored( "[ Behind by $behind ($branch) ]", "bold blue");
+ print colored( "[ Behind by $behind ($branch) ]", "bold magenta");
$logs = logs($repo, $branch => $tracking);
} else {
print colored( "[ Up-to-date ($branch) ]", "green");
commit c09a8c304e976248db439b61e73f1e40f45ab059
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon Oct 19 00:37:33 2009 -0400
Propagate signals (like SIGINT) from Git::command and `` back to ourselves
diff --git a/git-sync b/git-sync
index c3b1f2c..d5acfca 100755
--- a/git-sync
+++ b/git-sync
@@ -18,6 +18,11 @@ use Term::ANSIColor;
use Getopt::Long;
use LWP::Simple qw();
+$SIG{INT} = sub {
+ print colored("\n\nInterrupted!\n", "bold red");
+ exit;
+};
+
my ($verbose, $pretend, $log);
GetOptions(
'verbose|v' => \$verbose,
@@ -177,6 +182,7 @@ sub update {
} else {
eval { $repo->command( ["fetch"], STDERR => 0 ); } unless $pretend;
}
+ kill $? & 127, $$ if $? & 127;
my $error = $@; chomp $error;
print colored("[ Fetch failed! $error]\n", "bold red") and return if $@;
@@ -208,6 +214,8 @@ sub update {
print logs($repo, $branch => $tracking);
my $pull = $pretend ? "" : `git pull --stat`;
+ kill $? & 127, $$ if $? & 127;
+
# This line will always be present, and is content-free
$pull =~ s/^First, rewinding head.*?\n//m;
# Indent, and colorize (git doesn't, because we're not a tty)
@@ -237,6 +245,7 @@ sub update {
# Purge old tracking branches
$repo->command( qw/remote prune origin/ ) unless $gitsvn or $pretend;
+ kill $? & 127, $$ if $? & 127;
}
sub new {
@@ -250,6 +259,8 @@ sub new {
print colored( "[ Clone failed! ]\n", "bold red");
return;
}
+ kill $? & 127, $$ if $? & 127;
+
Git::command( config => "--file", "$into/.git/config", "user.email", $email )
if $email;
print colored( "[ Cloned! ]\n", "bold green");
commit 73952e2eebf3028d87a68b54103dbe83e1fb03c2
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Oct 30 15:37:58 2009 -0400
Create the 'into' directory if it doesn't exist
diff --git a/git-sync b/git-sync
index d5acfca..f372963 100755
--- a/git-sync
+++ b/git-sync
@@ -67,6 +67,10 @@ for my $name (@categories) {
sub sync_all_local {
my %config = @_;
foreach my $into ( ref $config{into} ? @{$config{into}} : $config{into} ) {
+ unless (-d $into) {
+ print colored(" Directory '$into' does not exist!\n", "bold red");
+ next;
+ }
for my $root (grep {-d} <$into/*>) {
$root =~ m{/([^/]+)(?:\.git)?$};
printf " %-40s ", $1;
@@ -82,6 +86,12 @@ sub sync_all_github {
print colored(" Only one value valid for 'into' when 'github' supplied", "red") and return
if ref $config{into};
+ unless (-d $config{into}) {
+ print colored(" Creating directory '$config{into}'\n", "bold");
+ print colored(" Directory creation failed: $!\n", "bold red") and return
+ unless mkdir $config{into};
+ }
+
my $decoder = eval { require JSON::Any; JSON::Any->import; JSON::Any->new };
print colored(" GitHub sync support requires the JSON::Any module\n", "red") and return
if $@ or not $decoder;
@@ -123,6 +133,12 @@ sub sync_all_remote {
print colored(" Only one value valid for 'into' when 'host' supplied!\n", "red") and return
if ref $config{into};
+ unless (-d $config{into}) {
+ print colored(" Creating directory '$config{into}'\n", "bold");
+ print colored(" Directory creation failed: $!\n", "bold red") and return
+ unless mkdir $config{into};
+ }
+
my @paths = ref $config{path} ? @{$config{path}} : ($config{path});
for my $path (@paths) {
my @list = `ssh $config{host} ls $path`;
commit 9da5111cb94e7af084b0390f0017f6fedc34731f
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Oct 30 16:38:39 2009 -0400
Use File::Path::mkpath instead of mkdir, for when `mkdir -p`-like effects are wanted
diff --git a/git-sync b/git-sync
index f372963..0fb3261 100755
--- a/git-sync
+++ b/git-sync
@@ -17,6 +17,7 @@ use warnings;
use Term::ANSIColor;
use Getopt::Long;
use LWP::Simple qw();
+use File::Path qw();
$SIG{INT} = sub {
print colored("\n\nInterrupted!\n", "bold red");
@@ -89,7 +90,7 @@ sub sync_all_github {
unless (-d $config{into}) {
print colored(" Creating directory '$config{into}'\n", "bold");
print colored(" Directory creation failed: $!\n", "bold red") and return
- unless mkdir $config{into};
+ unless eval { File::Path::mkpath($config{into}) };
}
my $decoder = eval { require JSON::Any; JSON::Any->import; JSON::Any->new };
@@ -136,7 +137,7 @@ sub sync_all_remote {
unless (-d $config{into}) {
print colored(" Creating directory '$config{into}'\n", "bold");
print colored(" Directory creation failed: $!\n", "bold red") and return
- unless mkdir $config{into};
+ unless eval { File::Path::mkpath($config{into}) };
}
my @paths = ref $config{path} ? @{$config{path}} : ($config{path});
commit 8bf9e5d5ec7c26432462e37ba7ab47f520a04558
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Fri Oct 30 19:26:47 2009 -0400
use remote update rather than fetch
If you have multiple remotes, git fetch silently does nothing.
Unfortunately, git remote update run from Git::command fails
in void context with return code 13?
diff --git a/git-sync b/git-sync
index 0fb3261..a01c165 100755
--- a/git-sync
+++ b/git-sync
@@ -197,7 +197,7 @@ sub update {
# git-svn doesn't work with $repo->command, hate
`git --git-dir @{[$repo->repo_path]} svn fetch -q` unless $pretend;
} else {
- eval { $repo->command( ["fetch"], STDERR => 0 ); } unless $pretend;
+ my $ret = eval { $repo->command( qw/remote update/ ); } unless $pretend;
}
kill $? & 127, $$ if $? & 127;
commit c1e8123a27c728238ffd5522799c93c40abb4df2
Author: Kevin Falcone <falcone at bestpractical.com>
Date: Wed Nov 4 10:15:41 2009 -0500
Prune while Updating
This makes sure we prune all your hedges, rather than just origin
diff --git a/git-sync b/git-sync
index a01c165..891f024 100755
--- a/git-sync
+++ b/git-sync
@@ -197,7 +197,7 @@ sub update {
# git-svn doesn't work with $repo->command, hate
`git --git-dir @{[$repo->repo_path]} svn fetch -q` unless $pretend;
} else {
- my $ret = eval { $repo->command( qw/remote update/ ); } unless $pretend;
+ my $ret = eval { $repo->command( qw/remote update --prune/ ); } unless $pretend;
}
kill $? & 127, $$ if $? & 127;
@@ -260,9 +260,6 @@ sub update {
print "\n$logs";
}
- # Purge old tracking branches
- $repo->command( qw/remote prune origin/ ) unless $gitsvn or $pretend;
- kill $? & 127, $$ if $? & 127;
}
sub new {
commit ce8e6164f47ec942425ea610bb2dbede1d1dd15f
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Wed Nov 4 17:57:00 2009 -0500
Localize $? when it gets set
diff --git a/git-sync b/git-sync
index 891f024..cb24957 100755
--- a/git-sync
+++ b/git-sync
@@ -265,6 +265,7 @@ sub update {
sub new {
# Path to clone into, path to clone from, user
my ($into, $from, $email) = @_;
+ local $?;
print colored("[ Would clone $from into $into ]\n", "bold green") and return if $pretend;
commit ae7281dfd903beb1a3f00447c52fa5f76ba70822
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Wed Nov 4 17:58:01 2009 -0500
Show clone error if verbose is set
diff --git a/git-sync b/git-sync
index cb24957..72e6b60 100755
--- a/git-sync
+++ b/git-sync
@@ -272,6 +272,7 @@ sub new {
my $ret = eval { Git::command( [clone => "-q" => $from => $into], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "bold red");
+ print colored( "Error: $@\n", "red") if ($verbose);
return;
}
kill $? & 127, $$ if $? & 127;
commit 4273ad2c115a8f45670e70ef01509698fc120c77
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Wed Nov 4 18:18:09 2009 -0500
Make new() have a true return value on success
diff --git a/git-sync b/git-sync
index 72e6b60..5c09a22 100755
--- a/git-sync
+++ b/git-sync
@@ -267,19 +267,20 @@ sub new {
my ($into, $from, $email) = @_;
local $?;
- print colored("[ Would clone $from into $into ]\n", "bold green") and return if $pretend;
+ print colored("[ Would clone $from into $into ]\n", "bold green") and return 1 if $pretend;
my $ret = eval { Git::command( [clone => "-q" => $from => $into], STDERR => 0 ) };
if ($@) {
print colored( "[ Clone failed! ]\n", "bold red");
print colored( "Error: $@\n", "red") if ($verbose);
- return;
+ return undef;
}
kill $? & 127, $$ if $? & 127;
Git::command( config => "--file", "$into/.git/config", "user.email", $email )
if $email;
print colored( "[ Cloned! ]\n", "bold green");
+ return 1;
}
sub logs {
commit 3263bd94a7df0abeaad95d0753606b0b477ad507
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Wed Nov 4 18:18:48 2009 -0500
Make github clones fall back to unauth
diff --git a/git-sync b/git-sync
index 5c09a22..1237ec8 100755
--- a/git-sync
+++ b/git-sync
@@ -116,7 +116,11 @@ sub sync_all_github {
if (-e $root) {
update($root, 1);
} else {
- new($root => "git\@github.com:$acct/$reponame.git" => $config{email});
+ my $auth = new($root => "git\@github.com:$acct/$reponame.git" => $config{email});
+ unless ($auth) {
+ printf " %-40s ", "...trying again, anonymously";
+ new($root => "git://github.com/$acct/$reponame.git" => $config{email});
+ }
}
}
}
commit 784b144a03a0246a1a9c2832e90c8fc5b7766e57
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Nov 6 13:11:01 2009 -0500
Add back STDERR => 0 so output isn't marred with "Unpacking objects" from fetch
diff --git a/git-sync b/git-sync
index 1237ec8..4a2cba9 100755
--- a/git-sync
+++ b/git-sync
@@ -201,7 +201,7 @@ sub update {
# git-svn doesn't work with $repo->command, hate
`git --git-dir @{[$repo->repo_path]} svn fetch -q` unless $pretend;
} else {
- my $ret = eval { $repo->command( qw/remote update --prune/ ); } unless $pretend;
+ my $ret = eval { $repo->command( [qw/remote update --prune/], STDERR => 0 ); } unless $pretend;
}
kill $? & 127, $$ if $? & 127;
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list