summaryrefslogtreecommitdiff
path: root/bin/git-push-all
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2016-07-23 16:30:41 -0700
committerSean Whitton <spwhitton@spwhitton.name>2016-07-23 16:30:41 -0700
commit6395195a796c436b6f03fe875e15b035043b5f39 (patch)
tree9e944d94c4a6937fc55170fe425ca8d7d717e716 /bin/git-push-all
parentce7fbd77a73bad22e40a2138c8a8242a5334f820 (diff)
downloaddotfiles-6395195a796c436b6f03fe875e15b035043b5f39.tar.gz
rework git-push-all
This avoids failure in the case where more than one remote has a branch of the same name, but the local branch of that name can be pushed to only one of them (and indeed, has its pushRemote set). E.g. the master branch at origin and locally is the Debian packaging branch, but the GitHub fork (used for submitting pull requests) has a master branch that is upstream's master branch. pushRemote for master is set to origin, but since another branch has pushRemote set to fork, the old script would try to push all matching branches to fork, which fails as it can't push master there (not a fast-forward).
Diffstat (limited to 'bin/git-push-all')
-rwxr-xr-xbin/git-push-all64
1 files changed, 27 insertions, 37 deletions
diff --git a/bin/git-push-all b/bin/git-push-all
index ec351c9c..b8f3734e 100755
--- a/bin/git-push-all
+++ b/bin/git-push-all
@@ -27,25 +27,18 @@
# Description:
# This script will try to push all your branches to the places they
-# should be pushed. Specifically,
+# should be pushed, with --follow-tags. Specifically, for each branch,
#
-# - If remote.pushDefault is set, push all matching branches to each
-# remote mentioned in remote.pushDefault or a
-# branch.<name>.pushRemote, with --follow-tags. I.e. for *each* remote
+# 1. If branch.pushRemote is set, push it there
#
-# git push --follow-tags <remote> :
+# 2. Otherwise, if remote.pushDefault is set, push it there
#
-# - Otherwise, push all matching branches and all tags to each remote. I.e.
-# for *each* remote
+# 3. Otherwise, if it is tracking a remote branch, push it there
#
-# git push --tags <remote> :
+# 4. Otherwise, exit non-zero.
#
-# In summary, this script is similar to `git push --all --tags` except
-# that it doesn't create any new remote branches. The recommended
-# usage is to run `git push-all` followed by some command which lists
-# branches that haven't been pushed anywhere, such as `mr status` from
-# the myrepos package. These can then be manually pushed to the right
-# places.
+# If a branch is tracking a remote that you cannot push to, be sure to
+# set at least one of branch.pushRemote and remote.pushDefault.
use strict;
use warnings;
@@ -58,30 +51,27 @@ my $git = Git::Wrapper->new(".");
my $config = Config::GitLike->new( confname => 'config' );
$config->load_file('.git/config');
-my $pushRemotes = $config->get_regexp( key => "branch\..*\.pushRemote" );
-my @pushRemotes = uniq(values %$pushRemotes);
+my @branches = $git->branch;
my $pushDefault = $config->get( key => "remote.pushDefault" );
-push @pushRemotes, $pushDefault if ( defined $pushDefault );
-my @remotes = uniq($git->remote);
-if ( defined $pushDefault ) {
- # mode one: assume that there are read-only remotes
- print "DEBUG: pushing to pushDefault alone\n";
- foreach my $remote ( @pushRemotes ) {
- unless ( $remote eq "dgit" ) {
- print "DEBUG: pushing $remote\n";
- system "git push --follow-tags $remote :";
- exit 1 if ( $? != 0 );
- }
- }
-} else {
- # mode two: assume we can write to all remotes
- print "DEBUG: pushing to all remotes\n";
- foreach my $remote ( @remotes ) {
- unless ( $remote eq "dgit" ) {
- print "DEBUG: pushing $remote\n";
- system "git push --tags $remote :";
- exit 1 if ( $? != 0 );
- }
+foreach my $branch ( @branches ) {
+ $branch =~ s/[ \*]//g;
+ my $pushRemote = $config->get( key => "branch.$branch.pushRemote" );
+ my $tracking = $config->get( key => "branch.$branch.remote" );
+
+ if ( defined $pushRemote ) {
+ print ">> pushing $branch to $pushRemote (its pushRemote)\n";
+ system "git push --follow-tags $pushRemote $branch";
+ exit 1 if ( $? != 0 );
+ } elsif ( defined $pushDefault ) {
+ print ">> pushing $branch to $pushDefault (the remote.pushDefault)\n";
+ system "git push --follow-tags $pushDefault $branch";
+ exit 1 if ( $? != 0 );
+ } elsif ( defined "$tracking" ) {
+ print ">> pushing $branch to $tracking (probably to its tracking branch)\n";
+ system "git push --follow-tags $tracking $branch";
+ exit 1 if ( $? != 0 );
+ } else {
+ die "couldn't find anywhere to push $branch";
}
}