{"thread":{"id":"20997","subject":"[PATCH] git-push: add option --repo-all","startedAt":"2009-09-18T07:17:02Z","lastAt":"2009-09-18T16:42:49Z","messageCount":6,"participants":["Kirill A. Korinskiy","Jakub Narebski","Paolo Bonzini","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"123484","messageId":"1253258222-11475-1-git-send-email-catap@catap.ru","threadId":"20997","inReplyTo":null,"subject":"[PATCH] git-push: add option --repo-all","fromName":"Kirill A. Korinskiy","fromEmail":"catap@catap.ru","sentAt":"2009-09-18T07:17:02Z","receivedAt":"2009-09-18T07:17:02Z","isPatch":true,"sender":{"key":"catap@catap.ru","avatar":"https://gravatar.com/avatar/ea0ab2c29579606bd684eccdf786c666f4425bedc4e599b698a175f12737b1c5?d=mp&s=160"},"body":"Example of usage: I write some software on my laptop and some time\npushing to my home/private server for backup. Some time ago my\nsoftware is done and I openin it on github, but I'm don't like kill my\nprivate repos. Now update a two remotes repo is'n sexy, because I'm\nneed using a some shell wrapper:\n\n    git remote show | while read repo; do git push $repo; done\n---\n Documentation/git-push.txt |    4 ++-\n builtin-push.c             |   34 +++++++++++++++++++++-----------\n t/t5523-push-repo-all.sh   |   46 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 71 insertions(+), 13 deletions(-)\n create mode 100755 t/t5523-push-repo-all.sh\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex ba6a8a2..734e745 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -10,7 +10,6 @@ SYNOPSIS\n --------\n [verse]\n 'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]\n-\t   [--repo=<repository>] [-f | --force] [-v | --verbose]\n \t   [<repository> <refspec>...]\n \n DESCRIPTION\n@@ -134,6 +133,9 @@ useful if you write an alias or script around 'git-push'.\n \ttransfer spends extra cycles to minimize the number of\n \tobjects to be sent and meant to be used on slower connection.\n \n+--repo-all::\n+\tSend changes to all remote repos.\n+\n -v::\n --verbose::\n \tRun verbosely.\ndiff --git a/builtin-push.c b/builtin-push.c\nindex 3cb1ee4..2b25293 100644\n--- a/builtin-push.c\n+++ b/builtin-push.c\n@@ -10,7 +10,7 @@\n #include \"parse-options.h\"\n \n static const char * const push_usage[] = {\n-\t\"git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]\",\n+\t\"git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository> | --repo-all] [-f | --force] [-v] [<repository> <refspec>...]\",\n \tNULL,\n };\n \n@@ -88,19 +88,13 @@ static void setup_default_push_refspecs(void)\n \t}\n }\n \n-static int do_push(const char *repo, int flags)\n+static int do_push(struct remote *remote, void *priv)\n {\n+\tint flags = *((int *)priv);\n \tint i, errs;\n-\tstruct remote *remote = remote_get(repo);\n \tconst char **url;\n \tint url_nr;\n \n-\tif (!remote) {\n-\t\tif (repo)\n-\t\t\tdie(\"bad repository '%s'\", repo);\n-\t\tdie(\"No destination configured to push to.\");\n-\t}\n-\n \tif (remote->mirror)\n \t\tflags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);\n \n@@ -171,13 +165,16 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n {\n \tint flags = 0;\n \tint tags = 0;\n+\tint repo_all = 0;\n \tint rc;\n+\tstruct remote *remote;\n \tconst char *repo = NULL;\t/* default repository */\n \n \tstruct option options[] = {\n \t\tOPT_BIT('q', \"quiet\", &flags, \"be quiet\", TRANSPORT_PUSH_QUIET),\n \t\tOPT_BIT('v', \"verbose\", &flags, \"be verbose\", TRANSPORT_PUSH_VERBOSE),\n \t\tOPT_STRING( 0 , \"repo\", &repo, \"repository\", \"repository\"),\n+\t\tOPT_BOOLEAN( 0 , \"repo-all\", &repo_all, \"push to all remote repos\"),\n \t\tOPT_BIT( 0 , \"all\", &flags, \"push all refs\", TRANSPORT_PUSH_ALL),\n \t\tOPT_BIT( 0 , \"mirror\", &flags, \"mirror all refs\",\n \t\t\t    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),\n@@ -197,11 +194,24 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \t\tadd_refspec(\"refs/tags/*\");\n \n \tif (argc > 0) {\n-\t\trepo = argv[0];\n-\t\tset_refspecs(argv + 1, argc - 1);\n+\t\tif (repo_all) {\n+\t\t\tset_refspecs(argv, argc);\n+\t\t} else {\n+\t\t\trepo = argv[0];\n+\t\t\tset_refspecs(argv + 1, argc - 1);\n+\t\t}\n \t}\n \n-\trc = do_push(repo, flags);\n+\tremote = remote_get(repo);\n+\tif (!remote && !repo_all) {\n+\t\tif (repo)\n+\t\t\tdie(\"bad repository '%s'\", repo);\n+\t\tdie(\"No destination configured to push to.\");\n+\t}\n+\n+\trc = repo_all ?\n+\t\tfor_each_remote(do_push, &flags) : do_push(remote, &flags);\n+\n \tif (rc == -1)\n \t\tusage_with_options(push_usage, options);\n \telse\ndiff --git a/t/t5523-push-repo-all.sh b/t/t5523-push-repo-all.sh\nnew file mode 100755\nindex 0000000..865b8a1\n--- /dev/null\n+++ b/t/t5523-push-repo-all.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+\n+test_description='pushing to all remote repos repository'\n+\n+. ./test-lib.sh\n+\n+mk_repos () {\n+\trm -rf maste mirror-1 mirror-2 &&\n+\tmkdir mirror-1 &&\n+\t(\n+\t\tcd mirror-1 &&\n+\t\tgit init\n+\t) &&\n+\tmkdir mirror-2 &&\n+\t(\n+\t\tcd mirror-2 &&\n+\t\tgit init\n+\t) &&\n+\tmkdir master &&\n+\t(\n+\t\tcd master &&\n+\t\tgit init &&\n+\t\tgit remote add mirror-1 ../mirror-1\n+\t\tgit remote add mirror-2 ../mirror-2\n+\t)\n+}\n+\n+\n+test_expect_success 'push to mirrors' '\n+\n+\tmk_repos &&\n+\t(\n+\t\tcd master &&\n+\t\techo one >foo && git add foo && git commit -m one &&\n+\t\tgit remote show &&\n+\t\tgit push --all --repo-all -f\n+\t) &&\n+\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n+\tmirror_1_master=$(cd mirror-1 && git show-ref -s --verify refs/heads/master) &&\n+\tmirror_2_master=$(cd mirror-2 && git show-ref -s --verify refs/heads/master) &&\n+\ttest \"$master_master\" = \"$mirror_1_master\" &&\n+\ttest \"$master_master\" = \"$mirror_2_master\"\n+\n+'\n+\n+test_done\n-- \n1.6.2\n"},{"id":"123486","messageId":"m3r5u43a8h.fsf@localhost.localdomain","threadId":"20997","inReplyTo":"1253258222-11475-1-git-send-email-catap@catap.ru","subject":"Re: [PATCH] git-push: add option --repo-all","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-09-18T08:52:49Z","receivedAt":"2009-09-18T08:52:49Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"\"Kirill A. Korinskiy\" <catap@catap.ru> writes:\n\n> Example of usage: I write some software on my laptop and some time\n> pushing to my home/private server for backup. Some time ago my\n> software is done and I openin it on github, but I'm don't like kill my\n> private repos. Now update a two remotes repo is'n sexy, because I'm\n> need using a some shell wrapper:\n> \n>     git remote show | while read repo; do git push $repo; done\n\nSignoff?\n\n> ---\n>  Documentation/git-push.txt |    4 ++-\n>  builtin-push.c             |   34 +++++++++++++++++++++-----------\n>  t/t5523-push-repo-all.sh   |   46 ++++++++++++++++++++++++++++++++++++++++++++\n>  3 files changed, 71 insertions(+), 13 deletions(-)\n>  create mode 100755 t/t5523-push-repo-all.sh\n\nI have created 'pushall' *alias* for that purpose, but I think that\nsuch functionality would be better added to \"git remote\" rather than\nto \"git push\".\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"123487","messageId":"1253270643-20262-1-git-send-email-catap@catap.ru","threadId":"20997","inReplyTo":"m3r5u43a8h.fsf@localhost.localdomain","subject":"[PATCH] git-push: add option --repo-all","fromName":"Kirill A. Korinskiy","fromEmail":"catap@catap.ru","sentAt":"2009-09-18T10:44:03Z","receivedAt":"2009-09-18T10:44:03Z","isPatch":true,"sender":{"key":"catap@catap.ru","avatar":"https://gravatar.com/avatar/ea0ab2c29579606bd684eccdf786c666f4425bedc4e599b698a175f12737b1c5?d=mp&s=160"},"body":"Example of usage: I write some software on my laptop and some time\npushing to my home/private server for backup. Some time ago my\nsoftware is done and I openin it on github, but I'm don't like kill my\nprivate repos. Now update a two remotes repo is'n sexy, because I'm\nneed using a some shell wrapper:\n\n    git remote show | while read repo; do git push $repo; done\n\nSigned-off-by: Kirill A. Korinskiy <catap@catap.ru>\n---\n Documentation/git-push.txt |    3 ++\n builtin-push.c             |   34 +++++++++++++++++++++-----------\n t/t5523-push-repo-all.sh   |   46 ++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 71 insertions(+), 12 deletions(-)\n create mode 100755 t/t5523-push-repo-all.sh\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex ba6a8a2..92e45c2 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -134,6 +134,9 @@ useful if you write an alias or script around 'git-push'.\n \ttransfer spends extra cycles to minimize the number of\n \tobjects to be sent and meant to be used on slower connection.\n \n+--repo-all::\n+\tSend changes to all remote repos.\n+\n -v::\n --verbose::\n \tRun verbosely.\ndiff --git a/builtin-push.c b/builtin-push.c\nindex 3cb1ee4..2b25293 100644\n--- a/builtin-push.c\n+++ b/builtin-push.c\n@@ -10,7 +10,7 @@\n #include \"parse-options.h\"\n \n static const char * const push_usage[] = {\n-\t\"git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]\",\n+\t\"git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository> | --repo-all] [-f | --force] [-v] [<repository> <refspec>...]\",\n \tNULL,\n };\n \n@@ -88,19 +88,13 @@ static void setup_default_push_refspecs(void)\n \t}\n }\n \n-static int do_push(const char *repo, int flags)\n+static int do_push(struct remote *remote, void *priv)\n {\n+\tint flags = *((int *)priv);\n \tint i, errs;\n-\tstruct remote *remote = remote_get(repo);\n \tconst char **url;\n \tint url_nr;\n \n-\tif (!remote) {\n-\t\tif (repo)\n-\t\t\tdie(\"bad repository '%s'\", repo);\n-\t\tdie(\"No destination configured to push to.\");\n-\t}\n-\n \tif (remote->mirror)\n \t\tflags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);\n \n@@ -171,13 +165,16 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n {\n \tint flags = 0;\n \tint tags = 0;\n+\tint repo_all = 0;\n \tint rc;\n+\tstruct remote *remote;\n \tconst char *repo = NULL;\t/* default repository */\n \n \tstruct option options[] = {\n \t\tOPT_BIT('q', \"quiet\", &flags, \"be quiet\", TRANSPORT_PUSH_QUIET),\n \t\tOPT_BIT('v', \"verbose\", &flags, \"be verbose\", TRANSPORT_PUSH_VERBOSE),\n \t\tOPT_STRING( 0 , \"repo\", &repo, \"repository\", \"repository\"),\n+\t\tOPT_BOOLEAN( 0 , \"repo-all\", &repo_all, \"push to all remote repos\"),\n \t\tOPT_BIT( 0 , \"all\", &flags, \"push all refs\", TRANSPORT_PUSH_ALL),\n \t\tOPT_BIT( 0 , \"mirror\", &flags, \"mirror all refs\",\n \t\t\t    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),\n@@ -197,11 +194,24 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \t\tadd_refspec(\"refs/tags/*\");\n \n \tif (argc > 0) {\n-\t\trepo = argv[0];\n-\t\tset_refspecs(argv + 1, argc - 1);\n+\t\tif (repo_all) {\n+\t\t\tset_refspecs(argv, argc);\n+\t\t} else {\n+\t\t\trepo = argv[0];\n+\t\t\tset_refspecs(argv + 1, argc - 1);\n+\t\t}\n \t}\n \n-\trc = do_push(repo, flags);\n+\tremote = remote_get(repo);\n+\tif (!remote && !repo_all) {\n+\t\tif (repo)\n+\t\t\tdie(\"bad repository '%s'\", repo);\n+\t\tdie(\"No destination configured to push to.\");\n+\t}\n+\n+\trc = repo_all ?\n+\t\tfor_each_remote(do_push, &flags) : do_push(remote, &flags);\n+\n \tif (rc == -1)\n \t\tusage_with_options(push_usage, options);\n \telse\ndiff --git a/t/t5523-push-repo-all.sh b/t/t5523-push-repo-all.sh\nnew file mode 100755\nindex 0000000..865b8a1\n--- /dev/null\n+++ b/t/t5523-push-repo-all.sh\n@@ -0,0 +1,46 @@\n+#!/bin/sh\n+\n+test_description='pushing to all remote repos repository'\n+\n+. ./test-lib.sh\n+\n+mk_repos () {\n+\trm -rf maste mirror-1 mirror-2 &&\n+\tmkdir mirror-1 &&\n+\t(\n+\t\tcd mirror-1 &&\n+\t\tgit init\n+\t) &&\n+\tmkdir mirror-2 &&\n+\t(\n+\t\tcd mirror-2 &&\n+\t\tgit init\n+\t) &&\n+\tmkdir master &&\n+\t(\n+\t\tcd master &&\n+\t\tgit init &&\n+\t\tgit remote add mirror-1 ../mirror-1\n+\t\tgit remote add mirror-2 ../mirror-2\n+\t)\n+}\n+\n+\n+test_expect_success 'push to mirrors' '\n+\n+\tmk_repos &&\n+\t(\n+\t\tcd master &&\n+\t\techo one >foo && git add foo && git commit -m one &&\n+\t\tgit remote show &&\n+\t\tgit push --all --repo-all -f\n+\t) &&\n+\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n+\tmirror_1_master=$(cd mirror-1 && git show-ref -s --verify refs/heads/master) &&\n+\tmirror_2_master=$(cd mirror-2 && git show-ref -s --verify refs/heads/master) &&\n+\ttest \"$master_master\" = \"$mirror_1_master\" &&\n+\ttest \"$master_master\" = \"$mirror_2_master\"\n+\n+'\n+\n+test_done\n-- \n1.6.2\n"},{"id":"123488","messageId":"200909181302.49335.jnareb@gmail.com","threadId":"20997","inReplyTo":"877hvwzkw7.wl%catap@catap.ru","subject":"Re: [PATCH] git-push: add option --repo-all","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-09-18T11:02:45Z","receivedAt":"2009-09-18T11:02:45Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Kirill A. Korinskiy wrote:\n> At Fri, 18 Sep 2009 01:52:49 -0700 (PDT),\n> Jakub Narebski <jnareb@gmail.com> wrote:\n> > \"Kirill A. Korinskiy\" <catap@catap.ru> writes:\n\n> > > ---\n> > >  Documentation/git-push.txt |    4 ++-\n> > >  builtin-push.c             |   34 +++++++++++++++++++++-----------\n> > >  t/t5523-push-repo-all.sh   |   46 ++++++++++++++++++++++++++++++++++++++++++++\n> > >  3 files changed, 71 insertions(+), 13 deletions(-)\n> > >  create mode 100755 t/t5523-push-repo-all.sh\n> > \n> > I have created 'pushall' *alias* for that purpose, but I think that\n> > such functionality would be better added to \"git remote\" rather than\n> > to \"git push\".\n> \n> not sure, because git remote make interface for managment remotes\n> repos and push make interface for pushing to remote repo. I just add a\n> pushing to all repos.\n> \n> I thought about pushing to some remotes repos, yes, but could not come\n> up with a good symantics.\n\nWell, git-remote has \"git remote update\" subcommand for fetching from\na group of remote repositories, so it is not only about managing remotes.\nI think \"git remote push\" (or something like that) would fit in \ngit-remote area of competence.\n\nBesides git-remote understands groups of remote repositories for fetch\n(update), which would be (I think) a good idea also for push.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"123489","messageId":"4AB36BEF.5050508@gnu.org","threadId":"20997","inReplyTo":"200909181302.49335.jnareb@gmail.com","subject":"Re: [PATCH] git-push: add option --repo-all","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2009-09-18T11:15:59Z","receivedAt":"2009-09-18T11:15:59Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"\n> Well, git-remote has \"git remote update\" subcommand for fetching from\n> a group of remote repositories, so it is not only about managing remotes.\n> I think \"git remote push\" (or something like that) would fit in\n> git-remote area of competence.\n>\n> Besides git-remote understands groups of remote repositories for fetch\n> (update), which would be (I think) a good idea also for push.\n\nAgreed.\n\nPaolo\n"},{"id":"123495","messageId":"7v8wgcb3w6.fsf@alter.siamese.dyndns.org","threadId":"20997","inReplyTo":"m3r5u43a8h.fsf@localhost.localdomain","subject":"Re: [PATCH] git-push: add option --repo-all","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-09-18T16:42:49Z","receivedAt":"2009-09-18T16:42:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> I have created 'pushall' *alias* for that purpose, but I think that\n> such functionality would be better added to \"git remote\" rather than\n> to \"git push\".\n\nAlso Linus added a mystery feature that you can have more than one pushURL\nto a [remote \"there\"] section to push to multiple places quite a while\nago, so use of it is another possibile solution for what Kirill wants to\nsolve.\n\nI do not think it is such a useful command line option that can be used to\nonly say \"everything\"; your suggestion to hook into the grouping mechanism\n\"git remote\" has sounds much nicer.\n\nThanks.\n"}]}