|
|
@@ -282,35 +282,60 @@ sub main {
|
|
|
# Build a map of names to clone URIs
|
|
|
my $field_name = $options{nossh} ? 'clone_url' : 'ssh_url';
|
|
|
my %names2clone = map { $_->{name} => $_->{$field_name} } @repos_local;
|
|
|
+
|
|
|
+ # Figure out which repos are private so we don't mirror them unless instructed to.
|
|
|
+ my @private_repos = map { $_->{name} } grep { $_->{private} } @repos_local;
|
|
|
+
|
|
|
+ # Grab all the mirrors push uris
|
|
|
my %mirror_uris;
|
|
|
foreach my $repo (@repos_mirror) {
|
|
|
$mirror_uris{$repo->{name}} //= [];
|
|
|
push( @{$mirror_uris{$repo->{name}}}, $repo->{$field_name});
|
|
|
}
|
|
|
|
|
|
- $cleanup->();
|
|
|
-
|
|
|
- use Data::Dumper;
|
|
|
- die Dumper(\%names2clone, \%mirror_uris);
|
|
|
-
|
|
|
- my @to_create;
|
|
|
foreach my $to_clone (keys(%names2clone)) {
|
|
|
- my $res = Git::command_oneline([ 'clone', $names2clone{$to_clone} ]);
|
|
|
+ #XXX testing removme
|
|
|
+ next unless $to_clone eq 'perl-Gogs';
|
|
|
+
|
|
|
+ # Don't clone it if it is already present.
|
|
|
+ my $already_exists=1;
|
|
|
+ if (!-d $to_clone) {
|
|
|
+ $already_exists=0;
|
|
|
+ my $res = Git::command_oneline([ 'clone', $names2clone{$to_clone} ]);
|
|
|
+ }
|
|
|
my $repo = Git->repository(Directory => $to_clone);
|
|
|
|
|
|
- #TODO check privacy field
|
|
|
+ # Figure out what the remotes look like
|
|
|
+ my $res = $repo->command(qw{remote -v});
|
|
|
+ my %remotes = _parse_remotes($res);
|
|
|
|
|
|
- if (!exists $mirror_uris{$to_clone}) {
|
|
|
- #TODO push into @to_create if $create
|
|
|
- next;
|
|
|
- }
|
|
|
- # TODO check if the repo is missing on just *some* of the mirrors and add to @to_create if $create
|
|
|
+ # TODO add specific remotes for the baseurl and mirrors. This way we can manually push to each if we need to sync.
|
|
|
+
|
|
|
+ # Ensure that origin is correctly the local one for those that already exist
|
|
|
+ if ($remotes{origin}{fetch} ne $names2clone{$to_clone}) {
|
|
|
+ print "Incorrect origin in $to_clone, correcting...\n";
|
|
|
+ $res = $repo->command(qw{remote set-url --fetch origin}, $names2clone{$to_clone});
|
|
|
+ # TODO error handling
|
|
|
|
|
|
- foreach my $mirror (@{$mirror_uris{$to_clone}}) {
|
|
|
- # The real "magic" here -- you can have many push urls.
|
|
|
- $repo->command(qw{git remote set-url --add --push}, 'origin', $mirror);
|
|
|
- #TODO make sure they are all synced up if --sync
|
|
|
+ # We don't care if push uri already there
|
|
|
+ next if any { $_ eq $names2clone{$to_clone} } @{$remotes{origin}{push}};
|
|
|
+
|
|
|
+ print "Lacking push URI for $to_clone, correcting...\n";
|
|
|
+ $res = $repo->command(qw{remote set-url --add --push origin}, $names2clone{$to_clone});
|
|
|
+ #TODO error handling
|
|
|
+ }
|
|
|
+ # TODO figure out which mirrors are missing, and add them if needed (consider privacy)
|
|
|
+
|
|
|
+ foreach my $mirror_uri ($mirror_uris{$to_clone}) {
|
|
|
+ # We don't care if it's already there
|
|
|
+ next if any { $_ eq $mirror_uri } @{$remotes{origin}{push}};
|
|
|
+ next if !$options{private} && any { $_ eq $to_clone } @private_repos;
|
|
|
+ print "Lacking push URI $mirror_uri, adding to origin...\n";
|
|
|
+ $res = $repo->command(qw{remote set-url --add --push origin}, $mirror_uri);
|
|
|
+ #TODO error handling
|
|
|
}
|
|
|
+
|
|
|
+ # Finally, sync up the mirrors if instructed. This is important, as push URIs which aren't in sync will leave git in an inconsistent state.
|
|
|
}
|
|
|
|
|
|
# Clean up
|
|
|
@@ -318,6 +343,21 @@ sub main {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+sub _parse_remotes {
|
|
|
+ my ($raw) = shift;
|
|
|
+ my %parsed;
|
|
|
+ foreach my $line (split(/\n/, $raw)) {
|
|
|
+ my ($name, $uri, $type) = $line =~ m/^(.+)\s+(.+)\s+\((.+)\)$/;
|
|
|
+ if ($type eq 'fetch') {
|
|
|
+ $parsed{$name}{$type} = $uri;
|
|
|
+ } else {
|
|
|
+ $parsed{$name}{$type} //= [];
|
|
|
+ push(@{$parsed{$name}{$type}}, $uri);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return %parsed;
|
|
|
+}
|
|
|
+
|
|
|
sub _cleanup_token {
|
|
|
my ( $api, $password, $insecure ) = @_;
|
|
|
my $result = $api->delete_token( sha1 => $api->token, password => $password, insecure => $insecure );
|