Merge branch 'tm/fetch-prune'
Fetching 'frotz' branch with "git fetch", while having 'frotz/nitfol' remote-tracking branch from an earlier fetch, would error out, primarily because the command has not been told to remove anything on our side. In such a case, "git fetch --prune" can be used to remove 'frotz/nitfol' to make room to fetch and store 'frotz' remote-tracking branch. * tm/fetch-prune: fetch --prune: Run prune before fetching fetch --prune: always print header url
This commit is contained in:
commit
666b4c2670
@ -44,6 +44,7 @@ static struct transport *gtransport;
|
|||||||
static struct transport *gsecondary;
|
static struct transport *gsecondary;
|
||||||
static const char *submodule_prefix = "";
|
static const char *submodule_prefix = "";
|
||||||
static const char *recurse_submodules_default;
|
static const char *recurse_submodules_default;
|
||||||
|
static int shown_url = 0;
|
||||||
|
|
||||||
static int option_parse_recurse_submodules(const struct option *opt,
|
static int option_parse_recurse_submodules(const struct option *opt,
|
||||||
const char *arg, int unset)
|
const char *arg, int unset)
|
||||||
@ -535,7 +536,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
int url_len, i, shown_url = 0, rc = 0;
|
int url_len, i, rc = 0;
|
||||||
struct strbuf note = STRBUF_INIT;
|
struct strbuf note = STRBUF_INIT;
|
||||||
const char *what, *kind;
|
const char *what, *kind;
|
||||||
struct ref *rm;
|
struct ref *rm;
|
||||||
@ -708,17 +709,36 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
|
static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
|
||||||
|
const char *raw_url)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int url_len, i, result = 0;
|
||||||
struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
|
struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
|
||||||
|
char *url;
|
||||||
const char *dangling_msg = dry_run
|
const char *dangling_msg = dry_run
|
||||||
? _(" (%s will become dangling)")
|
? _(" (%s will become dangling)")
|
||||||
: _(" (%s has become dangling)");
|
: _(" (%s has become dangling)");
|
||||||
|
|
||||||
|
if (raw_url)
|
||||||
|
url = transport_anonymize_url(raw_url);
|
||||||
|
else
|
||||||
|
url = xstrdup("foreign");
|
||||||
|
|
||||||
|
url_len = strlen(url);
|
||||||
|
for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
|
||||||
|
;
|
||||||
|
|
||||||
|
url_len = i + 1;
|
||||||
|
if (4 < i && !strncmp(".git", url + i - 3, 4))
|
||||||
|
url_len = i - 3;
|
||||||
|
|
||||||
for (ref = stale_refs; ref; ref = ref->next) {
|
for (ref = stale_refs; ref; ref = ref->next) {
|
||||||
if (!dry_run)
|
if (!dry_run)
|
||||||
result |= delete_ref(ref->name, NULL, 0);
|
result |= delete_ref(ref->name, NULL, 0);
|
||||||
|
if (verbosity >= 0 && !shown_url) {
|
||||||
|
fprintf(stderr, _("From %.*s\n"), url_len, url);
|
||||||
|
shown_url = 1;
|
||||||
|
}
|
||||||
if (verbosity >= 0) {
|
if (verbosity >= 0) {
|
||||||
fprintf(stderr, " x %-*s %-*s -> %s\n",
|
fprintf(stderr, " x %-*s %-*s -> %s\n",
|
||||||
TRANSPORT_SUMMARY(_("[deleted]")),
|
TRANSPORT_SUMMARY(_("[deleted]")),
|
||||||
@ -726,6 +746,7 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
|
|||||||
warn_dangling_symref(stderr, dangling_msg, ref->name);
|
warn_dangling_symref(stderr, dangling_msg, ref->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(url);
|
||||||
free_refs(stale_refs);
|
free_refs(stale_refs);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -842,11 +863,6 @@ static int do_fetch(struct transport *transport,
|
|||||||
|
|
||||||
if (tags == TAGS_DEFAULT && autotags)
|
if (tags == TAGS_DEFAULT && autotags)
|
||||||
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
|
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
|
||||||
if (fetch_refs(transport, ref_map)) {
|
|
||||||
free_refs(ref_map);
|
|
||||||
retcode = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (prune) {
|
if (prune) {
|
||||||
/*
|
/*
|
||||||
* We only prune based on refspecs specified
|
* We only prune based on refspecs specified
|
||||||
@ -854,13 +870,19 @@ static int do_fetch(struct transport *transport,
|
|||||||
* don't care whether --tags was specified.
|
* don't care whether --tags was specified.
|
||||||
*/
|
*/
|
||||||
if (ref_count) {
|
if (ref_count) {
|
||||||
prune_refs(refs, ref_count, ref_map);
|
prune_refs(refs, ref_count, ref_map, transport->url);
|
||||||
} else {
|
} else {
|
||||||
prune_refs(transport->remote->fetch,
|
prune_refs(transport->remote->fetch,
|
||||||
transport->remote->fetch_refspec_nr,
|
transport->remote->fetch_refspec_nr,
|
||||||
ref_map);
|
ref_map,
|
||||||
|
transport->url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fetch_refs(transport, ref_map)) {
|
||||||
|
free_refs(ref_map);
|
||||||
|
retcode = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
free_refs(ref_map);
|
free_refs(ref_map);
|
||||||
|
|
||||||
/* if neither --no-tags nor --tags was specified, do automated tag
|
/* if neither --no-tags nor --tags was specified, do automated tag
|
||||||
|
@ -614,4 +614,30 @@ test_expect_success 'all boundary commits are excluded' '
|
|||||||
test_bundle_object_count .git/objects/pack/pack-${pack##pack }.pack 3
|
test_bundle_object_count .git/objects/pack/pack-${pack##pack }.pack 3
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'fetch --prune prints the remotes url' '
|
||||||
|
git branch goodbye &&
|
||||||
|
git clone . only-prunes &&
|
||||||
|
git branch -D goodbye &&
|
||||||
|
(
|
||||||
|
cd only-prunes &&
|
||||||
|
git fetch --prune origin 2>&1 | head -n1 >../actual
|
||||||
|
) &&
|
||||||
|
echo "From ${D}/." >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'branchname D/F conflict resolved by --prune' '
|
||||||
|
git branch dir/file &&
|
||||||
|
git clone . prune-df-conflict &&
|
||||||
|
git branch -D dir/file &&
|
||||||
|
git branch dir &&
|
||||||
|
(
|
||||||
|
cd prune-df-conflict &&
|
||||||
|
git fetch --prune &&
|
||||||
|
git rev-parse origin/dir >../actual
|
||||||
|
) &&
|
||||||
|
git rev-parse dir >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user