Skip to content

Commit 80eac92

Browse files
committed
Merge branch 'il/rev-glob'
2 parents e73bbd9 + e2b53e5 commit 80eac92

File tree

9 files changed

+357
-19
lines changed

9 files changed

+357
-19
lines changed

Documentation/git-log.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ git log --follow builtin-rev-list.c::
107107
those commits that occurred before the file was given its
108108
present name.
109109

110+
git log --branches --not --remotes=origin::
111+
112+
Shows all commits that are in any of local branches but not in
113+
any of remote tracking branches for 'origin' (what you have that
114+
origin doesn't).
115+
116+
git log master --not --remotes=*/master::
117+
118+
Shows all commits that are in local master but not in any remote
119+
repository master branches.
120+
110121
Discussion
111122
----------
112123

Documentation/git-rev-list.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ SYNOPSIS
2121
[ \--full-history ]
2222
[ \--not ]
2323
[ \--all ]
24-
[ \--branches ]
25-
[ \--tags ]
26-
[ \--remotes ]
24+
[ \--branches[=pattern] ]
25+
[ \--tags=[pattern] ]
26+
[ \--remotes=[pattern] ]
27+
[ \--glob=glob-pattern ]
2728
[ \--stdin ]
2829
[ \--quiet ]
2930
[ \--topo-order ]

Documentation/git-rev-parse.txt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,24 @@ OPTIONS
103103
--all::
104104
Show all refs found in `$GIT_DIR/refs`.
105105

106-
--branches::
107-
Show branch refs found in `$GIT_DIR/refs/heads`.
108-
109-
--tags::
110-
Show tag refs found in `$GIT_DIR/refs/tags`.
111-
112-
--remotes::
113-
Show tag refs found in `$GIT_DIR/refs/remotes`.
106+
--branches[=pattern]::
107+
--tags[=pattern]::
108+
--remotes[=pattern]::
109+
Show all branches, tags, or remote-tracking branches,
110+
respectively (i.e., refs found in `$GIT_DIR/refs/heads`,
111+
`$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`,
112+
respectively).
113+
+
114+
If a `pattern` is given, only refs matching the given shell glob are
115+
shown. If the pattern does not contain a globbing character (`?`,
116+
`\*`, or `[`), it is turned into a prefix match by appending `/\*`.
117+
118+
--glob=pattern::
119+
Show all refs matching the shell glob pattern `pattern`. If
120+
the pattern does not start with `refs/`, this is automatically
121+
prepended. If the pattern does not contain a globbing
122+
character (`?`, `\*`, or `[`), it is turned into a prefix
123+
match by appending `/\*`.
114124

115125
--show-toplevel::
116126
Show the absolute path of the top-level directory.

Documentation/rev-list-options.txt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,20 +228,33 @@ endif::git-rev-list[]
228228
Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the
229229
command line as '<commit>'.
230230

231-
--branches::
231+
--branches[=pattern]::
232232

233233
Pretend as if all the refs in `$GIT_DIR/refs/heads` are listed
234-
on the command line as '<commit>'.
234+
on the command line as '<commit>'. If `pattern` is given, limit
235+
branches to ones matching given shell glob. If pattern lacks '?',
236+
'*', or '[', '/*' at the end is impiled.
235237

236-
--tags::
238+
--tags[=pattern]::
237239

238240
Pretend as if all the refs in `$GIT_DIR/refs/tags` are listed
239-
on the command line as '<commit>'.
241+
on the command line as '<commit>'. If `pattern` is given, limit
242+
tags to ones matching given shell glob. If pattern lacks '?', '*',
243+
or '[', '/*' at the end is impiled.
240244

241-
--remotes::
245+
--remotes[=pattern]::
242246

243247
Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed
244-
on the command line as '<commit>'.
248+
on the command line as '<commit>'. If `pattern`is given, limit
249+
remote tracking branches to ones matching given shell glob.
250+
If pattern lacks '?', '*', or '[', '/*' at the end is impiled.
251+
252+
--glob=glob-pattern::
253+
Pretend as if all the refs matching shell glob `glob-pattern`
254+
are listed on the command line as '<commit>'. Leading 'refs/',
255+
is automatically prepended if missing. If pattern lacks '?', '*',
256+
or '[', '/*' at the end is impiled.
257+
245258

246259
ifndef::git-rev-list[]
247260
--bisect::

builtin-rev-parse.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static int is_rev_argument(const char *arg)
4141
"--all",
4242
"--bisect",
4343
"--dense",
44+
"--branches=",
4445
"--branches",
4546
"--header",
4647
"--max-age=",
@@ -51,8 +52,11 @@ static int is_rev_argument(const char *arg)
5152
"--objects-edge",
5253
"--parents",
5354
"--pretty",
55+
"--remotes=",
5456
"--remotes",
57+
"--glob=",
5558
"--sparse",
59+
"--tags=",
5660
"--tags",
5761
"--topo-order",
5862
"--date-order",
@@ -569,14 +573,33 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
569573
for_each_ref_in("refs/bisect/good", anti_reference, NULL);
570574
continue;
571575
}
576+
if (!prefixcmp(arg, "--branches=")) {
577+
for_each_glob_ref_in(show_reference, arg + 11,
578+
"refs/heads/", NULL);
579+
continue;
580+
}
572581
if (!strcmp(arg, "--branches")) {
573582
for_each_branch_ref(show_reference, NULL);
574583
continue;
575584
}
585+
if (!prefixcmp(arg, "--tags=")) {
586+
for_each_glob_ref_in(show_reference, arg + 7,
587+
"refs/tags/", NULL);
588+
continue;
589+
}
576590
if (!strcmp(arg, "--tags")) {
577591
for_each_tag_ref(show_reference, NULL);
578592
continue;
579593
}
594+
if (!prefixcmp(arg, "--glob=")) {
595+
for_each_glob_ref(show_reference, arg + 7, NULL);
596+
continue;
597+
}
598+
if (!prefixcmp(arg, "--remotes=")) {
599+
for_each_glob_ref_in(show_reference, arg + 10,
600+
"refs/remotes/", NULL);
601+
continue;
602+
}
580603
if (!strcmp(arg, "--remotes")) {
581604
for_each_remote_ref(show_reference, NULL);
582605
continue;

refs.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,13 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
519519
return ref;
520520
}
521521

522+
/* The argument to filter_refs */
523+
struct ref_filter {
524+
const char *pattern;
525+
each_ref_fn *fn;
526+
void *cb_data;
527+
};
528+
522529
int read_ref(const char *ref, unsigned char *sha1)
523530
{
524531
if (resolve_ref(ref, sha1, 1, NULL))
@@ -545,6 +552,15 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
545552
return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
546553
}
547554

555+
static int filter_refs(const char *ref, const unsigned char *sha, int flags,
556+
void *data)
557+
{
558+
struct ref_filter *filter = (struct ref_filter *)data;
559+
if (fnmatch(filter->pattern, ref, 0))
560+
return 0;
561+
return filter->fn(ref, sha, flags, filter->cb_data);
562+
}
563+
548564
int peel_ref(const char *ref, unsigned char *sha1)
549565
{
550566
int flag;
@@ -674,6 +690,43 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)
674690
return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data);
675691
}
676692

693+
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
694+
const char *prefix, void *cb_data)
695+
{
696+
struct strbuf real_pattern = STRBUF_INIT;
697+
struct ref_filter filter;
698+
const char *has_glob_specials;
699+
int ret;
700+
701+
if (!prefix && prefixcmp(pattern, "refs/"))
702+
strbuf_addstr(&real_pattern, "refs/");
703+
else if (prefix)
704+
strbuf_addstr(&real_pattern, prefix);
705+
strbuf_addstr(&real_pattern, pattern);
706+
707+
has_glob_specials = strpbrk(pattern, "?*[");
708+
if (!has_glob_specials) {
709+
/* Append impiled '/' '*' if not present. */
710+
if (real_pattern.buf[real_pattern.len - 1] != '/')
711+
strbuf_addch(&real_pattern, '/');
712+
/* No need to check for '*', there is none. */
713+
strbuf_addch(&real_pattern, '*');
714+
}
715+
716+
filter.pattern = real_pattern.buf;
717+
filter.fn = fn;
718+
filter.cb_data = cb_data;
719+
ret = for_each_ref(filter_refs, &filter);
720+
721+
strbuf_release(&real_pattern);
722+
return ret;
723+
}
724+
725+
int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
726+
{
727+
return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
728+
}
729+
677730
int for_each_rawref(each_ref_fn fn, void *cb_data)
678731
{
679732
return do_for_each_ref("refs/", fn, 0,

refs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ extern int for_each_tag_ref(each_ref_fn, void *);
2525
extern int for_each_branch_ref(each_ref_fn, void *);
2626
extern int for_each_remote_ref(each_ref_fn, void *);
2727
extern int for_each_replace_ref(each_ref_fn, void *);
28+
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
29+
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
2830

2931
/* can be used to learn about broken ref and symref */
3032
extern int for_each_rawref(each_ref_fn, void *);

revision.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,12 +699,18 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
699699
return 0;
700700
}
701701

702+
static void init_all_refs_cb(struct all_refs_cb *cb, struct rev_info *revs,
703+
unsigned flags)
704+
{
705+
cb->all_revs = revs;
706+
cb->all_flags = flags;
707+
}
708+
702709
static void handle_refs(struct rev_info *revs, unsigned flags,
703710
int (*for_each)(each_ref_fn, void *))
704711
{
705712
struct all_refs_cb cb;
706-
cb.all_revs = revs;
707-
cb.all_flags = flags;
713+
init_all_refs_cb(&cb, revs, flags);
708714
for_each(handle_one_ref, &cb);
709715
}
710716

@@ -1361,6 +1367,30 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
13611367
handle_refs(revs, flags, for_each_remote_ref);
13621368
continue;
13631369
}
1370+
if (!prefixcmp(arg, "--glob=")) {
1371+
struct all_refs_cb cb;
1372+
init_all_refs_cb(&cb, revs, flags);
1373+
for_each_glob_ref(handle_one_ref, arg + 7, &cb);
1374+
continue;
1375+
}
1376+
if (!prefixcmp(arg, "--branches=")) {
1377+
struct all_refs_cb cb;
1378+
init_all_refs_cb(&cb, revs, flags);
1379+
for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
1380+
continue;
1381+
}
1382+
if (!prefixcmp(arg, "--tags=")) {
1383+
struct all_refs_cb cb;
1384+
init_all_refs_cb(&cb, revs, flags);
1385+
for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
1386+
continue;
1387+
}
1388+
if (!prefixcmp(arg, "--remotes=")) {
1389+
struct all_refs_cb cb;
1390+
init_all_refs_cb(&cb, revs, flags);
1391+
for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
1392+
continue;
1393+
}
13641394
if (!strcmp(arg, "--reflog")) {
13651395
handle_reflog(revs, flags);
13661396
continue;

0 commit comments

Comments
 (0)