All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC/PATCH] remote: add new sync command
@ 2011-11-07 16:07 Felipe Contreras
  2011-11-07 17:22 ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-07 16:07 UTC (permalink / raw)
  To: git; +Cc: Felipe Contreras

This is useful to mirror all the branches in the current repo to
another.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-remote.txt |   17 +++++++
 builtin/remote.c             |  108 ++++++++++++++++++++++++++++++++++++++++++
 t/t5505-remote.sh            |   15 ++++++
 3 files changed, 140 insertions(+), 0 deletions(-)

diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 5a8c506..643fc8b 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -21,6 +21,7 @@ SYNOPSIS
 'git remote' [-v | --verbose] 'show' [-n] <name>
 'git remote prune' [-n | --dry-run] <name>
 'git remote' [-v | --verbose] 'update' [-p | --prune] [(<group> | <remote>)...]
+'git remote sync' <name> [-a | --all] [-n | --new] [-p | --prune] [-f | --force] [--dry-run]
 
 DESCRIPTION
 -----------
@@ -169,6 +170,22 @@ be updated.  (See linkgit:git-config[1]).
 +
 With `--prune` option, prune all the remotes that are updated.
 
+'sync'::
+
+Synchronizes local branches with certain remote. This is useful to backup all
+the branches in a local repository to a remote one, regardless of what upstream
+is configured for each branch.
++
+With `--prune`, remote branches will be deleted if they are not also locally.
++
+With `--new`, local branches that are not yet in the remote will be pushed too.
++
+With `--all`, basically both `--prune` and `--new` will be selected.
++
+With `--force`, existing branches will be forced to update, like `git push
+--force`.
++
+With `--dry-run`, all the changes will be reported, but not really happen.
 
 DISCUSSION
 ----------
diff --git a/builtin/remote.c b/builtin/remote.c
index e1285be..b3b9b19 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -64,6 +64,11 @@ static const char * const builtin_remote_update_usage[] = {
 	NULL
 };
 
+static const char * const builtin_remote_sync_usage[] = {
+	"git remote sync <name> [-a|--all] [-n|--new] [-p|--prune] [<options>]",
+	NULL
+};
+
 static const char * const builtin_remote_seturl_usage[] = {
 	"git remote set-url [--push] <name> <newurl> [<oldurl>]",
 	"git remote set-url --add <name> <newurl>",
@@ -1492,6 +1497,107 @@ static int set_url(int argc, const char **argv)
 	return 0;
 }
 
+struct action {
+	struct string_list *list;
+	int type;
+};
+
+static int ref_cb(const char *refname,
+	const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct action *action = cb_data;
+	struct string_list_item *item;
+	if (strcmp(refname, "HEAD") == 0)
+		return 0;
+	item = string_list_insert(action->list, refname);
+	item->util = (void *)((long)item->util | action->type);
+	return 0;
+}
+
+static int for_each_in_remote_ref(const char *name, each_ref_fn fn, void *cb_data)
+{
+	char prefix[1000];
+	sprintf(prefix, "refs/remotes/%s/", name);
+	return for_each_ref_in(prefix, fn, cb_data);
+}
+
+static int do_sync(int argc, const char **argv)
+{
+	const char *remotename;
+	struct string_list list;
+	struct action action;
+	struct remote *remote;
+	struct transport *transport;
+	int i, r, nonff;
+	char **refspec;
+	int refspec_nr = 0;
+	int prune = 0, new = 0, all = 0, flags = 0;
+
+	struct option options[] = {
+		OPT_BOOLEAN('p', "prune", &prune, "prune remote branches"),
+		OPT_BOOLEAN('n', "new", &new, "push new branches"),
+		OPT_BOOLEAN('a', "all", &all, "synchronize everything"),
+		OPT_BIT(0, "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
+		OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
+		OPT_END()
+	};
+	argc = parse_options(argc, argv, NULL, options, builtin_remote_sync_usage,
+			     PARSE_OPT_KEEP_ARGV0);
+	if (argc < 2 || argc > 2)
+		usage_with_options(builtin_remote_sync_usage, options);
+
+	if (all)
+		prune = new = 1;
+
+	remotename = argv[1];
+	if (!remote_is_configured(remotename))
+		die("No such remote '%s'", remotename);
+
+	memset(&list, 0, sizeof(list));
+
+	action.list = &list;
+
+	action.type = 1;
+	for_each_in_remote_ref(remotename, ref_cb, &action);
+
+	action.type = 2;
+	for_each_branch_ref(ref_cb, &action);
+
+	refspec = xmalloc(sizeof(*refspec) * list.nr);
+
+	for (i = 0; i < list.nr; i++) {
+		const char *str = list.items[i].string;
+		char *t = NULL;
+
+		switch ((long)list.items[i].util) {
+		case 1:
+			if (prune)
+				asprintf(&t, ":%s", str);
+			break;
+		case 2:
+			if (new)
+				t = strdup(str);
+			break;
+		case 3:
+			t = strdup(str);
+			break;
+		}
+		if (t)
+			refspec[refspec_nr++] = t;
+	}
+
+	remote = remote_get(remotename);
+	transport = transport_get(remote, NULL);
+	r = transport_push(transport, refspec_nr, (const char **)refspec, flags, &nonff);
+
+	for (i = 0; i < refspec_nr; i++)
+		free(refspec[i]);
+
+	string_list_clear(&list, 0);
+
+	return r;
+}
+
 static int get_one_entry(struct remote *remote, void *priv)
 {
 	struct string_list *list = priv;
@@ -1581,6 +1687,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
 		result = prune(argc, argv);
 	else if (!strcmp(argv[0], "update"))
 		result = update(argc, argv);
+	else if (!strcmp(argv[0], "sync"))
+		result = do_sync(argc, argv);
 	else {
 		error("Unknown subcommand: %s", argv[0]);
 		usage_with_options(builtin_remote_usage, options);
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index e8af615..13378c5 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -997,4 +997,19 @@ test_expect_success 'remote set-url --delete baz' '
 	cmp expect actual
 '
 
+test_expect_success 'remote sync' '
+	setup_repository sync-origin &&
+	(cd sync-origin &&
+	 git branch another &&
+	 git config receive.denyCurrentBranch ignore) &&
+	git clone sync-origin sync &&
+	(cd sync &&
+	 git branch -a > /tmp/a &&
+	 git remote sync origin &&
+	 git commit --allow-empty -m "Test" &&
+	 git checkout side &&
+	 git commit --allow-empty -m "Test" &&
+	 git remote sync -a origin)
+'
+
 test_done
-- 
1.7.7

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 16:07 [RFC/PATCH] remote: add new sync command Felipe Contreras
@ 2011-11-07 17:22 ` Jeff King
  2011-11-07 18:35   ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-07 17:22 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Mon, Nov 07, 2011 at 06:07:12PM +0200, Felipe Contreras wrote:

> This is useful to mirror all the branches in the current repo to
> another.
> [...]
> +'sync'::
> +
> +Synchronizes local branches with certain remote. This is useful to backup all
> +the branches in a local repository to a remote one, regardless of what upstream
> +is configured for each branch.
> ++
> +With `--prune`, remote branches will be deleted if they are not also locally.
> ++
> +With `--new`, local branches that are not yet in the remote will be pushed too.
> ++
> +With `--all`, basically both `--prune` and `--new` will be selected.
> ++
> +With `--force`, existing branches will be forced to update, like `git push
> +--force`.
> ++
> +With `--dry-run`, all the changes will be reported, but not really happen.

Why is this in "git remote", and not "git push"?  The former is usually
about managing the configuration of remotes, not about actually doing
the ref transfer (the "-f" flag excepted, but that is clearly just
calling out to "fetch").

And how does this differ from "git push --mirror"? It looks like you
have more options for what pushing all versus pruning, but wouldn't it
be better for "git push" to grow those options?

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 17:22 ` Jeff King
@ 2011-11-07 18:35   ` Felipe Contreras
  2011-11-07 18:39     ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-07 18:35 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Nov 7, 2011 at 7:22 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 07, 2011 at 06:07:12PM +0200, Felipe Contreras wrote:
>
>> This is useful to mirror all the branches in the current repo to
>> another.
>> [...]
>> +'sync'::
>> +
>> +Synchronizes local branches with certain remote. This is useful to backup all
>> +the branches in a local repository to a remote one, regardless of what upstream
>> +is configured for each branch.
>> ++
>> +With `--prune`, remote branches will be deleted if they are not also locally.
>> ++
>> +With `--new`, local branches that are not yet in the remote will be pushed too.
>> ++
>> +With `--all`, basically both `--prune` and `--new` will be selected.
>> ++
>> +With `--force`, existing branches will be forced to update, like `git push
>> +--force`.
>> ++
>> +With `--dry-run`, all the changes will be reported, but not really happen.
>
> Why is this in "git remote", and not "git push"?  The former is usually
> about managing the configuration of remotes, not about actually doing
> the ref transfer (the "-f" flag excepted, but that is clearly just
> calling out to "fetch").

I don't know, seems logical to me what 'git remote sync' does, but
'git push sync'? That sounds weird, and there are no 'git push foo'
commands.

> And how does this differ from "git push --mirror"? It looks like you
> have more options for what pushing all versus pruning, but wouldn't it
> be better for "git push" to grow those options?

But how? --mirror is just an option, I want a separate command, with
it's own options.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 18:35   ` Felipe Contreras
@ 2011-11-07 18:39     ` Jeff King
  2011-11-07 20:51       ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-07 18:39 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Mon, Nov 07, 2011 at 08:35:07PM +0200, Felipe Contreras wrote:

> I don't know, seems logical to me what 'git remote sync' does, but
> 'git push sync'? That sounds weird, and there are no 'git push foo'
> commands.

What I don't understand is why it is not:

  git push --mirror <URL|remote>

> > And how does this differ from "git push --mirror"? It looks like you
> > have more options for what pushing all versus pruning, but wouldn't it
> > be better for "git push" to grow those options?
> 
> But how? --mirror is just an option, I want a separate command, with
> it's own options.

That's what I don't understand from your proposal. Your command is just
pushing something to the remote, right? Why isn't "push" the command,
and your sync options become options to push?

Can you step back and describe the problem you're trying to solve? Maybe
we're not connecting there.

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 18:39     ` Jeff King
@ 2011-11-07 20:51       ` Felipe Contreras
  2011-11-07 21:01         ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-07 20:51 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Nov 7, 2011 at 8:39 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 07, 2011 at 08:35:07PM +0200, Felipe Contreras wrote:
>
>> I don't know, seems logical to me what 'git remote sync' does, but
>> 'git push sync'? That sounds weird, and there are no 'git push foo'
>> commands.
>
> What I don't understand is why it is not:
>
>  git push --mirror <URL|remote>

Because that pushes *everything*.

>> > And how does this differ from "git push --mirror"? It looks like you
>> > have more options for what pushing all versus pruning, but wouldn't it
>> > be better for "git push" to grow those options?
>>
>> But how? --mirror is just an option, I want a separate command, with
>> it's own options.
>
> That's what I don't understand from your proposal. Your command is just
> pushing something to the remote, right? Why isn't "push" the command,
> and your sync options become options to push?

How exactly? --sync-prune, --sync-new, --sync-all? But actually, I was
thinking on adding an option to sync the other way around; to get all
the remote branches and have them locally.

> Can you step back and describe the problem you're trying to solve? Maybe
> we're not connecting there.

Well, I usually have quite a lot of branches in my local repositories,
like a dozen of so. And I like to back them up in some remote
repository, however, not all the branches all the time. git push
--mirror not only pushes branches, but also tags (and I don't want
that), and even other refs. Does that clarifies things?

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 20:51       ` Felipe Contreras
@ 2011-11-07 21:01         ` Jeff King
  2011-11-07 21:25           ` Junio C Hamano
  2011-11-08 17:31           ` Felipe Contreras
  0 siblings, 2 replies; 26+ messages in thread
From: Jeff King @ 2011-11-07 21:01 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Mon, Nov 07, 2011 at 10:51:10PM +0200, Felipe Contreras wrote:

> > What I don't understand is why it is not:
> >
> >  git push --mirror <URL|remote>
> 
> Because that pushes *everything*.

Ahh, I think I see. It is doing --mirror, but only on a reduced refspec?

In that case, is there a reason that:

  git push --prune <URL|remote> refs/heads/*

would not do what you want (note that "--prune" does not exist, but I
think it should).

> > That's what I don't understand from your proposal. Your command is just
> > pushing something to the remote, right? Why isn't "push" the command,
> > and your sync options become options to push?
> 
> How exactly? --sync-prune, --sync-new, --sync-all? But actually, I was
> thinking on adding an option to sync the other way around; to get all
> the remote branches and have them locally.

If I understand correctly, you have three modes:

  1. update remote refs with local values, prune anything remote that we
     don't have locally (--sync-prune)

  2. update remote refs with local values, including pushing anything
     new that we don't have locally (--sync-new)

  3. push new and prune (i.e., 1 and 2 together)

If we had "git push --prune" as above, those would be:

  1. git push --prune <remote> :

     I.e., use the "matching" refspec to not push new things, but turn
     on pruning.

  2. git push <remote> refs/heads/*

     Turn off pruning, but use an explicit refspec, not just "matching",
     which will push all local branches.

  3. git push --prune <remote> refs/heads/*

     Turn on both features.

> Well, I usually have quite a lot of branches in my local repositories,
> like a dozen of so. And I like to back them up in some remote
> repository, however, not all the branches all the time. git push
> --mirror not only pushes branches, but also tags (and I don't want
> that), and even other refs. Does that clarifies things?

That makes sense. But I think it fits in with git's current UI to do
this via a combination of push options and refspecs. Even if we want to
wrap it in some "git remote" command for convenience, I think what
you're asking should be implemented as part of "git push".

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 21:01         ` Jeff King
@ 2011-11-07 21:25           ` Junio C Hamano
  2011-11-07 21:31             ` Jeff King
  2011-11-08 16:43             ` Felipe Contreras
  2011-11-08 17:31           ` Felipe Contreras
  1 sibling, 2 replies; 26+ messages in thread
From: Junio C Hamano @ 2011-11-07 21:25 UTC (permalink / raw)
  To: Jeff King; +Cc: Felipe Contreras, git

Jeff King <peff@peff.net> writes:

> That makes sense. But I think it fits in with git's current UI to do
> this via a combination of push options and refspecs. Even if we want to
> wrap it in some "git remote" command for convenience, I think what
> you're asking should be implemented as part of "git push".

Yeah, I think it makes sense to give --prune to "push" just like "fetch"
already has. These two are the primary (and in the ideal world, only)
operations that talk to the outside world. "remote add -f" might have been
a tempting "convenience" feature, but I personally think it probably was a
mistake for the exact reason that letting anything but "push" and "fetch"
talk to the outside world just invites more confusion. There does not have
to be 47 different ways to do the same thing.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 21:25           ` Junio C Hamano
@ 2011-11-07 21:31             ` Jeff King
  2011-11-08 16:43             ` Felipe Contreras
  1 sibling, 0 replies; 26+ messages in thread
From: Jeff King @ 2011-11-07 21:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Felipe Contreras, git

On Mon, Nov 07, 2011 at 01:25:23PM -0800, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > That makes sense. But I think it fits in with git's current UI to do
> > this via a combination of push options and refspecs. Even if we want to
> > wrap it in some "git remote" command for convenience, I think what
> > you're asking should be implemented as part of "git push".
> 
> Yeah, I think it makes sense to give --prune to "push" just like "fetch"
> already has. These two are the primary (and in the ideal world, only)
> operations that talk to the outside world. "remote add -f" might have been
> a tempting "convenience" feature, but I personally think it probably was a
> mistake for the exact reason that letting anything but "push" and "fetch"
> talk to the outside world just invites more confusion. There does not have
> to be 47 different ways to do the same thing.

I don't mind "add -f" too much, which is at least very clear that it is
simply a convenience feature for "git remote add foo && git fetch foo".
But the other "git remote" features like "set-head -a", which can't be
done any other way, or the "auto-check-what-the-remote-has" feature of
"git remote show" are a little gross.

Anyway, I think we are on the same page; this feature (and btw, I think
this is a great feature that we should have) should go into "push".

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 21:25           ` Junio C Hamano
  2011-11-07 21:31             ` Jeff King
@ 2011-11-08 16:43             ` Felipe Contreras
  2011-11-08 17:49               ` Junio C Hamano
  1 sibling, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-08 16:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git

On Mon, Nov 7, 2011 at 11:25 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jeff King <peff@peff.net> writes:
>
>> That makes sense. But I think it fits in with git's current UI to do
>> this via a combination of push options and refspecs. Even if we want to
>> wrap it in some "git remote" command for convenience, I think what
>> you're asking should be implemented as part of "git push".
>
> Yeah, I think it makes sense to give --prune to "push" just like "fetch"
> already has. These two are the primary (and in the ideal world, only)
> operations that talk to the outside world. "remote add -f" might have been
> a tempting "convenience" feature, but I personally think it probably was a
> mistake for the exact reason that letting anything but "push" and "fetch"
> talk to the outside world just invites more confusion. There does not have
> to be 47 different ways to do the same thing.

What about 'git remote update'?

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-07 21:01         ` Jeff King
  2011-11-07 21:25           ` Junio C Hamano
@ 2011-11-08 17:31           ` Felipe Contreras
  2011-11-08 18:14             ` Jeff King
  1 sibling, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-08 17:31 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Nov 7, 2011 at 11:01 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 07, 2011 at 10:51:10PM +0200, Felipe Contreras wrote:
>
>> > What I don't understand is why it is not:
>> >
>> >  git push --mirror <URL|remote>
>>
>> Because that pushes *everything*.
>
> Ahh, I think I see. It is doing --mirror, but only on a reduced refspec?
>
> In that case, is there a reason that:
>
>  git push --prune <URL|remote> refs/heads/*
>
> would not do what you want (note that "--prune" does not exist, but I
> think it should).

I guess that should work.

>> > That's what I don't understand from your proposal. Your command is just
>> > pushing something to the remote, right? Why isn't "push" the command,
>> > and your sync options become options to push?
>>
>> How exactly? --sync-prune, --sync-new, --sync-all? But actually, I was
>> thinking on adding an option to sync the other way around; to get all
>> the remote branches and have them locally.
>
> If I understand correctly, you have three modes:
>
>  1. update remote refs with local values, prune anything remote that we
>     don't have locally (--sync-prune)
>
>  2. update remote refs with local values, including pushing anything
>     new that we don't have locally (--sync-new)

Anything new that we don't have *remotely*.

>  3. push new and prune (i.e., 1 and 2 together)

Yeap.

> If we had "git push --prune" as above, those would be:
>
>  1. git push --prune <remote> :
>
>     I.e., use the "matching" refspec to not push new things, but turn
>     on pruning.

I guess so, but ":" seems a bit obscure.

>  2. git push <remote> refs/heads/*
>
>     Turn off pruning, but use an explicit refspec, not just "matching",
>     which will push all local branches.

Isn't refs/heads/* the same as --all? BTW. I think --all is confusing,
should be --branches, or something.

>  3. git push --prune <remote> refs/heads/*
>
>     Turn on both features.

Maybe 'git push' options should be reorganized (for 1.8.0):

--all -> --branches
--tags (same)
--mirror -> --all
--update = :
--prune (new)

In the meantime, we could add --update and --prune, which would not conflict.

>> Well, I usually have quite a lot of branches in my local repositories,
>> like a dozen of so. And I like to back them up in some remote
>> repository, however, not all the branches all the time. git push
>> --mirror not only pushes branches, but also tags (and I don't want
>> that), and even other refs. Does that clarifies things?
>
> That makes sense. But I think it fits in with git's current UI to do
> this via a combination of push options and refspecs. Even if we want to
> wrap it in some "git remote" command for convenience, I think what
> you're asking should be implemented as part of "git push".

Perhaps. I will give that a try, let's see how the code ends up.

But then, maybe similar options should be added to 'git fetch' to do
the same in the opposite direction, and that's where things get a bit
ugly:

--all -> rename to --all-remotes?
--prune -> rename to --prune-tracking?
--prune-local (new; prune local branches that don't exist on the remote)
--all (new; similar to 'git push --all' [--mirror])
--tags (same)
--update (new; similar to 'git push --update')
--branches (new; similar to 'git push --branches')

Somehow I fell there should be a 'sync' command somewhere to
differentiate these options from normal 'git fetch/push' commands.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-08 16:43             ` Felipe Contreras
@ 2011-11-08 17:49               ` Junio C Hamano
  2011-11-08 17:59                 ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Junio C Hamano @ 2011-11-08 17:49 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Jeff King, git

Felipe Contreras <felipe.contreras@gmail.com> writes:

> On Mon, Nov 7, 2011 at 11:25 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> Jeff King <peff@peff.net> writes:
>>
>>> That makes sense. But I think it fits in with git's current UI to do
>>> this via a combination of push options and refspecs. Even if we want to
>>> wrap it in some "git remote" command for convenience, I think what
>>> you're asking should be implemented as part of "git push".
>>
>> Yeah, I think it makes sense to give --prune to "push" just like "fetch"
>> already has. These two are the primary (and in the ideal world, only)
>> operations that talk to the outside world. "remote add -f" might have been
>> a tempting "convenience" feature, but I personally think it probably was a
>> mistake for the exact reason that letting anything but "push" and "fetch"
>> talk to the outside world just invites more confusion. There does not have
>> to be 47 different ways to do the same thing.
>
> What about 'git remote update'?

If you asked, I would have to say that is probably a worse mistake in the
hindsight. I am guessing that back them "remote" command might have been a
tool meant only for the read-only customers and the verb "update" may have
made sense as "update me from the upstream", but these days "remote" also
helps the aspect of pushing things out (e.g. "set-url --push"), so "update"
that does not specify the direction is totally an inappropriate verb.

You _could_ argue that adding subcommands and options related to pushing
to "git remote" was a mistake. I don't care too much which side you would
choose to blame, but taken as the whole, in the current set of options,
subcommands and what "git remote" command does, "update" is a complete
misnomer.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-08 17:49               ` Junio C Hamano
@ 2011-11-08 17:59                 ` Felipe Contreras
  2011-11-09  3:36                   ` Junio C Hamano
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-08 17:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git

On Tue, Nov 8, 2011 at 7:49 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
>> On Mon, Nov 7, 2011 at 11:25 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>> Jeff King <peff@peff.net> writes:
>>>
>>>> That makes sense. But I think it fits in with git's current UI to do
>>>> this via a combination of push options and refspecs. Even if we want to
>>>> wrap it in some "git remote" command for convenience, I think what
>>>> you're asking should be implemented as part of "git push".
>>>
>>> Yeah, I think it makes sense to give --prune to "push" just like "fetch"
>>> already has. These two are the primary (and in the ideal world, only)
>>> operations that talk to the outside world. "remote add -f" might have been
>>> a tempting "convenience" feature, but I personally think it probably was a
>>> mistake for the exact reason that letting anything but "push" and "fetch"
>>> talk to the outside world just invites more confusion. There does not have
>>> to be 47 different ways to do the same thing.
>>
>> What about 'git remote update'?
>
> If you asked, I would have to say that is probably a worse mistake in the
> hindsight. I am guessing that back them "remote" command might have been a
> tool meant only for the read-only customers and the verb "update" may have
> made sense as "update me from the upstream", but these days "remote" also
> helps the aspect of pushing things out (e.g. "set-url --push"), so "update"
> that does not specify the direction is totally an inappropriate verb.
>
> You _could_ argue that adding subcommands and options related to pushing
> to "git remote" was a mistake. I don't care too much which side you would
> choose to blame, but taken as the whole, in the current set of options,
> subcommands and what "git remote" command does, "update" is a complete
> misnomer.

Perhaps these 'git remote' commands should be removed in 1.8 then.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-08 17:31           ` Felipe Contreras
@ 2011-11-08 18:14             ` Jeff King
  2011-11-11 12:30               ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-08 18:14 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Tue, Nov 08, 2011 at 07:31:09PM +0200, Felipe Contreras wrote:

> >  2. update remote refs with local values, including pushing anything
> >     new that we don't have locally (--sync-new)
> 
> Anything new that we don't have *remotely*.

Sorry, yeah.

> >  1. git push --prune <remote> :
> >
> >     I.e., use the "matching" refspec to not push new things, but turn
> >     on pruning.
> 
> I guess so, but ":" seems a bit obscure.

Yeah, it is. It's also the default, so you could just do:

  git push --prune <remote>

Although some people have argued for changing the default in future
versions. I don't know what the status of that is.

> >  2. git push <remote> refs/heads/*
> >
> >     Turn off pruning, but use an explicit refspec, not just "matching",
> >     which will push all local branches.
> 
> Isn't refs/heads/* the same as --all? BTW. I think --all is confusing,
> should be --branches, or something.

Doesn't --all mean all refs, including tags and branches? I thought that
was the thing you were avoiding. We could add syntactic sugar to make
--branches mean "refs/heads/*". But I do worry that pseudo-options like
that just end up creating more confusion (I seem to recall there being a
lot of confusion about "--tags", which is more or less the same thing).

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-08 17:59                 ` Felipe Contreras
@ 2011-11-09  3:36                   ` Junio C Hamano
  2011-11-11 10:35                     ` Jakub Narebski
  0 siblings, 1 reply; 26+ messages in thread
From: Junio C Hamano @ 2011-11-09  3:36 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Jeff King, git

Felipe Contreras <felipe.contreras@gmail.com> writes:

> Perhaps these 'git remote' commands should be removed in 1.8 then.

It is true that it was a long-term goal to deprecate many parts of the
"git remote" script that started as a hack to scratch itches "git fetch"
in the older days did not directly scratch for people, e.g. fetching from
multiple remotes in one go.

I do not think 1.7.X series to 1.8 is a big enough jump to remove
duplicated features, though.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-09  3:36                   ` Junio C Hamano
@ 2011-11-11 10:35                     ` Jakub Narebski
  2011-11-11 16:38                       ` Junio C Hamano
  0 siblings, 1 reply; 26+ messages in thread
From: Jakub Narebski @ 2011-11-11 10:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Felipe Contreras, Jeff King, git

Junio C Hamano <gitster@pobox.com> writes:
> Felipe Contreras <felipe.contreras@gmail.com> writes:
> 
> > Perhaps these 'git remote' commands should be removed in 1.8 then.
> 
> It is true that it was a long-term goal to deprecate many parts of the
> "git remote" script that started as a hack to scratch itches "git fetch"
> in the older days did not directly scratch for people, e.g. fetching from
> multiple remotes in one go.
> 
> I do not think 1.7.X series to 1.8 is a big enough jump to remove
> duplicated features, though.
 
I am using "git remote update" to fetch a _subset_ of remotes;
does "git fetch" offers such feature already?

-- 
Jakub Narębski

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-08 18:14             ` Jeff King
@ 2011-11-11 12:30               ` Felipe Contreras
  2011-11-11 18:13                 ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-11 12:30 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Tue, Nov 8, 2011 at 8:14 PM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 08, 2011 at 07:31:09PM +0200, Felipe Contreras wrote:
>
>> >  1. git push --prune <remote> :
>> >
>> >     I.e., use the "matching" refspec to not push new things, but turn
>> >     on pruning.
>>
>> I guess so, but ":" seems a bit obscure.
>
> Yeah, it is. It's also the default, so you could just do:
>
>  git push --prune <remote>

That would work only if not configured otherwise; remote.<foo>.push,
push.default

> Although some people have argued for changing the default in future
> versions. I don't know what the status of that is.

IMO the default doesn't matter, it should be easy for everyone.

>> >  2. git push <remote> refs/heads/*
>> >
>> >     Turn off pruning, but use an explicit refspec, not just "matching",
>> >     which will push all local branches.
>>
>> Isn't refs/heads/* the same as --all? BTW. I think --all is confusing,
>> should be --branches, or something.
>
> Doesn't --all mean all refs, including tags and branches?

Nope, only branches, try it. I also found it strange. And what is
more, you can't use --all and --tags at the same time. Totally
strange.

Also, --all doesn't push other refs (say refs/foobar/test)

I think this area has been neglected.

> I thought that was the thing you were avoiding.

--all + --tags is not the same as --mirror (refs/foobar/* is pushed
only by --mirror).

And yes, in this particular use-case that's what I am trying to avoid,
but in other use-cases (like creating a new repo and pushing
*everything*), a *true* --all would be nice.

> We could add syntactic sugar to make
> --branches mean "refs/heads/*". But I do worry that pseudo-options like
> that just end up creating more confusion (I seem to recall there being a
> lot of confusion about "--tags", which is more or less the same thing).

But it's not, that could explain part of the confusion. I think these
would be totally intuitive.

 --branches
 --tags
 --other
 --all
 --update
 --prune

But what about 'git fetch'? You didn't comment anything. I think we
should try to be consistent in these imaginary future options, maybe
to devise a transition, or at least to identify good names for the new
options.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-11 10:35                     ` Jakub Narebski
@ 2011-11-11 16:38                       ` Junio C Hamano
  2011-11-11 22:00                         ` Jakub Narebski
  0 siblings, 1 reply; 26+ messages in thread
From: Junio C Hamano @ 2011-11-11 16:38 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Felipe Contreras, Jeff King, git

Jakub Narebski <jnareb@gmail.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>> Felipe Contreras <felipe.contreras@gmail.com> writes:
>> 
>> > Perhaps these 'git remote' commands should be removed in 1.8 then.
>> 
>> It is true that it was a long-term goal to deprecate many parts of the
>> "git remote" script that started as a hack to scratch itches "git fetch"
>> in the older days did not directly scratch for people, e.g. fetching from
>> multiple remotes in one go.
>> 
>> I do not think 1.7.X series to 1.8 is a big enough jump to remove
>> duplicated features, though.
>  
> I am using "git remote update" to fetch a _subset_ of remotes;
> does "git fetch" offers such feature already?

Heh, look at builtin/remote.c::update() and report what you see.  It just
calls into "git fetch" and let the command fetch either from a single
repository or from a remote group. "git remote update" is not even aware
of the remote groups; the expansion is done by "git fetch".

Whoever added "multiple repositories" feature to "git fetch" in order to
support "remote update <group>" apparently under-documented it.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-11 12:30               ` Felipe Contreras
@ 2011-11-11 18:13                 ` Jeff King
  2011-11-12 22:07                   ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-11 18:13 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Fri, Nov 11, 2011 at 02:30:48PM +0200, Felipe Contreras wrote:

> > Doesn't --all mean all refs, including tags and branches?
> 
> Nope, only branches, try it. I also found it strange. And what is
> more, you can't use --all and --tags at the same time. Totally
> strange.

Yeah, you're right. Sorry for my confusion.

So in that sense, it is poorly named, and "--branches" (or "--heads")
would be more accurate. At the same time, it is probably more likely
what the user wants to do (you almost never want to push "refs/remotes",
for example). So I am a little hesitant to suggest changing it, even
with a warning and deprecation period.

> And yes, in this particular use-case that's what I am trying to avoid,
> but in other use-cases (like creating a new repo and pushing
> *everything*), a *true* --all would be nice.

Right. It looks like that is just spelled "--mirror" (which gives you
pruning also), or "refs/*:refs/*" (without pruning). The latter is even
more flexible, as you could do "refs/*:refs/foo/*" to keep several
related backups in one upstream repo.

Just to get back to the original patch for a second: are we in agreement
that what you want to do with "sync" is almost possible now (modulo a
separate --prune option), and that there is a separate issue of making
friendlier syntax for a few common refspecs?

> > We could add syntactic sugar to make
> > --branches mean "refs/heads/*". But I do worry that pseudo-options like
> > that just end up creating more confusion (I seem to recall there being a
> > lot of confusion about "--tags", which is more or less the same thing).
> 
> But it's not, that could explain part of the confusion. I think these
> would be totally intuitive.
> 
>  --branches
>  --tags
>  --other
>  --all
>  --update
>  --prune

My problem with them syntactically is that you have option-looking
things that are really not flags, but rather syntactic placeholders for
refspecs. So you have:

  git push --prune remote --branches

which looks wrong from the perspective of usual option-parsing rules.
And does:

  git push remote --prune --branches

work? Or:

  git push --prune --branches remote

?

I think we could make them all work if we want. But somehow the syntaxes
just look wrong to me. Using a non-dashed placeholder for special
refspecs makes more sense to me like:

  git push --prune remote BRANCHES

and then it really is just a special way of spelling "refs/heads/*". But
then, I also think it's good for users to understand that the options
are refspecs, and what that means. It's not a hard concept, and then
when they inevitably say "how can I do BRANCHES, except put the result
somewhere else in the remote namespace", it's a very natural extension
to learn about the right-hand side o the refspec.

Of course I also think BRANCHES looks ugly, and people should just learn
"refs/heads/*".

I dunno. Maybe my brain is fried from knowing too much about how git
works. I don't have much of an "ordinary user" perspective anymore.

> But what about 'git fetch'? You didn't comment anything. I think we
> should try to be consistent in these imaginary future options, maybe
> to devise a transition, or at least to identify good names for the new
> options.

Yeah, fetch makes it harder because the options may have subtly
different meanings. Using non-option placeholders would work around
that. You would still have options for pruning, which to me is not
really a refspec, but an option that acts on the refspecs.

>From the list in your previous email, you wrote:

> --prune -> rename to --prune-tracking?
> --prune-local (new; prune local branches that don't exist on the remote)

I think --prune wouldn't need renaming. If you fetch into tracking
branches, then pruning would prune tracking branches. If you fetch as a
mirror (refs/*:refs/*), then you would prune everything.

And "--prune-local" doesn't seem like a fetch operation to me. Either
you are mirroring, and --prune already handles it as above. Or you are
interested in getting rid of branches whose upstream has gone away. But
that's not a fetch operation; that's a branch operation.

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-11 16:38                       ` Junio C Hamano
@ 2011-11-11 22:00                         ` Jakub Narebski
  0 siblings, 0 replies; 26+ messages in thread
From: Jakub Narebski @ 2011-11-11 22:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Felipe Contreras, Jeff King, git

On Fri, 11 Nov 2011, Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
>> Junio C Hamano <gitster@pobox.com> writes:
>>> Felipe Contreras <felipe.contreras@gmail.com> writes:
>>>> 
>>>> Perhaps these 'git remote' commands should be removed in 1.8 then.
>>> 
>>> It is true that it was a long-term goal to deprecate many parts of the
>>> "git remote" script that started as a hack to scratch itches "git fetch"
>>> in the older days did not directly scratch for people, e.g. fetching from
>>> multiple remotes in one go.
>>> 
>>> I do not think 1.7.X series to 1.8 is a big enough jump to remove
>>> duplicated features, though.
>>  
>> I am using "git remote update" to fetch a _subset_ of remotes;
>> does "git fetch" offers such feature already?
> 
> Heh, look at builtin/remote.c::update() and report what you see.  It just
> calls into "git fetch" and let the command fetch either from a single
> repository or from a remote group. "git remote update" is not even aware
> of the remote groups; the expansion is done by "git fetch".
> 
> Whoever added "multiple repositories" feature to "git fetch" in order to
> support "remote update <group>" apparently under-documented it.

Well, it is documented in git-fetch(1), though in slightly piecemeal
fashion.

One difference is that "git remote update" defaults to "default" group
if it is defined, and to "--all" if it isn't.  With "git fetch --multiple"
you have to specify it explicitly ("git fetch --multiple" is a no-op,
I think).

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-11 18:13                 ` Jeff King
@ 2011-11-12 22:07                   ` Felipe Contreras
  2011-11-14 12:25                     ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-12 22:07 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Fri, Nov 11, 2011 at 8:13 PM, Jeff King <peff@peff.net> wrote:
> On Fri, Nov 11, 2011 at 02:30:48PM +0200, Felipe Contreras wrote:
>
>> > Doesn't --all mean all refs, including tags and branches?
>>
>> Nope, only branches, try it. I also found it strange. And what is
>> more, you can't use --all and --tags at the same time. Totally
>> strange.
>
> Yeah, you're right. Sorry for my confusion.
>
> So in that sense, it is poorly named, and "--branches" (or "--heads")
> would be more accurate. At the same time, it is probably more likely
> what the user wants to do (you almost never want to push "refs/remotes",
> for example).

But you do want to push tags, and --all --tags doesn't sound right; if
I'm pushing everything, why do I specify I want to push more stuff.
And then, why it --all --tags disallowed?

> So I am a little hesitant to suggest changing it, even
> with a warning and deprecation period.

It is confusing and wrong, what more reason do you need?

>> And yes, in this particular use-case that's what I am trying to avoid,
>> but in other use-cases (like creating a new repo and pushing
>> *everything*), a *true* --all would be nice.
>
> Right. It looks like that is just spelled "--mirror" (which gives you
> pruning also), or "refs/*:refs/*" (without pruning). The latter is even
> more flexible, as you could do "refs/*:refs/foo/*" to keep several
> related backups in one upstream repo.

So, we agree that --all is the same as 'refs/heads/*'. Therefore we
already have this mixture of refspecs and options.

> Just to get back to the original patch for a second: are we in agreement
> that what you want to do with "sync" is almost possible now (modulo a
> separate --prune option), and that there is a separate issue of making
> friendlier syntax for a few common refspecs?

Yes.

>> > We could add syntactic sugar to make
>> > --branches mean "refs/heads/*". But I do worry that pseudo-options like
>> > that just end up creating more confusion (I seem to recall there being a
>> > lot of confusion about "--tags", which is more or less the same thing).
>>
>> But it's not, that could explain part of the confusion. I think these
>> would be totally intuitive.
>>
>>  --branches
>>  --tags
>>  --other
>>  --all
>>  --update
>>  --prune
>
> My problem with them syntactically is that you have option-looking
> things that are really not flags, but rather syntactic placeholders for
> refspecs.

We already have those: --all -> 'ref/heads/*', --tags -> 'refs/tags/*'.

> So you have:
>
>  git push --prune remote --branches
>
> which looks wrong from the perspective of usual option-parsing rules.
> And does:
>
>  git push remote --prune --branches
>
> work? Or:
>
>  git push --prune --branches remote
>
> ?
>
> I think we could make them all work if we want. But somehow the syntaxes
> just look wrong to me. Using a non-dashed placeholder for special
> refspecs makes more sense to me like:

I don't see any problem with making them all work.

>  git push --prune remote BRANCHES
>
> and then it really is just a special way of spelling "refs/heads/*". But
> then, I also think it's good for users to understand that the options
> are refspecs, and what that means. It's not a hard concept, and then
> when they inevitably say "how can I do BRANCHES, except put the result
> somewhere else in the remote namespace", it's a very natural extension
> to learn about the right-hand side o the refspec.
>
> Of course I also think BRANCHES looks ugly, and people should just learn
> "refs/heads/*".

Look, I'm all in favor of people learning stuff, but I have been
involved in Git since basically day 1, and up to this day I was (am?)
not familiar with refspecs, I don't use them regularly, and never
really had a need to, and that's fine. People are already complaining
about the learning curve of git, and what you are suggesting is that:

Instead of doing:
% git push remote --branches --tags

They should do:
% git push remote 'refs/heads/*' 'refs/tags/*'

I disagree, I think refspecs should remain as plumbing, and there must
be a porcelain way to achieve the options I proposed.

> I dunno. Maybe my brain is fried from knowing too much about how git
> works. I don't have much of an "ordinary user" perspective anymore.

Maybe :)

>> But what about 'git fetch'? You didn't comment anything. I think we
>> should try to be consistent in these imaginary future options, maybe
>> to devise a transition, or at least to identify good names for the new
>> options.
>
> Yeah, fetch makes it harder because the options may have subtly
> different meanings. Using non-option placeholders would work around
> that. You would still have options for pruning, which to me is not
> really a refspec, but an option that acts on the refspecs.
>
> From the list in your previous email, you wrote:
>
>> --prune -> rename to --prune-tracking?
>> --prune-local (new; prune local branches that don't exist on the remote)
>
> I think --prune wouldn't need renaming. If you fetch into tracking
> branches, then pruning would prune tracking branches. If you fetch as a
> mirror (refs/*:refs/*), then you would prune everything.

I'm not going to investigate the subtleties of these different setups,
I'm going to put my common user hat and ask; how do I fetch as a
mirror?

> And "--prune-local" doesn't seem like a fetch operation to me. Either
> you are mirroring, and --prune already handles it as above. Or you are
> interested in getting rid of branches whose upstream has gone away. But
> that's not a fetch operation; that's a branch operation.

This would make things more confusing to the user.

Say on one side I do this push?
% git push test --prune 'refs/heads/*' 'refs/tags/*'

What do I do in the other side to synchronize the repo?
% git fetch test --prune-local 'refs/heads/*:refs/heads/*'
'refs/tags/*:refs/tags/*'

I would prefer this of course:
% git fetch test --all --prune-local

But you are saying it should be:
% git fetch test 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
% git branch --prune-remote test

That doesn't sound right to me; mixing branch operations with a specific remote?

Again, I think conceptually it's much easier to think about these
operations to be related to a specific remote, sure, fetch and push
mostly deal with specific remotes, but even more 'git remote'.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-12 22:07                   ` Felipe Contreras
@ 2011-11-14 12:25                     ` Jeff King
  2011-11-14 13:57                       ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-14 12:25 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Sun, Nov 13, 2011 at 12:07:19AM +0200, Felipe Contreras wrote:

> > So in that sense, it is poorly named, and "--branches" (or "--heads")
> > would be more accurate. At the same time, it is probably more likely
> > what the user wants to do (you almost never want to push "refs/remotes",
> > for example).
> 
> But you do want to push tags, and --all --tags doesn't sound right; if
> I'm pushing everything, why do I specify I want to push more stuff.
> And then, why it --all --tags disallowed?

I agree that "--all --tags" looks silly. I don't know why it's
disallowed; from my reading, it should be a perfectly sensible
operation. You might try digging in the history or the mailing list.

> > So I am a little hesitant to suggest changing it, even
> > with a warning and deprecation period.
> 
> It is confusing and wrong, what more reason do you need?

Because I am worried that "--all" pushing refs/remotes will also be
confusing; it's not what most people are going to want.

If your suggestion is to deprecate the name "--all" and start calling it
"--branches" or "--heads", then that is an improvement. But making
"refs/*:refs/*" easier to accidentally use might not be.

> > Right. It looks like that is just spelled "--mirror" (which gives you
> > pruning also), or "refs/*:refs/*" (without pruning). The latter is even
> > more flexible, as you could do "refs/*:refs/foo/*" to keep several
> > related backups in one upstream repo.
> 
> So, we agree that --all is the same as 'refs/heads/*'. Therefore we
> already have this mixture of refspecs and options.

True. I wonder why there has been so much confusion over "--tags", and
so little over "--all".

> > and then it really is just a special way of spelling "refs/heads/*". But
> > then, I also think it's good for users to understand that the options
> > are refspecs, and what that means. It's not a hard concept, and then
> > when they inevitably say "how can I do BRANCHES, except put the result
> > somewhere else in the remote namespace", it's a very natural extension
> > to learn about the right-hand side o the refspec.
> >
> > Of course I also think BRANCHES looks ugly, and people should just learn
> > "refs/heads/*".
> 
> Look, I'm all in favor of people learning stuff, but I have been
> involved in Git since basically day 1, and up to this day I was (am?)
> not familiar with refspecs, I don't use them regularly, and never
> really had a need to, and that's fine. People are already complaining
> about the learning curve of git, and what you are suggesting is that:
> 
> Instead of doing:
> % git push remote --branches --tags
> 
> They should do:
> % git push remote 'refs/heads/*' 'refs/tags/*'

Sorry, I should have been more clear with what I wrote. My "of
course..." was more of a tangential "well, this is so far from what my
gut tells me is reasonable that I'm not sure my definition of ugly is
even relevant here".

For me personally as a user, I prefer learning how a tool actually works
at its core (in this case, refspecs), and then applying syntactic sugar
to simplify usage. But I also respect that not everybody feels that way.

> I'm not going to investigate the subtleties of these different setups,
> I'm going to put my common user hat and ask; how do I fetch as a
> mirror?

The problem with that question is that you haven't defined mirror. Does
that mean you just want pruning, or does it mean that you want your
local ref namespace to match that of the remote?

Git should be able to do each of those cases. And I think it's fine to
have a less cumbersome syntax to specify them. But it's also important
that we don't over-simplify the terms so much that they get option A
when they wanted B.

BTW, right now there is "git remote add --mirror ...", which sets up the
fetch refspec for you (in this case, mirror is "make your refs look like
the remote's"). Perhaps rather than adding syntactic sugar to fetch, it
would be best to channel users into configuring a remote that selects
from one of a few common setups (including different types of mirrors).

It's not as flexible (I can't do a one-off mirrored push without using
actual refspecs), but my guess is that most users would want to set up
an actual remote, and picking from a set of configuration recipes would
be the ideal interface for them.

> > And "--prune-local" doesn't seem like a fetch operation to me. Either
> > you are mirroring, and --prune already handles it as above. Or you are
> > interested in getting rid of branches whose upstream has gone away. But
> > that's not a fetch operation; that's a branch operation.
> 
> This would make things more confusing to the user.
> 
> Say on one side I do this push?
> % git push test --prune 'refs/heads/*' 'refs/tags/*'
> 
> What do I do in the other side to synchronize the repo?
> % git fetch test --prune-local 'refs/heads/*:refs/heads/*'
> 'refs/tags/*:refs/tags/*'

No, you would just do "--prune", because your refspecs are _already_
indicating that you are writing into the local namespace, and anything
you have locally would be deleted by the prune operation. I.e., there is
no need for --prune-local in this scenario; --prune already does what we
want.

> I would prefer this of course:
> % git fetch test --all --prune-local
> 
> But you are saying it should be:
> % git fetch test 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
> % git branch --prune-remote test
> 
> That doesn't sound right to me; mixing branch operations with a specific remote?

I was trying to outline a situation where "--prune" wouldn't be
sufficient, which is:

  : we make some topic branch based on another branch
  $ git checkout -b topic-Y origin/topic-X

  : later, we (or someone else) deletes topic-X upstream
  $ git push origin :topic-X

  : now we fetch using the regular default refspecs, which put
  : everything in a separate remote. But we ask to prune, so that
  : deleted branches will go away.
  $ git fetch --prune origin

Now origin/topic-X doesn't exist, even though it's configured as the
upstream of topic-Y. Fetch doesn't enter into the picture, because it is
configured to only touch items in refs/remotes/.

As a user, how do I resolve the situation? I might say topic-Y is
obsolete and get rid of it. I might rebase it onto another branch. Or I
might declare it to have no upstream. But all of those are branch
operations, not fetch operations.

So what I was trying to say was that either your fetch refspecs tell
fetch to write into your local branch namespace, or not. If they do,
then --prune is sufficient (with no -local variant required). If not,
then touching your local branch namespace is outside the scope of fetch.

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-14 12:25                     ` Jeff King
@ 2011-11-14 13:57                       ` Felipe Contreras
  2011-11-21 21:44                         ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-14 13:57 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Nov 14, 2011 at 2:25 PM, Jeff King <peff@peff.net> wrote:
> On Sun, Nov 13, 2011 at 12:07:19AM +0200, Felipe Contreras wrote:
>
>> > So in that sense, it is poorly named, and "--branches" (or "--heads")
>> > would be more accurate. At the same time, it is probably more likely
>> > what the user wants to do (you almost never want to push "refs/remotes",
>> > for example).
>>
>> But you do want to push tags, and --all --tags doesn't sound right; if
>> I'm pushing everything, why do I specify I want to push more stuff.
>> And then, why it --all --tags disallowed?
>
> I agree that "--all --tags" looks silly. I don't know why it's
> disallowed; from my reading, it should be a perfectly sensible
> operation. You might try digging in the history or the mailing list.

Yeah, I might do that.

>> > So I am a little hesitant to suggest changing it, even
>> > with a warning and deprecation period.
>>
>> It is confusing and wrong, what more reason do you need?
>
> Because I am worried that "--all" pushing refs/remotes will also be
> confusing; it's not what most people are going to want.
>
> If your suggestion is to deprecate the name "--all" and start calling it
> "--branches" or "--heads", then that is an improvement. But making
> "refs/*:refs/*" easier to accidentally use might not be.

That's what I meant; replace --all with --branches (remember heads is
a plumbing name).

>> > and then it really is just a special way of spelling "refs/heads/*". But
>> > then, I also think it's good for users to understand that the options
>> > are refspecs, and what that means. It's not a hard concept, and then
>> > when they inevitably say "how can I do BRANCHES, except put the result
>> > somewhere else in the remote namespace", it's a very natural extension
>> > to learn about the right-hand side o the refspec.
>> >
>> > Of course I also think BRANCHES looks ugly, and people should just learn
>> > "refs/heads/*".
>>
>> Look, I'm all in favor of people learning stuff, but I have been
>> involved in Git since basically day 1, and up to this day I was (am?)
>> not familiar with refspecs, I don't use them regularly, and never
>> really had a need to, and that's fine. People are already complaining
>> about the learning curve of git, and what you are suggesting is that:
>>
>> Instead of doing:
>> % git push remote --branches --tags
>>
>> They should do:
>> % git push remote 'refs/heads/*' 'refs/tags/*'
>
> Sorry, I should have been more clear with what I wrote. My "of
> course..." was more of a tangential "well, this is so far from what my
> gut tells me is reasonable that I'm not sure my definition of ugly is
> even relevant here".
>
> For me personally as a user, I prefer learning how a tool actually works
> at its core (in this case, refspecs), and then applying syntactic sugar
> to simplify usage. But I also respect that not everybody feels that way.
>
>> I'm not going to investigate the subtleties of these different setups,
>> I'm going to put my common user hat and ask; how do I fetch as a
>> mirror?
>
> The problem with that question is that you haven't defined mirror. Does
> that mean you just want pruning, or does it mean that you want your
> local ref namespace to match that of the remote?

Exactly, no mirror has been defined, because I don't want a mirror. A
mirror is supposed to have all the refs in sync all the time; that's
not what I want.

> Git should be able to do each of those cases. And I think it's fine to
> have a less cumbersome syntax to specify them. But it's also important
> that we don't over-simplify the terms so much that they get option A
> when they wanted B.
>
> BTW, right now there is "git remote add --mirror ...", which sets up the
> fetch refspec for you (in this case, mirror is "make your refs look like
> the remote's"). Perhaps rather than adding syntactic sugar to fetch, it
> would be best to channel users into configuring a remote that selects
> from one of a few common setups (including different types of mirrors).

But that assumes that they would want the same refspec operation *all
the time* which is not the case (at least for me). Sometimes I want to
update only existing branches, sometimes I want to fetch new branches
too, sometimes I want to prune local branches, sometimes not.

> It's not as flexible (I can't do a one-off mirrored push without using
> actual refspecs), but my guess is that most users would want to set up
> an actual remote, and picking from a set of configuration recipes would
> be the ideal interface for them.

I don't think so. I doubt users would like a refspec that will delete
their local branches *always*; sometimes they would want to prune the
remote tracking branches.

>> > And "--prune-local" doesn't seem like a fetch operation to me. Either
>> > you are mirroring, and --prune already handles it as above. Or you are
>> > interested in getting rid of branches whose upstream has gone away. But
>> > that's not a fetch operation; that's a branch operation.
>>
>> This would make things more confusing to the user.
>>
>> Say on one side I do this push?
>> % git push test --prune 'refs/heads/*' 'refs/tags/*'
>>
>> What do I do in the other side to synchronize the repo?
>> % git fetch test --prune-local 'refs/heads/*:refs/heads/*'
>> 'refs/tags/*:refs/tags/*'
>
> No, you would just do "--prune", because your refspecs are _already_
> indicating that you are writing into the local namespace, and anything
> you have locally would be deleted by the prune operation. I.e., there is
> no need for --prune-local in this scenario; --prune already does what we
> want.

That's very risky. The user might forget that this is a mirror repo,
and delete the local branches unintentionally. Plus, it would be then
impossible to prune remote tracking branches.

>> I would prefer this of course:
>> % git fetch test --all --prune-local
>>
>> But you are saying it should be:
>> % git fetch test 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
>> % git branch --prune-remote test
>>
>> That doesn't sound right to me; mixing branch operations with a specific remote?
>
> I was trying to outline a situation where "--prune" wouldn't be
> sufficient, which is:
>
>  : we make some topic branch based on another branch
>  $ git checkout -b topic-Y origin/topic-X
>
>  : later, we (or someone else) deletes topic-X upstream
>  $ git push origin :topic-X
>
>  : now we fetch using the regular default refspecs, which put
>  : everything in a separate remote. But we ask to prune, so that
>  : deleted branches will go away.
>  $ git fetch --prune origin
>
> Now origin/topic-X doesn't exist, even though it's configured as the
> upstream of topic-Y. Fetch doesn't enter into the picture, because it is
> configured to only touch items in refs/remotes/.

That's only by default.

> As a user, how do I resolve the situation? I might say topic-Y is
> obsolete and get rid of it. I might rebase it onto another branch. Or I
> might declare it to have no upstream. But all of those are branch
> operations, not fetch operations.

Yes, but that has nothing to do with the operation I want to achieve:
git remote sync. By which I mean synchronize the local branches with
the branches of a certain remote.

Note that in this sync operation, the upstream branch is irrelevant.

> So what I was trying to say was that either your fetch refspecs tell
> fetch to write into your local branch namespace, or not. If they do,
> then --prune is sufficient (with no -local variant required). If not,
> then touching your local branch namespace is outside the scope of fetch.

I don't want this to be a *permanent* configuration. I see this
similar to --force. You can achieve the same by adding a + at the
beginning of the refspec, but this is something that should be
activated on a per-command basis, thus the option. I think this should
be the same.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-14 13:57                       ` Felipe Contreras
@ 2011-11-21 21:44                         ` Jeff King
  2011-11-21 23:47                           ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-21 21:44 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Mon, Nov 14, 2011 at 03:57:07PM +0200, Felipe Contreras wrote:

> >> I'm not going to investigate the subtleties of these different setups,
> >> I'm going to put my common user hat and ask; how do I fetch as a
> >> mirror?
> >
> > The problem with that question is that you haven't defined mirror. Does
> > that mean you just want pruning, or does it mean that you want your
> > local ref namespace to match that of the remote?
> 
> Exactly, no mirror has been defined, because I don't want a mirror. A
> mirror is supposed to have all the refs in sync all the time; that's
> not what I want.

I didn't mean "you didn't define a mirror in your config". I meant "your
question is not well-defined, because you haven't defined the term
'mirror'". IOW, I can't answer your question without knowing exactly
what you meant.

> > BTW, right now there is "git remote add --mirror ...", which sets up the
> > fetch refspec for you (in this case, mirror is "make your refs look like
> > the remote's"). Perhaps rather than adding syntactic sugar to fetch, it
> > would be best to channel users into configuring a remote that selects
> > from one of a few common setups (including different types of mirrors).
> 
> But that assumes that they would want the same refspec operation *all
> the time* which is not the case (at least for me). Sometimes I want to
> update only existing branches, sometimes I want to fetch new branches
> too, sometimes I want to prune local branches, sometimes not.

OK, then that means it must be a fetch command-line thing, not a
configured thing. Though note that even leaving prune out, I don't think
git does what you want (e.g., how are you fetching only to update
existing branches?).

> > No, you would just do "--prune", because your refspecs are _already_
> > indicating that you are writing into the local namespace, and anything
> > you have locally would be deleted by the prune operation. I.e., there is
> > no need for --prune-local in this scenario; --prune already does what we
> > want.
> 
> That's very risky. The user might forget that this is a mirror repo,
> and delete the local branches unintentionally. Plus, it would be then
> impossible to prune remote tracking branches.

Sorry, but I don't see how "--prune" is supposed to know what to prune
except through the refspecs that have been provided to it (either in
configuration or on the command line). So what is:

  git fetch --prune <remote> refs/*:refs/*

_supposed_ to do, if not prune your local namespace?

I don't buy the "it's too risky" argument. You have configured a remote
that will fetch and overwrite your local branches already, if you ever
run "git fetch foo". But somehow running "git fetch --prune foo" is too
risky, because you might forget that it will delete all of your
branches?

> > As a user, how do I resolve the situation? I might say topic-Y is
> > obsolete and get rid of it. I might rebase it onto another branch. Or I
> > might declare it to have no upstream. But all of those are branch
> > operations, not fetch operations.
> 
> Yes, but that has nothing to do with the operation I want to achieve:
> git remote sync. By which I mean synchronize the local branches with
> the branches of a certain remote.

Right. I was only trying to explain a case where you would want to prune
in the local namespace, when fetch is not configured to touch the local
namespace. Which is the only use case I could think of for something
named --prune-local. But let's forget it. My point was that it is not
related to fetch, and I was just guessing at what you might want from
--prune-local.

> > So what I was trying to say was that either your fetch refspecs tell
> > fetch to write into your local branch namespace, or not. If they do,
> > then --prune is sufficient (with no -local variant required). If not,
> > then touching your local branch namespace is outside the scope of fetch.
> 
> I don't want this to be a *permanent* configuration. I see this
> similar to --force. You can achieve the same by adding a + at the
> beginning of the refspec, but this is something that should be
> activated on a per-command basis, thus the option. I think this should
> be the same.

Then you can tweak what is pruned on a per-command basis by providing
alternate refspecs. Right now that would probably mean:

  git fetch --prune <remote> refs/*:refs/*

or

  git fetch --prune <remote> refs/heads/*:refs/remotes/<remote>/*

but as we discussed earlier in the thread, those can be made less scary
with syntactic sugar.

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-21 21:44                         ` Jeff King
@ 2011-11-21 23:47                           ` Felipe Contreras
  2011-11-30  7:01                             ` Jeff King
  0 siblings, 1 reply; 26+ messages in thread
From: Felipe Contreras @ 2011-11-21 23:47 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Nov 21, 2011 at 11:44 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Nov 14, 2011 at 03:57:07PM +0200, Felipe Contreras wrote:
>
>> >> I'm not going to investigate the subtleties of these different setups,
>> >> I'm going to put my common user hat and ask; how do I fetch as a
>> >> mirror?
>> >
>> > The problem with that question is that you haven't defined mirror. Does
>> > that mean you just want pruning, or does it mean that you want your
>> > local ref namespace to match that of the remote?
>>
>> Exactly, no mirror has been defined, because I don't want a mirror. A
>> mirror is supposed to have all the refs in sync all the time; that's
>> not what I want.
>
> I didn't mean "you didn't define a mirror in your config". I meant "your
> question is not well-defined, because you haven't defined the term
> 'mirror'". IOW, I can't answer your question without knowing exactly
> what you meant.

I wasn't the one that brought the mirror up, you did:

> I think --prune wouldn't need renaming. If you fetch into tracking
> branches, then pruning would prune tracking branches. If you fetch as a
> mirror (refs/*:refs/*), then you would prune everything.

So you should know what you meant :)

>> > BTW, right now there is "git remote add --mirror ...", which sets up the
>> > fetch refspec for you (in this case, mirror is "make your refs look like
>> > the remote's"). Perhaps rather than adding syntactic sugar to fetch, it
>> > would be best to channel users into configuring a remote that selects
>> > from one of a few common setups (including different types of mirrors).
>>
>> But that assumes that they would want the same refspec operation *all
>> the time* which is not the case (at least for me). Sometimes I want to
>> update only existing branches, sometimes I want to fetch new branches
>> too, sometimes I want to prune local branches, sometimes not.
>
> OK, then that means it must be a fetch command-line thing, not a
> configured thing. Though note that even leaving prune out, I don't think
> git does what you want (e.g., how are you fetching only to update
> existing branches?).

It should be possible to do a git fetch, so the remote tracking
branches are updated, and then compare those with the local ones. This
might not feel natural under 'git fetch' which is why I decided to use
'git remote sync'.

>> > No, you would just do "--prune", because your refspecs are _already_
>> > indicating that you are writing into the local namespace, and anything
>> > you have locally would be deleted by the prune operation. I.e., there is
>> > no need for --prune-local in this scenario; --prune already does what we
>> > want.
>>
>> That's very risky. The user might forget that this is a mirror repo,
>> and delete the local branches unintentionally. Plus, it would be then
>> impossible to prune remote tracking branches.
>
> Sorry, but I don't see how "--prune" is supposed to know what to prune
> except through the refspecs that have been provided to it (either in
> configuration or on the command line). So what is:

That's why I suggested --prune-local.

>  git fetch --prune <remote> refs/*:refs/*
>
> _supposed_ to do, if not prune your local namespace?

I thought 'git fetch --prune <remote_mirror>' would not prune the
local branches, but now I see that it does (currently), so nevermind.

>> > As a user, how do I resolve the situation? I might say topic-Y is
>> > obsolete and get rid of it. I might rebase it onto another branch. Or I
>> > might declare it to have no upstream. But all of those are branch
>> > operations, not fetch operations.
>>
>> Yes, but that has nothing to do with the operation I want to achieve:
>> git remote sync. By which I mean synchronize the local branches with
>> the branches of a certain remote.
>
> Right. I was only trying to explain a case where you would want to prune
> in the local namespace, when fetch is not configured to touch the local
> namespace. Which is the only use case I could think of for something
> named --prune-local. But let's forget it. My point was that it is not
> related to fetch, and I was just guessing at what you might want from
> --prune-local.

Basically 'git fetch --prune <remote> refs/*:refs/*', when the remote
is not configured as a mirror. But it would be nice to prune the
branches without having to update the local ones (for whatever
reason).

>> > So what I was trying to say was that either your fetch refspecs tell
>> > fetch to write into your local branch namespace, or not. If they do,
>> > then --prune is sufficient (with no -local variant required). If not,
>> > then touching your local branch namespace is outside the scope of fetch.
>>
>> I don't want this to be a *permanent* configuration. I see this
>> similar to --force. You can achieve the same by adding a + at the
>> beginning of the refspec, but this is something that should be
>> activated on a per-command basis, thus the option. I think this should
>> be the same.
>
> Then you can tweak what is pruned on a per-command basis by providing
> alternate refspecs. Right now that would probably mean:
>
>  git fetch --prune <remote> refs/*:refs/*
>
> or
>
>  git fetch --prune <remote> refs/heads/*:refs/remotes/<remote>/*
>
> but as we discussed earlier in the thread, those can be made less scary
> with syntactic sugar.

Indeed, but those commands will also update the local branches.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-21 23:47                           ` Felipe Contreras
@ 2011-11-30  7:01                             ` Jeff King
  2011-11-30 11:47                               ` Felipe Contreras
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff King @ 2011-11-30  7:01 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Tue, Nov 22, 2011 at 01:47:36AM +0200, Felipe Contreras wrote:

> > I didn't mean "you didn't define a mirror in your config". I meant "your
> > question is not well-defined, because you haven't defined the term
> > 'mirror'". IOW, I can't answer your question without knowing exactly
> > what you meant.
> 
> I wasn't the one that brought the mirror up, you did:

Yes, because that is the most related concept in current git. But I
thought you were asking from the perspective of a clueless user, and I
don't know what that clueless user meant by "mirror".

Anyway, I don't think it's important.

I read over your whole message, and I feel like our discussion isn't
really moving towards an actual goal. Junio and I both mentioned that in
the long-term, features like this should be part of "push", not
"remote". Do you want to try revising your patch in that direction?
That will give us something concrete to talk about (and hopefully
apply).

-Peff

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [RFC/PATCH] remote: add new sync command
  2011-11-30  7:01                             ` Jeff King
@ 2011-11-30 11:47                               ` Felipe Contreras
  0 siblings, 0 replies; 26+ messages in thread
From: Felipe Contreras @ 2011-11-30 11:47 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Wed, Nov 30, 2011 at 9:01 AM, Jeff King <peff@peff.net> wrote:
> On Tue, Nov 22, 2011 at 01:47:36AM +0200, Felipe Contreras wrote:
>
>> > I didn't mean "you didn't define a mirror in your config". I meant "your
>> > question is not well-defined, because you haven't defined the term
>> > 'mirror'". IOW, I can't answer your question without knowing exactly
>> > what you meant.
>>
>> I wasn't the one that brought the mirror up, you did:
>
> Yes, because that is the most related concept in current git. But I
> thought you were asking from the perspective of a clueless user, and I
> don't know what that clueless user meant by "mirror".

I don't think common users know, or should care about, what a "mirror" is.

> Anyway, I don't think it's important.

Me neither.

> I read over your whole message, and I feel like our discussion isn't
> really moving towards an actual goal. Junio and I both mentioned that in
> the long-term, features like this should be part of "push", not
> "remote". Do you want to try revising your patch in that direction?

Yes, I can try that for 'git push', but my worry is about 'git fetch'.
To me it's really clear that what I am trying to achieve is more
complicated than a simple push/fetch.

You still haven't replied to my solution to synchronize the local
branches, which to first do a 'git fetch' so we have the remote
branches tracked locally, and go through each one of them and do
something to the local ones. This solution works, is simple, and
allows all kinds of options, but IMO it's not part of 'git fetch'.

> That will give us something concrete to talk about (and hopefully
> apply).

Yes, but that's basically 'git push --prune', which I think is the
only thing we have agreed. But what about the rest?

I feel you are trying to ignore the fact that 'refs/heads/*' is not
user-friendly, neither is BRANCHES, or :, and 'git fetch' would be
even more cumbersome.

The user-friendliness of git is one of the biggest complains people
have, and while it makes sense to keep certain operations under
push/fetch, there's only so much pureness we can have before things
become too complicated for the users. The fact of the matter is that
these particular remote synchronization operations are much easier to
picture mentally in a group like 'git remote sync'. That not only
works for all the cases, including 'git fetch', but it's
non-intrusive, and most importantly: user-friendly.

Cheers.

-- 
Felipe Contreras

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-11-30 11:47 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-07 16:07 [RFC/PATCH] remote: add new sync command Felipe Contreras
2011-11-07 17:22 ` Jeff King
2011-11-07 18:35   ` Felipe Contreras
2011-11-07 18:39     ` Jeff King
2011-11-07 20:51       ` Felipe Contreras
2011-11-07 21:01         ` Jeff King
2011-11-07 21:25           ` Junio C Hamano
2011-11-07 21:31             ` Jeff King
2011-11-08 16:43             ` Felipe Contreras
2011-11-08 17:49               ` Junio C Hamano
2011-11-08 17:59                 ` Felipe Contreras
2011-11-09  3:36                   ` Junio C Hamano
2011-11-11 10:35                     ` Jakub Narebski
2011-11-11 16:38                       ` Junio C Hamano
2011-11-11 22:00                         ` Jakub Narebski
2011-11-08 17:31           ` Felipe Contreras
2011-11-08 18:14             ` Jeff King
2011-11-11 12:30               ` Felipe Contreras
2011-11-11 18:13                 ` Jeff King
2011-11-12 22:07                   ` Felipe Contreras
2011-11-14 12:25                     ` Jeff King
2011-11-14 13:57                       ` Felipe Contreras
2011-11-21 21:44                         ` Jeff King
2011-11-21 23:47                           ` Felipe Contreras
2011-11-30  7:01                             ` Jeff King
2011-11-30 11:47                               ` Felipe Contreras

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.