0

I have a Git repository with a single origin remote, and that remote has two pushurls, one for each of the servers foo and bar:

$ git remote set-url --add --push origin me@foo:path/to/repo.git
$ git remote set-url --add --push origin me@bar:path/to/repo.git

The intent here was to always have an upstream mirror bar in case I (temporarily) lose access to the main server foo. With this configuration, I can issue a simple git push and have my commits automatically propagated to both servers. Until now I have found this solution to be more convenient than setting up multiple remotes, since the latter requires issuing separate git push commands for each remote (or creating a shell script/alias that does this automatically and then remembering to install it on all my machines).

The problem with the multiple-pushurls approach is that when the main server really does go down or otherwise becomes temporarily inaccessible, git push aborts before even attempting to push to the mirror server:

$ git push -v
Pushing to me@foo:path/to/repo.git
GitLab: The project you were looking for could not be found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

$

How can I make git push ignore such errors and instead move on to the next pushurl in the list?

Psychonaut
  • 859
  • 8
  • 22
  • I would assume that you can manually set the push url when pushing, thus solving the problem? – mnestorov Aug 27 '19 at 12:17
  • @mnestorov Sure, but that doesn't lend itself well to automation, particularly when different projects/submodules have different mirrors. What I am actually trying to do is `git submodule foreach git push` on a project with dozens of submodules. – Psychonaut Aug 27 '19 at 12:21

1 Answers1

0

Rather than using the multiple push URLs, you might set things up such that running git push directly always fail as a sort of reminder (this part is optional), then use a script that you write yourself that invokes separate git pushes with each of the various mirrors, determines whether enough of those worked, and reports success or failure based on that.

You can make this even more convenient by putting your git submodule foreach into this script.

In other words, instead of:

git submodule foreach git push

you would just run:

myscript

or:

git myscript

To make the latter work, write the script and call it git-myscript. Put this anywhere in your $PATH so that running git-myscript invokes it. Now running git myscript will have Git invoke it for you, with $GIT_DIR set, and with $PATH adjusted so that the Git scripting routines will be found by the shell: your script can now use:

 . git-sh-setup

to initialize itself and gain access to the functions in git-sh-setup.sh.

The git submodule command is, at least as of today, just such a script. Perusing it may help you with ideas for writing the mirroring script you'd like to have. Note that git config --get is one way to extract various settings, such as remote.$remote.pushurl; git config --get-regexp is another. Git's git config is largely agnostic to what any particular setting means, which in turn means that you can invent your own settings, such as remote.$remote.mirror1, remote.$remote.mirror2, and so on.

torek
  • 448,244
  • 59
  • 642
  • 775
  • While the setup you propose is a valid alternative way of doing things, and something I might consider in the future, it does not solve my immediate problem. I already have many repositories set up with multiple pushurls; it would be a lot of work to reconfigure all these and to write and install the requisite shell scripts on all my development machines. (And in fact, it is for this reason that my question explicitly stated that I am not interested in such a solution.) If possible, I would prefer a quick workaround that simply makes `git push` ignore errors. – Psychonaut Aug 28 '19 at 06:26
  • There isn't one. But you could make your new script use the multiple push URLs that are already there, either as a fallback if there isn't anything more sensible, or just as its standard way of operating. – torek Aug 28 '19 at 15:22