Jeff King wrote:
>   $ git clone https://github.com/upstream/project.git
>   $ cd project
>   $ hack hack hack; commit commit commit
>   $ git tag -m 'something of note' my-tag
>   $ git remote add me https://github.com/me/project.git
>   $ git config branch.master.remote me
>   $ git tag -m 'something of note'
>   $ git push master my-tag

Tags have nothing to do with branches, and it is illogical to respect
branch.* when pushing a tag.  You've illustrated a common case when
the user creates a tag on a specific branch and immediately pushes it.
 I would argue that optimizing our tools for this specific usecase
breaks the general case.  What if I create a branch on master, and
decide to push the tag after checking out implicit-push and doing some
work on it?  Does that not break user expectations?

In the "I push to the same place I pull from" (aka. single-remote)
case, there are never any problems and even "matching" works fine.
However, in the triangular workflow (aka. multiple-remote) case, you
must give git enough information about your workflow for it to DTRT.
I will argue that, in the above example, you have not configured git
for a multiple-remote case, and that you cannot expect it to DTRT
since you have supplied insufficient information.  As to how to
configure git for the general multiple-remote case:

Let us imagine that origin points to git/git.git (upstream), ram
points to artagnon/git.git and peff points to peff/git.git.  I fork
off from upstream and have various local branches that only have
corresponding refs in ram (say implicit-push).  Then, you fork off
from me, and have various local branches that only have corresponding
refs in peff (say implicit-push-next).  I have peff as a configured
remote, because I routinely review the changes you make to my fork.
In this case, I must have:

- push.default set to anything but matching, because matching makes no
sense in the multiple-remote scenario*.

- remote.default set to origin, because this is where I get new code
from for all branches.

- remote.pushdefault set to ram, because this is where I publish all
my refs to (whether branches or tags).  I might have local branches
that I will never publish, but that's a separate issue.  The point is
that all my tags will always be published here.

- branch.implicit-push.remote set to ram, because this is the correct
upstream for the implicit-push branch.

- branch.implicit-push-next.remote set to peff, because this is the
correct upstream for the implicit-push-next branch.

- branch.implicit-push-next.pushremote set to null**, because I will
never want to push this branch.

(Note that branch.implicit-push.pushremote is unnecessary because
remote.pushdefault takes care of that)

With these settings, git push will always DTRT when you specify
nothing, just a remote, or just a refspec.  Ofcourse, you can specify
both and be explicit (which is what we do now).  Does this make sense?
 Should we document this in gitworkflows.txt so that users know what
is expected of them when they move from a single-remote setup to a
multi-remote setup?

* I will definitely push for the deprecation of push.default=matching,
but I doubt we need to invent a new push.default.  current makes a lot
of sense to me personally.

** Yet to be invented.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to