summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2018-09-17 20:54:00 (GMT)
committerJunio C Hamano <gitster@pobox.com>2018-09-17 20:54:00 (GMT)
commitd39cab3989f9e660cae124f78143369b13ad2901 (patch)
treec7968b5d7ff14c5d4a2207e101a92e17cbbbc964 /builtin
parent1c515bf7e2b395509a122fb92cd6f925bf09a6fe (diff)
parent0bc8d71b99e91c9e90b519073b639a5066119591 (diff)
downloadgit-d39cab3989f9e660cae124f78143369b13ad2901.zip
git-d39cab3989f9e660cae124f78143369b13ad2901.tar.gz
git-d39cab3989f9e660cae124f78143369b13ad2901.tar.bz2
Merge branch 'ab/fetch-tags-noclobber'
The rules used by "git push" and "git fetch" to determine if a ref can or cannot be updated were inconsistent; specifically, fetching to update existing tags were allowed even though tags are supposed to be unmoving anchoring points. "git fetch" was taught to forbid updates to existing tags without the "--force" option. * ab/fetch-tags-noclobber: fetch: stop clobbering existing tags without --force fetch: document local ref updates with/without --force push doc: correct lies about how push refspecs work push doc: move mention of "tag <tag>" later in the prose push doc: remove confusing mention of remote merger fetch tests: add a test for clobbering tag behavior push tests: use spaces in interpolated string push tests: make use of unused $1 in test description fetch: change "branch" to "reference" in --force -h output
Diffstat (limited to 'builtin')
-rw-r--r--builtin/fetch.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index dc0931f..0696abf 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -115,7 +115,7 @@ static struct option builtin_fetch_options[] = {
N_("append to .git/FETCH_HEAD instead of overwriting")),
OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
N_("path to upload pack on remote end")),
- OPT__FORCE(&force, N_("force overwrite of local branch"), 0),
+ OPT__FORCE(&force, N_("force overwrite of local reference"), 0),
OPT_BOOL('m', "multiple", &multiple,
N_("fetch from multiple remotes")),
OPT_SET_INT('t', "tags", &tags,
@@ -668,12 +668,18 @@ static int update_local_ref(struct ref *ref,
if (!is_null_oid(&ref->old_oid) &&
starts_with(ref->name, "refs/tags/")) {
- int r;
- r = s_update_ref("updating tag", ref, 0);
- format_display(display, r ? '!' : 't', _("[tag update]"),
- r ? _("unable to update local ref") : NULL,
- remote, pretty_ref, summary_width);
- return r;
+ if (force || ref->force) {
+ int r;
+ r = s_update_ref("updating tag", ref, 0);
+ format_display(display, r ? '!' : 't', _("[tag update]"),
+ r ? _("unable to update local ref") : NULL,
+ remote, pretty_ref, summary_width);
+ return r;
+ } else {
+ format_display(display, '!', _("[rejected]"), _("would clobber existing tag"),
+ remote, pretty_ref, summary_width);
+ return 1;
+ }
}
current = lookup_commit_reference_gently(the_repository,