Merge branch 'sp/remote'
* sp/remote: Make "git-remote rm" delete refs acccording to fetch specs Make "git-remote prune" delete refs according to fetch specs Remove unused remote_prefix member in builtin-remote
This commit is contained in:
commit
0cc01c9657
@ -206,7 +206,6 @@ static void read_branches(void)
|
||||
|
||||
struct ref_states {
|
||||
struct remote *remote;
|
||||
struct strbuf remote_prefix;
|
||||
struct path_list new, stale, tracked;
|
||||
};
|
||||
|
||||
@ -262,36 +261,72 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
|
||||
}
|
||||
free_refs(fetch_map);
|
||||
|
||||
strbuf_addf(&states->remote_prefix,
|
||||
"refs/remotes/%s/", states->remote->name);
|
||||
for_each_ref(handle_one_branch, states);
|
||||
sort_path_list(&states->stale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct known_remote {
|
||||
struct known_remote *next;
|
||||
struct remote *remote;
|
||||
};
|
||||
|
||||
struct known_remotes {
|
||||
struct remote *to_delete;
|
||||
struct known_remote *list;
|
||||
};
|
||||
|
||||
static int add_known_remote(struct remote *remote, void *cb_data)
|
||||
{
|
||||
struct known_remotes *all = cb_data;
|
||||
struct known_remote *r;
|
||||
|
||||
if (!strcmp(all->to_delete->name, remote->name))
|
||||
return 0;
|
||||
|
||||
r = xmalloc(sizeof(*r));
|
||||
r->remote = remote;
|
||||
r->next = all->list;
|
||||
all->list = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct branches_for_remote {
|
||||
const char *prefix;
|
||||
struct remote *remote;
|
||||
struct path_list *branches;
|
||||
struct known_remotes *keep;
|
||||
};
|
||||
|
||||
static int add_branch_for_removal(const char *refname,
|
||||
const unsigned char *sha1, int flags, void *cb_data)
|
||||
{
|
||||
struct branches_for_remote *branches = cb_data;
|
||||
struct refspec refspec;
|
||||
struct path_list_item *item;
|
||||
struct known_remote *kr;
|
||||
|
||||
if (!prefixcmp(refname, branches->prefix)) {
|
||||
struct path_list_item *item;
|
||||
memset(&refspec, 0, sizeof(refspec));
|
||||
refspec.dst = (char *)refname;
|
||||
if (remote_find_tracking(branches->remote, &refspec))
|
||||
return 0;
|
||||
|
||||
/* make sure that symrefs are deleted */
|
||||
if (flags & REF_ISSYMREF)
|
||||
return unlink(git_path(refname));
|
||||
|
||||
item = path_list_append(refname, branches->branches);
|
||||
item->util = xmalloc(20);
|
||||
hashcpy(item->util, sha1);
|
||||
/* don't delete a branch if another remote also uses it */
|
||||
for (kr = branches->keep->list; kr; kr = kr->next) {
|
||||
memset(&refspec, 0, sizeof(refspec));
|
||||
refspec.dst = (char *)refname;
|
||||
if (!remote_find_tracking(kr->remote, &refspec))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* make sure that symrefs are deleted */
|
||||
if (flags & REF_ISSYMREF)
|
||||
return unlink(git_path(refname));
|
||||
|
||||
item = path_list_append(refname, branches->branches);
|
||||
item->util = xmalloc(20);
|
||||
hashcpy(item->util, sha1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -316,8 +351,9 @@ static int rm(int argc, const char **argv)
|
||||
};
|
||||
struct remote *remote;
|
||||
struct strbuf buf;
|
||||
struct known_remotes known_remotes = { NULL, NULL };
|
||||
struct path_list branches = { NULL, 0, 0, 1 };
|
||||
struct branches_for_remote cb_data = { NULL, &branches };
|
||||
struct branches_for_remote cb_data = { NULL, &branches, &known_remotes };
|
||||
int i;
|
||||
|
||||
if (argc != 2)
|
||||
@ -327,6 +363,9 @@ static int rm(int argc, const char **argv)
|
||||
if (!remote)
|
||||
die("No such remote: %s", argv[1]);
|
||||
|
||||
known_remotes.to_delete = remote;
|
||||
for_each_remote(add_known_remote, &known_remotes);
|
||||
|
||||
strbuf_init(&buf, 0);
|
||||
strbuf_addf(&buf, "remote.%s", remote->name);
|
||||
if (git_config_rename_section(buf.buf, NULL) < 1)
|
||||
@ -355,9 +394,7 @@ static int rm(int argc, const char **argv)
|
||||
* the branches one by one, since for_each_ref() relies on cached
|
||||
* refs, which are invalidated when deleting a branch.
|
||||
*/
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "refs/remotes/%s/", remote->name);
|
||||
cb_data.prefix = buf.buf;
|
||||
cb_data.remote = remote;
|
||||
i = for_each_ref(add_branch_for_removal, &cb_data);
|
||||
strbuf_release(&buf);
|
||||
|
||||
@ -422,27 +459,10 @@ static int show_or_prune(int argc, const char **argv, int prune)
|
||||
states.remote->name);
|
||||
|
||||
if (prune) {
|
||||
struct strbuf buf;
|
||||
int prefix_len;
|
||||
|
||||
strbuf_init(&buf, 0);
|
||||
if (states.remote->fetch_refspec_nr == 1 &&
|
||||
states.remote->fetch->pattern &&
|
||||
!strcmp(states.remote->fetch->src,
|
||||
states.remote->fetch->dst))
|
||||
/* handle --mirror remote */
|
||||
strbuf_addstr(&buf, "refs/heads/");
|
||||
else
|
||||
strbuf_addf(&buf, "refs/remotes/%s/", *argv);
|
||||
prefix_len = buf.len;
|
||||
|
||||
for (i = 0; i < states.stale.nr; i++) {
|
||||
strbuf_setlen(&buf, prefix_len);
|
||||
strbuf_addstr(&buf, states.stale.items[i].path);
|
||||
result |= delete_ref(buf.buf, NULL);
|
||||
const char *refname = states.stale.items[i].util;
|
||||
result |= delete_ref(refname, NULL);
|
||||
}
|
||||
|
||||
strbuf_release(&buf);
|
||||
goto cleanup_states;
|
||||
}
|
||||
|
||||
|
@ -164,6 +164,24 @@ test_expect_success 'add --mirror && prune' '
|
||||
git rev-parse --verify refs/heads/side)
|
||||
'
|
||||
|
||||
test_expect_success 'add alt && prune' '
|
||||
(mkdir alttst &&
|
||||
cd alttst &&
|
||||
git init &&
|
||||
git remote add -f origin ../one &&
|
||||
git config remote.alt.url ../one &&
|
||||
git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
|
||||
(cd one &&
|
||||
git branch -m side side2) &&
|
||||
(cd alttst &&
|
||||
git rev-parse --verify refs/remotes/origin/side &&
|
||||
! git rev-parse --verify refs/remotes/origin/side2 &&
|
||||
git fetch alt &&
|
||||
git remote prune alt &&
|
||||
! git rev-parse --verify refs/remotes/origin/side &&
|
||||
git rev-parse --verify refs/remotes/origin/side2)
|
||||
'
|
||||
|
||||
cat > one/expect << EOF
|
||||
apis/master
|
||||
apis/side
|
||||
|
Loading…
Reference in New Issue
Block a user