Fetching tags overwrites existing tags
If have a repository with a tag "v1.0.0" and I add a remote repository which also has a tag "v1.0.0" tag is overwritten. Google found [1] from 2011 and option 3 is what I'd like to see. Has it been implemented and I just don't see it? [1]: https://groups.google.com/forum/#!topic/git-version-control/0l_rJFyTE60 Here is an example demonstrating what I see: $ echo abc > abc.txt $ git init . Initialized empty Git repository in /home/wink/prgs/git/investigate-fetch-tags/.git/ $ git add * $ git commit -m "Initial commit" [master (root-commit) 1116fdc] Initial commit 1 file changed, 1 insertion(+) create mode 100644 abc.txt $ git tag v1.0.0 $ git remote add gbenchmark g...@github.com:google/benchmark $ git log --graph --format="%h %s %d" * 1116fdc Initial commit (HEAD -> master, tag: v1.0.0) $ git fetch --tags gbenchmark warning: no common commits remote: Counting objects: 4400, done. remote: Compressing objects: 100% (15/15), done. remote: Total 4400 (delta 5), reused 5 (delta 3), pack-reused 4382 Receiving objects: 100% (4400/4400), 1.33 MiB | 2.81 MiB/s, done. Resolving deltas: 100% (2863/2863), done. >From github.com:google/benchmark * [new branch] clangtidy -> gbenchmark/clangtidy * [new branch] iter_report -> gbenchmark/iter_report * [new branch] master -> gbenchmark/master * [new branch] releasing -> gbenchmark/releasing * [new branch] reportercleanup -> gbenchmark/reportercleanup * [new branch] rmheaders -> gbenchmark/rmheaders * [new branch] v2 -> gbenchmark/v2 * [new tag] v0.0.9 -> v0.0.9 * [new tag] v0.1.0 -> v0.1.0 t [tag update] v1.0.0 -> v1.0.0 * [new tag] v1.1.0 -> v1.1.0 * [new tag] v1.2.0 -> v1.2.0 * [new tag] v1.3.0 -> v1.3.0 * [new tag] v1.4.0 -> v1.4.0 $ git log --graph --format="%h %s %d" * 1116fdc Initial commit (HEAD -> master) As you can see the tag on 1116fdc is gone, v1.0.0 tag has been updated and now its pointing to the tag in gbenchmark: $ git log -5 --graph --format="%h %s %d" v1.0.0 * cd525ae Merge pull request #171 from eliben/update-doc-userealtime (tag: v1.0.0) |\ | * c7ab1b9 Update README to mention UseRealTime for wallclock time measurements. |/ * f662e8b Rename OS_MACOSX macro to new name BENCHMARK_OS_MACOSX. Fix #169 * 0a1f484 Merge pull request #166 from disconnect3d/master |\ | * d2917bc Fixes #165: CustomArguments ret type in README |/ Ideally I would have liked the tags fetched from gbenchmark to have a prefix of gbenchmark/, like the branches have, maybe something like: $ git fetch --tags gbenchmark ... * [new branch] v2 -> gbenchmark/v2 * [new tag] v0.0.9 -> gbenchmark/v0.0.9 * [new tag] v0.1.0 -> gbenchmark/v0.1.0 * [new tag] v1.0.0 -> gbenchmark/v1.0.0 * [new tag] v1.1.0 -> gbenchmark/v1.1.0 * [new tag] v1.2.0 -> gbenchmark/v1.2.0 * [new tag] v1.3.0 -> gbenchmark/v1.3.0 * [new tag] v1.4.0 -> gbenchmark/v1.4.0 -- Wink
Re: Fetching tags overwrites existing tags
On Tue, Apr 24, 2018 at 12:57 PM, Wink Saville wrote: > If have a repository with a tag "v1.0.0" and I add a remote repository > which also has a tag "v1.0.0" tag is overwritten. > > Google found [1] from 2011 and option 3 is what I'd like to see. Has it been > implemented and I just don't see it? > > [1]: https://groups.google.com/forum/#!topic/git-version-control/0l_rJFyTE60 > > > Here is an example demonstrating what I see: > > $ echo abc > abc.txt > $ git init . > Initialized empty Git repository in > /home/wink/prgs/git/investigate-fetch-tags/.git/ > $ git add * > $ git commit -m "Initial commit" > [master (root-commit) 1116fdc] Initial commit > 1 file changed, 1 insertion(+) > create mode 100644 abc.txt > $ git tag v1.0.0 > $ git remote add gbenchmark g...@github.com:google/benchmark > $ git log --graph --format="%h %s %d" > * 1116fdc Initial commit (HEAD -> master, tag: v1.0.0) > $ git fetch --tags gbenchmark > warning: no common commits > remote: Counting objects: 4400, done. > remote: Compressing objects: 100% (15/15), done. > remote: Total 4400 (delta 5), reused 5 (delta 3), pack-reused 4382 > Receiving objects: 100% (4400/4400), 1.33 MiB | 2.81 MiB/s, done. > Resolving deltas: 100% (2863/2863), done. > From github.com:google/benchmark > * [new branch] clangtidy -> gbenchmark/clangtidy > * [new branch] iter_report -> gbenchmark/iter_report > * [new branch] master -> gbenchmark/master > * [new branch] releasing -> gbenchmark/releasing > * [new branch] reportercleanup -> gbenchmark/reportercleanup > * [new branch] rmheaders -> gbenchmark/rmheaders > * [new branch] v2 -> gbenchmark/v2 > * [new tag] v0.0.9 -> v0.0.9 > * [new tag] v0.1.0 -> v0.1.0 > t [tag update] v1.0.0 -> v1.0.0 > * [new tag] v1.1.0 -> v1.1.0 > * [new tag] v1.2.0 -> v1.2.0 > * [new tag] v1.3.0 -> v1.3.0 > * [new tag] v1.4.0 -> v1.4.0 > $ git log --graph --format="%h %s %d" > * 1116fdc Initial commit (HEAD -> master) > > As you can see the tag on 1116fdc is gone, v1.0.0 tag has been updated > and now its pointing to the tag in gbenchmark: > > $ git log -5 --graph --format="%h %s %d" v1.0.0 > * cd525ae Merge pull request #171 from eliben/update-doc-userealtime > (tag: v1.0.0) > |\ > | * c7ab1b9 Update README to mention UseRealTime for wallclock time > measurements. > |/ > * f662e8b Rename OS_MACOSX macro to new name BENCHMARK_OS_MACOSX. Fix #169 > * 0a1f484 Merge pull request #166 from disconnect3d/master > |\ > | * d2917bc Fixes #165: CustomArguments ret type in README > |/ > > Ideally I would have liked the tags fetched from gbenchmark to have a prefix > of gbenchmark/, like the branches have, maybe something like: > That would require a complete redesign of how we handle remotes. I've proposed ideas in the past but never had time and they didn't gain much traction. It's a known limitation that the tags namespace can only hold a single tag name (even if remotes differ in what that tag is). I *thought* that the tags should not be updated after you fetch it once, but it seems this is not the behavior we get now? My basic idea was to fetch *all* remote refs into a refs///* such that *every* ref in a remote can be determined by something like "refs/tracking/origin/tags/name" instead of "refs/remotes/origin/name", and then tags would have to be updated to check for tags in each remote as well as locally. Additionally, you could update the tool to warn when two remotes have the same tag at different refs, and allow disambiguation. Ideally, "origin/branch" should still DWIM, same for "tag" should work unless there are conflicts. Unfortunately, it's a pretty big change in how remotes are handled, and I never had time to actually work towards a POC or implementation. Mostly, we ended up on bikeshedding what the name should be now that we can't use "refs/remotes" due to backwards compatibility. I don't really like "tracking" as a name, but it was the best I could come up with. (Note, the impetus for this proposal was actually to allow easy sharing of notes and other specialized refs). Thanks, Jake > $ git fetch --tags gbenchmark > ... > * [new branch] v2 -> gbenchmark/v2 > * [new tag] v0.0.9 -> gbenchmark/v0.0.9 > * [new tag] v0.1.0 -> gbenchmark/v0.1.0 > * [new tag] v1.0.0 -> gbenchmark/v1.0.0 > * [new tag] v1.1.0 -> gbenchmark/v1.1.0 > * [new tag] v1.2.0 -> gbenchmark/v1.2.0 > * [new tag] v1.3.0 -> gbenchmark/v1.3.0 > * [new tag] v1.4.0 -> gbenchmark/v1.4.0 > > > -- Wink
Re: Fetching tags overwrites existing tags
Wink Saville writes: > Ideally I would have liked the tags fetched from gbenchmark to have a prefix > of gbenchmark/, like the branches have, maybe something like: > > $ git fetch --tags gbenchmark > ... > * [new branch] v2 -> gbenchmark/v2 > * [new tag] v0.0.9 -> gbenchmark/v0.0.9 > * [new tag] v0.1.0 -> gbenchmark/v0.1.0 > * [new tag] v1.0.0 -> gbenchmark/v1.0.0 > * [new tag] v1.1.0 -> gbenchmark/v1.1.0 > * [new tag] v1.2.0 -> gbenchmark/v1.2.0 > * [new tag] v1.3.0 -> gbenchmark/v1.3.0 > * [new tag] v1.4.0 -> gbenchmark/v1.4.0 The tag namespace (refs/tags/) is considered a shared resource (I am not saying that that is the only valid world model---I am merely explaining why things are like they are), hence the auto-following tags will bring them to refs/tags/ (and I do not think there is no way to configure auto-following to place them elsewhere). But you could configure things yourself. $ git init victim && cd victim $ git remote add origin ../git.git $ git config --add remote.origin.fetch \ "+refs/tags/*:refs/remote-tags/origin/*" $ tail -n 4 .git/config [remote "origin"] url = ../git.git/ fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/tags/*:refs/remote-tags/origin/* $ git fetch --no-tags The "--no-tags" option serves to decline the auto-following tags to refs/tags/ hierarchy; once your repository is configured this way, your initial and subsequent "git fetch" will copy refs it finds in refs/tags/ hierarchy over there to your refs/remote-tags/origin/ hierarchy locally.
Re: Fetching tags overwrites existing tags
On Tue, Apr 24, 2018 at 5:52 PM, Junio C Hamano wrote: > Wink Saville writes: > >> Ideally I would have liked the tags fetched from gbenchmark to have a prefix >> of gbenchmark/, like the branches have, maybe something like: >> >> $ git fetch --tags gbenchmark >> ... >> * [new branch] v2 -> gbenchmark/v2 >> * [new tag] v0.0.9 -> gbenchmark/v0.0.9 >> * [new tag] v0.1.0 -> gbenchmark/v0.1.0 >> * [new tag] v1.0.0 -> gbenchmark/v1.0.0 >> * [new tag] v1.1.0 -> gbenchmark/v1.1.0 >> * [new tag] v1.2.0 -> gbenchmark/v1.2.0 >> * [new tag] v1.3.0 -> gbenchmark/v1.3.0 >> * [new tag] v1.4.0 -> gbenchmark/v1.4.0 > > The tag namespace (refs/tags/) is considered a shared resource (I am > not saying that that is the only valid world model---I am merely > explaining why things are like they are), hence the auto-following > tags will bring them to refs/tags/ (and I do not think there is no > way to configure auto-following to place them elsewhere). > > But you could configure things yourself. > > $ git init victim && cd victim > $ git remote add origin ../git.git > $ git config --add remote.origin.fetch \ > "+refs/tags/*:refs/remote-tags/origin/*" > $ tail -n 4 .git/config > [remote "origin"] > url = ../git.git/ > fetch = +refs/heads/*:refs/remotes/origin/* > fetch = +refs/tags/*:refs/remote-tags/origin/* > $ git fetch --no-tags > > The "--no-tags" option serves to decline the auto-following tags to > refs/tags/ hierarchy; once your repository is configured this way, > your initial and subsequent "git fetch" will copy refs it finds in > refs/tags/ hierarchy over there to your refs/remote-tags/origin/ > hierarchy locally. It should be noted, that remote-tags would not be integrated into "git tag" or many other places in git commands, so it may be significantly less visible. Thanks, Jake
Re: Fetching tags overwrites existing tags
On Tue, Apr 24, 2018 at 5:52 PM, Junio C Hamano wrote: > Wink Saville writes: > >> Ideally I would have liked the tags fetched from gbenchmark to have a prefix >> of gbenchmark/, like the branches have, maybe something like: >> >> $ git fetch --tags gbenchmark >> ... >> * [new branch] v2 -> gbenchmark/v2 >> * [new tag] v0.0.9 -> gbenchmark/v0.0.9 >> * [new tag] v0.1.0 -> gbenchmark/v0.1.0 >> * [new tag] v1.0.0 -> gbenchmark/v1.0.0 >> * [new tag] v1.1.0 -> gbenchmark/v1.1.0 >> * [new tag] v1.2.0 -> gbenchmark/v1.2.0 >> * [new tag] v1.3.0 -> gbenchmark/v1.3.0 >> * [new tag] v1.4.0 -> gbenchmark/v1.4.0 > > The tag namespace (refs/tags/) is considered a shared resource (I am > not saying that that is the only valid world model---I am merely > explaining why things are like they are), hence the auto-following > tags will bring them to refs/tags/ (and I do not think there is no > way to configure auto-following to place them elsewhere). > > But you could configure things yourself. > > $ git init victim && cd victim > $ git remote add origin ../git.git > $ git config --add remote.origin.fetch \ > "+refs/tags/*:refs/remote-tags/origin/*" > $ tail -n 4 .git/config > [remote "origin"] > url = ../git.git/ > fetch = +refs/heads/*:refs/remotes/origin/* > fetch = +refs/tags/*:refs/remote-tags/origin/* > $ git fetch --no-tags > > The "--no-tags" option serves to decline the auto-following tags to > refs/tags/ hierarchy; once your repository is configured this way, > your initial and subsequent "git fetch" will copy refs it finds in > refs/tags/ hierarchy over there to your refs/remote-tags/origin/ > hierarchy locally. Interesting that kinda works, what about teaching git-remote to understand a "--prefix-tags" option which would create the "fetch = refs/tags/*:refs/remote-tags/origin" entry. And teach git-fetch to use that entry if it exists and not require the "--no-tags"? Of course I'm sure there are "lots" of other things to change, doing a search for "remotes/" gives the following: $ find . -type f -name '*.c' | xargs grep '\bremotes/' | sort -uk1,1 ./builtin/branch.c: fmt = "refs/remotes/%s"; ./builtin/checkout.c: skip_prefix(argv0, "remotes/", &argv0); ./builtin/clone.c: strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin); ./builtin/describe.c: !skip_prefix(path, "refs/remotes/", &path_to_match)) { ./builtin/fast-export.c: "refs/remotes/", ./builtin/fetch.c: else if (starts_with(rm->name, "refs/remotes/")) { ./builtin/merge.c: if (starts_with(found_ref, "refs/remotes/")) { ./builtin/pull.c: * refs/heads/ to refs/remotes//. ./builtin/remote.c: strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s", ./builtin/rev-parse.c: handle_ref_opt(arg, "refs/remotes/"); ./builtin/show-branch.c: if (!starts_with(refname, "refs/remotes/")) ./contrib/examples/builtin-fetch--tool.c: else if (!strncmp(remote_name, "refs/remotes/", 13)) { ./help.c: if (skip_prefix(refname, "refs/remotes/", &remote) && ./log-tree.c: else if (starts_with(refname, "refs/remotes/")) ./ref-filter.c:skip_prefix(refname, "refs/remotes/", &refname) || ./refs.c: return refs_for_each_ref_in(refs, "refs/remotes/", fn, cb_data); ./remote.c: FILE *f = fopen_or_warn(git_path("remotes/%s", remote->name), "r"); ./revision.c: for_each_glob_ref_in(handle_one_ref, optarg, "refs/remotes/", &cb); ./sha1_name.c: starts_with(refname, "refs/remotes/")) ./wt-status.c: skip_prefix(from, "refs/remotes/", &from); -- wink
Re: Fetching tags overwrites existing tags
I've tried to teach 'git remote add' the --prefix-tags option using the technique Junio provided. At moment it is PR #486 on github [1] and I'd love some comments on whether or not this the right direction for fetching tags and putting them in the branches namespace. -- Wink [1] https://github.com/git/git/pull/486
Re: Fetching tags overwrites existing tags
Wink Saville writes: > I've tried to teach 'git remote add' the --prefix-tags option using the > technique Junio provided. At moment it is PR #486 on github [1] > and I'd love some comments on whether or not this the right direction > for fetching tags and putting them in the branches namespace. > > -- Wink > > [1] https://github.com/git/git/pull/486 FWIW, here is how that pull/486/head looks like. -- >8 -- From: Wink Saville Date: Thu, 26 Apr 2018 09:56:11 -0700 Subject: [PATCH] Teach remote add the --prefix-tags option When --prefix-tags is passed to `git remote add` the tagopt is set to --prefix-tags and a second fetch line is added so tags are placed in the branches namespace. For example: $ git remote add -f --prefix-tags gbenchmark g...@github.com:google/benchmark Updating gbenchmark warning: no common commits remote: Counting objects: 4406, done. remote: Compressing objects: 100% (18/18), done. remote: Total 4406 (delta 7), reused 13 (delta 6), pack-reused 4382 Receiving objects: 100% (4406/4406), 1.34 MiB | 7.46 MiB/s, done. Resolving deltas: 100% (2865/2865), done. From github.com:google/benchmark * [new branch] clangtidy -> gbenchmark/clangtidy * [new branch] iter_report -> gbenchmark/iter_report * [new branch] master -> gbenchmark/master * [new branch] releasing -> gbenchmark/releasing * [new branch] reportercleanup -> gbenchmark/reportercleanup * [new branch] rmheaders -> gbenchmark/rmheaders * [new branch] v2 -> gbenchmark/v2 * [new tag] v0.0.9 -> refs/remote-tags/gbenchmark/v0.0.9 * [new tag] v0.1.0 -> refs/remote-tags/gbenchmark/v0.1.0 * [new tag] v1.0.0 -> refs/remote-tags/gbenchmark/v1.0.0 * [new tag] v1.1.0 -> refs/remote-tags/gbenchmark/v1.1.0 * [new tag] v1.2.0 -> refs/remote-tags/gbenchmark/v1.2.0 * [new tag] v1.3.0 -> refs/remote-tags/gbenchmark/v1.3.0 * [new tag] v1.4.0 -> refs/remote-tags/gbenchmark/v1.4.0 And the .git/config remote "gbenchmark" section looks like: [remote "gbenchmark"] url = g...@github.com:google/benchmark fetch = +refs/heads/*:refs/remotes/gbenchmark/* fetch = +refs/tags/*:refs/remote-tags/gbenchmark/* tagopt = --prefix-tags --- Documentation/git-remote.txt | 8 -- builtin/remote.c | 47 +--- remote.c | 2 ++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 4feddc0293..cdfd24e2ea 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git remote' [-v | --verbose] -'git remote add' [-t ] [-m ] [-f] [--[no-]tags] [--mirror=] +'git remote add' [-t ] [-m ] [-f] [--prefix-tags | --tags | --no-tags] [--mirror=] 'git remote rename' 'git remote remove' 'git remote set-head' (-a | --auto | -d | --delete | ) @@ -54,7 +54,11 @@ With `-f` option, `git fetch ` is run immediately after the remote information is set up. + With `--tags` option, `git fetch ` imports every tag from the -remote repository. +remote repository to refs/tags, use --prefix-tags to import them +to refs/remote-tags//. ++ +With `--prefix-tags` option, `git fetch ` imports every tag from the +remote repository to refs/remote-tags//. + With `--no-tags` option, `git fetch ` does not import tags from the remote repository. diff --git a/builtin/remote.c b/builtin/remote.c index 805ffc05cd..75813eeaa3 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -11,7 +11,7 @@ static const char * const builtin_remote_usage[] = { N_("git remote [-v | --verbose]"), - N_("git remote add [-t ] [-m ] [-f] [--tags | --no-tags] [--mirror=] "), + N_("git remote add [-t ] [-m ] [-f] [--prefix-tags | --tags | --no-tags] [--mirror=] "), N_("git remote rename "), N_("git remote remove "), N_("git remote set-head (-a | --auto | -d | --delete | )"), @@ -101,7 +101,8 @@ static int fetch_remote(const char *name) enum { TAGS_UNSET = 0, TAGS_DEFAULT = 1, - TAGS_SET = 2 + TAGS_SET = 2, + TAGS_SET_PREFIX = 3 }; #define MIRROR_NONE 0 @@ -123,6 +124,16 @@ static void add_branch(const char *key, const char *branchname, git_config_set_multivar(key, tmp->buf, "^$", 0); } +static void add_remote_tags(const char *key, const char *branchname, + const char *remotename, struct strbuf *tmp) +{ + strbuf_reset(tmp); + strbuf_addch(tmp, '+'); + strbuf_addf(tmp, "refs/tags/%s:refs/remote-tags/%s/%s", + branchname, remotename, branchname); + git_config_set_multivar(key, tmp->buf, "^$", 0); +} + static const char mirror_advice[] = N_("--mirror is dangerous and
Re: Fetching tags overwrites existing tags
Junio C Hamano writes: > Wink Saville writes: > >> I've tried to teach 'git remote add' the --prefix-tags option using the >> technique Junio provided. At moment it is PR #486 on github [1] >> and I'd love some comments on whether or not this the right direction >> for fetching tags and putting them in the branches namespace. >> >> -- Wink >> >> [1] https://github.com/git/git/pull/486 > > FWIW, here is how that pull/486/head looks like. > > -- >8 -- > > From: Wink Saville > Date: Thu, 26 Apr 2018 09:56:11 -0700 > Subject: [PATCH] Teach remote add the --prefix-tags option > > When --prefix-tags is passed to `git remote add` the tagopt is set to > --prefix-tags and a second fetch line is added so tags are placed in > the branches namespace. When I hear "branches namespace", what comes to my mind is refs/heads/ or perhaps refs/remotes/*/. "... are placed in a separate hierarchy per remote" or something, perhaps? > > ... > And the .git/config remote "gbenchmark" section looks like: > [remote "gbenchmark"] > url = g...@github.com:google/benchmark > fetch = +refs/heads/*:refs/remotes/gbenchmark/* > fetch = +refs/tags/*:refs/remote-tags/gbenchmark/* > tagopt = --prefix-tags > --- Missing sign-off ;-) > +static void add_remote_tags(const char *key, const char *branchname, > +const char *remotename, struct strbuf *tmp) > +{ > + strbuf_reset(tmp); > + strbuf_addch(tmp, '+'); > + strbuf_addf(tmp, "refs/tags/%s:refs/remote-tags/%s/%s", > + branchname, remotename, branchname); With "+refs/tags/%s:refs/remote-tags/%s/%s", combine addch/addf into one, perhaps? > + git_config_set_multivar(key, tmp->buf, "^$", 0); > +} Calling the second parameter "branchname" makes little sense, I would think. Practically, you would call this at most once with its second parameter set to '*', and even if the second parameter is not a wildcard/asterisk, it would be a tagname. > static const char mirror_advice[] = > N_("--mirror is dangerous and deprecated; please\n" > "\t use --mirror=fetch or --mirror=push instead"); > @@ -161,6 +172,9 @@ static int add(int argc, const char **argv) > OPT_SET_INT(0, "tags", &fetch_tags, > N_("import all tags and associated objects when > fetching"), > TAGS_SET), > + OPT_SET_INT(0, "prefix-tags", &fetch_tags, > + N_("import all tags and associated objects when > fetching and prefix with "), > + TAGS_SET_PREFIX), Funny indent. Use monospaced font in your editor, set tab width to 8 and align, imitating how the above OPT_SET_INT() item does for TAGS_SET. > @@ -215,10 +229,35 @@ static int add(int argc, const char **argv) > } > > if (fetch_tags != TAGS_DEFAULT) { > + if (fetch_tags == TAGS_SET_PREFIX) { > + strbuf_reset(&buf); > + strbuf_addf(&buf, "remote.%s.fetch", name); > + if (track.nr == 0) > + string_list_append(&track, "*"); > + for (i = 0; i < track.nr; i++) { > + add_remote_tags(buf.buf, track.items[i].string, > + name, &buf2); > + } The "track" thing is made incompatible with anything but mirror in early part of this function (outside the precontext). I highly suspect that --prefix-tags does *not* make sense when mirroring. Hence (1) we should detect and error out when --prefix-tags is used with mirror fetch near where we do the same for track used without mirror fetch already, (2) detect and error out when --prefix-tags is used with track, and (3) add "+refs/tags/*:refs/remote-tags/$name/*" just once without paying attention to track here. We may not even want add_remote_tags() helper function if we go that route. > + } > + > strbuf_reset(&buf); > strbuf_addf(&buf, "remote.%s.tagopt", name); > - git_config_set(buf.buf, > -fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); > + char* config_val = NULL; decl-after-statement. Also "char *var", not "char* var". > + switch (fetch_tags) { > + case TAGS_UNSET: > + config_val = "--no-tags"; > + break; > + case TAGS_SET: > + config_val = "--tags"; > + break; > + case TAGS_SET_PREFIX: > + config_val = "--prefix-tags"; > + break; > + default: > + die(_("Unexpected TAGS enum %d"), fetch_tags); > + break; > + } > + git_config_set(buf.buf, config_val); > } > > if (fetch && fetch_remote(name)) > diff --git a/remote.c b/remote.c > index 91eb010ca9..f383ce3cdf 100644 > --- a/remot
Re: Fetching tags overwrites existing tags
On Thu, Apr 26, 2018 at 4:24 PM, Junio C Hamano wrote: > Junio C Hamano writes: > > > Hence (1) we should detect and error out when --prefix-tags is used > with mirror fetch near where we do the same for track used without > mirror fetch already, (2) detect and error out when --prefix-tags is > used with track, and (3) add "+refs/tags/*:refs/remote-tags/$name/*" > just once without paying attention to track here. We may not even > want add_remote_tags() helper function if we go that route. > I've replied to the thread using format-email/send-email with the subject: "[RFC PATCH v2] Teach remote add the --prefix-tags option", but I misspelled Junio's email address :( I've tried to address the issues pointed out by Junio. But I've choosen not to do "(2) detect and error out when --prefix-tags is used with track". My thinking is tags are independent of tracking and it seems reasonable that they sould be included if requested. If I'm wrong I'll certainly fix it. The other change was rather than using ""+refs/tags/*:refs/remote-tags/$name/*" I've changed it to "+refs/tags/*:refs/remote/tags/$name/*" which seems cleaner. Again, if remote-tags is preferred I'll change it back. One other question, I'm not sure "--prefix-tags" is the best name for the option, maybe "--sub-tags" or "--nested-tags" or ... -- Wink
Re: Fetching tags overwrites existing tags
On Fri, Apr 27, 2018 at 12:08 PM, Wink Saville wrote: > > The other change was rather than using > ""+refs/tags/*:refs/remote-tags/$name/*" > I've changed it to "+refs/tags/*:refs/remote/tags/$name/*" which seems > cleaner. > Again, if remote-tags is preferred I'll change it back. >From looking at the code, it looks like you mean "+refs/tags/*:refs/remotes/tags/$name/*". The issue with that approach is that it collides with a remote named "tags". "refs/remote-tags", on the other hand, represents a new-to-Git path, one that won't already be in use by any other standard functionality. That seems like a better approach than hoping no one out there will call one of their remotes "tags". Bryan
Re: Fetching tags overwrites existing tags
On Tue, Apr 24, 2018 at 9:57 PM, Wink Saville wrote: > If have a repository with a tag "v1.0.0" and I add a remote repository > which also has a tag "v1.0.0" tag is overwritten. I feel like this thread has gotten somewhat side-tracked by the valid discussion about whether we should have remote tracking tags, but the much easier thing to fix is that the "+" prefix for refs/tags/* means nothing. I noticed this when working on fetch.pruneTags in the last release, but didn't dig further. I.e. if you clone git.git and update "master" and a tag: $ git fetch origin 'refs/heads/*:refs/heads/*' --dry-run >From github.com:git/git ! [rejected] master -> master (non-fast-forward) $ git fetch origin '+refs/heads/*:refs/heads/*' --dry-run >From github.com:git/git + 969e05fae2...1f1cddd558 master -> master (forced update) Here "+" does the right thing, but then: $ git fetch origin 'refs/tags/*:refs/tags/*' --dry-run >From github.com:git/git t [tag update]v2.17.0-> v2.17.0 $ git fetch origin '+refs/tags/*:refs/tags/*' --dry-run >From github.com:git/git t [tag update]v2.17.0-> v2.17.0 Here the former shouldn't be clobbering the existing tag.
Re: Fetching tags overwrites existing tags
On Fri, Apr 27, 2018 at 12:08 PM, Wink Saville wrote: > On Thu, Apr 26, 2018 at 4:24 PM, Junio C Hamano wrote: >> Junio C Hamano writes: >> >> >> Hence (1) we should detect and error out when --prefix-tags is used >> with mirror fetch near where we do the same for track used without >> mirror fetch already, (2) detect and error out when --prefix-tags is >> used with track, and (3) add "+refs/tags/*:refs/remote-tags/$name/*" >> just once without paying attention to track here. We may not even >> want add_remote_tags() helper function if we go that route. >> > > I've replied to the thread using format-email/send-email with the > subject: "[RFC PATCH v2] Teach remote add the --prefix-tags option", > but I misspelled Junio's email address :( > > I've tried to address the issues pointed out by Junio. But I've choosen > not to do "(2) detect and error out when --prefix-tags is used with track". > My thinking is tags are independent of tracking and it seems reasonable > that they sould be included if requested. If I'm wrong I'll certainly fix it. > > The other change was rather than using > ""+refs/tags/*:refs/remote-tags/$name/*" > I've changed it to "+refs/tags/*:refs/remote/tags/$name/*" which seems > cleaner. > Again, if remote-tags is preferred I'll change it back. The only main concern I have with "remote" is that it is very similar but not exactly the same as "remotes". Unfortunately, it is not possible in *every* circumstance to use remotes. Personally, I'd prefer we used "refs/remote//tags" rather than "refs/remote/tags/", and possibly plan to migrate from refs/remotes// to refs/remote//heads/ This is mostly so that future additions of things like notes, replaces, or really *any* refs would automatically drop into "refs/remotes//", which is a longer term goal I've had for a while (though i haven't been able to put much time to it at present). Historically, I proposed using "tracking" instead of "remote", but I am ok with any name we choose as long as it doesn't create conflicts. Thanks, Jake > > One other question, I'm not sure "--prefix-tags" is the best name for > the option, > maybe "--sub-tags" or "--nested-tags" or ... > > -- Wink
Re: Fetching tags overwrites existing tags
I'm going on vacation until May 17 and will have limited connectivity. I've created a new patch series, "Optional sub hierarchy for remote tags" [1] that I'd appreciate comments and if someone wants to take this over in my absence that would be great. I'd sure like to see this continue to move forward. In v4 I've tweaked git tag -l and added a test, so for me it has the minimal functionality I'd need to make use of it. -- Wink https://public-inbox.org/git/xmqqbme51rgn@gitster-ct.c.googlers.com/T/#m89df9b973ab55d85eae72dd749e038354ea3a250
Re: Fetching tags overwrites existing tags
On Fri, Apr 27, 2018 at 12:13 PM, Bryan Turner wrote: > On Fri, Apr 27, 2018 at 12:08 PM, Wink Saville wrote: >> >> The other change was rather than using >> ""+refs/tags/*:refs/remote-tags/$name/*" >> I've changed it to "+refs/tags/*:refs/remote/tags/$name/*" which seems >> cleaner. >> Again, if remote-tags is preferred I'll change it back. > > > From looking at the code, it looks like you mean > "+refs/tags/*:refs/remotes/tags/$name/*". > > The issue with that approach is that it collides with a remote named > "tags". "refs/remote-tags", on the other hand, represents a new-to-Git > path, one that won't already be in use by any other standard > functionality. That seems like a better approach than hoping no one > out there will call one of their remotes "tags". > > Bryan Note that my suggestion was very specific "remote" not pluralized, which is obviously a bit confusing, since there's remote and "remotes". The goal being that you put "remote//" followed by the full remote ref minus the refs prefix. It specifically is attempting to avoid the problem of expanding "remotes". Unfortunately, I don't have a better alternative format, and i very much want to avoid having to do "remote-tags", "remote-notes", "remote-replaces", "remote-meta" etc... In that spirit, I'm working to hopefully propose something today. Thanks, Jake