2018-05-17 06:57:48 +08:00
|
|
|
#ifndef REFSPEC_H
|
|
|
|
#define REFSPEC_H
|
|
|
|
|
|
|
|
#define TAG_REFSPEC "refs/tags/*:refs/tags/*"
|
2018-05-17 06:57:49 +08:00
|
|
|
extern const struct refspec_item *tag_refspec;
|
2018-05-17 06:57:48 +08:00
|
|
|
|
2020-08-15 08:25:07 +08:00
|
|
|
/**
|
refspec: add support for negative refspecs
Both fetch and push support pattern refspecs which allow fetching or
pushing references that match a specific pattern. Because these patterns
are globs, they have somewhat limited ability to express more complex
situations.
For example, suppose you wish to fetch all branches from a remote except
for a specific one. To allow this, you must setup a set of refspecs
which match only the branches you want. Because refspecs are either
explicit name matches, or simple globs, many patterns cannot be
expressed.
Add support for a new type of refspec, referred to as "negative"
refspecs. These are prefixed with a '^' and mean "exclude any ref
matching this refspec". They can only have one "side" which always
refers to the source. During a fetch, this refers to the name of the ref
on the remote. During a push, this refers to the name of the ref on the
local side.
With negative refspecs, users can express more complex patterns. For
example:
git fetch origin refs/heads/*:refs/remotes/origin/* ^refs/heads/dontwant
will fetch all branches on origin into remotes/origin, but will exclude
fetching the branch named dontwant.
Refspecs today are commutative, meaning that order doesn't expressly
matter. Rather than forcing an implied order, negative refspecs will
always be applied last. That is, in order to match, a ref must match at
least one positive refspec, and match none of the negative refspecs.
This is similar to how negative pathspecs work.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-01 05:25:29 +08:00
|
|
|
* A struct refspec_item holds the parsed interpretation of a refspec. If it
|
|
|
|
* will force updates (starts with a '+'), force is true. If it is a pattern
|
|
|
|
* (sides end with '*') pattern is true. If it is a negative refspec, (starts
|
|
|
|
* with '^'), negative is true. src and dest are the two sides (including '*'
|
|
|
|
* characters if present); if there is only one side, it is src, and dst is
|
|
|
|
* NULL; if sides exist but are empty (i.e., the refspec either starts or ends
|
|
|
|
* with ':'), the corresponding side is "".
|
2020-08-15 08:25:07 +08:00
|
|
|
*
|
|
|
|
* remote_find_tracking(), given a remote and a struct refspec_item with either src
|
|
|
|
* or dst filled out, will fill out the other such that the result is in the
|
|
|
|
* "fetch" specification for the remote (note that this evaluates patterns and
|
|
|
|
* returns a single result).
|
|
|
|
*/
|
2018-05-17 06:57:49 +08:00
|
|
|
struct refspec_item {
|
2018-05-17 06:57:48 +08:00
|
|
|
unsigned force : 1;
|
|
|
|
unsigned pattern : 1;
|
|
|
|
unsigned matching : 1;
|
|
|
|
unsigned exact_sha1 : 1;
|
refspec: add support for negative refspecs
Both fetch and push support pattern refspecs which allow fetching or
pushing references that match a specific pattern. Because these patterns
are globs, they have somewhat limited ability to express more complex
situations.
For example, suppose you wish to fetch all branches from a remote except
for a specific one. To allow this, you must setup a set of refspecs
which match only the branches you want. Because refspecs are either
explicit name matches, or simple globs, many patterns cannot be
expressed.
Add support for a new type of refspec, referred to as "negative"
refspecs. These are prefixed with a '^' and mean "exclude any ref
matching this refspec". They can only have one "side" which always
refers to the source. During a fetch, this refers to the name of the ref
on the remote. During a push, this refers to the name of the ref on the
local side.
With negative refspecs, users can express more complex patterns. For
example:
git fetch origin refs/heads/*:refs/remotes/origin/* ^refs/heads/dontwant
will fetch all branches on origin into remotes/origin, but will exclude
fetching the branch named dontwant.
Refspecs today are commutative, meaning that order doesn't expressly
matter. Rather than forcing an implied order, negative refspecs will
always be applied last. That is, in order to match, a ref must match at
least one positive refspec, and match none of the negative refspecs.
This is similar to how negative pathspecs work.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-01 05:25:29 +08:00
|
|
|
unsigned negative : 1;
|
2018-05-17 06:57:48 +08:00
|
|
|
|
|
|
|
char *src;
|
|
|
|
char *dst;
|
|
|
|
};
|
|
|
|
|
2018-05-17 06:57:51 +08:00
|
|
|
#define REFSPEC_FETCH 1
|
|
|
|
#define REFSPEC_PUSH 0
|
|
|
|
|
|
|
|
#define REFSPEC_INIT_FETCH { .fetch = REFSPEC_FETCH }
|
|
|
|
#define REFSPEC_INIT_PUSH { .fetch = REFSPEC_PUSH }
|
|
|
|
|
2019-11-18 05:04:45 +08:00
|
|
|
/**
|
2020-08-15 08:25:07 +08:00
|
|
|
* An array of strings can be parsed into a struct refspec using
|
2019-11-18 05:04:45 +08:00
|
|
|
* parse_fetch_refspec() or parse_push_refspec().
|
|
|
|
*/
|
2018-05-17 06:57:51 +08:00
|
|
|
struct refspec {
|
|
|
|
struct refspec_item *items;
|
|
|
|
int alloc;
|
|
|
|
int nr;
|
|
|
|
|
|
|
|
const char **raw;
|
|
|
|
int raw_alloc;
|
|
|
|
int raw_nr;
|
|
|
|
|
|
|
|
int fetch;
|
|
|
|
};
|
|
|
|
|
2018-06-06 03:54:39 +08:00
|
|
|
int refspec_item_init(struct refspec_item *item, const char *refspec,
|
|
|
|
int fetch);
|
2018-06-06 03:54:38 +08:00
|
|
|
void refspec_item_init_or_die(struct refspec_item *item, const char *refspec,
|
|
|
|
int fetch);
|
2018-05-17 06:57:51 +08:00
|
|
|
void refspec_item_clear(struct refspec_item *item);
|
|
|
|
void refspec_init(struct refspec *rs, int fetch);
|
|
|
|
void refspec_append(struct refspec *rs, const char *refspec);
|
2020-09-05 22:49:30 +08:00
|
|
|
__attribute__((format (printf,2,3)))
|
|
|
|
void refspec_appendf(struct refspec *rs, const char *fmt, ...);
|
2018-05-17 06:57:51 +08:00
|
|
|
void refspec_appendn(struct refspec *rs, const char **refspecs, int nr);
|
|
|
|
void refspec_clear(struct refspec *rs);
|
|
|
|
|
2018-05-17 06:57:52 +08:00
|
|
|
int valid_fetch_refspec(const char *refspec);
|
|
|
|
|
argv-array: rename to strvec
The name "argv-array" isn't very good, because it describes what the
data type can be used for (program argument arrays), not what it
actually is (a dynamically-growing string array that maintains a
NULL-terminator invariant). This leads to people being hesitant to use
it for other cases where it would actually be a good fit. The existing
name is also clunky to use. It's overly long, and the name often leads
to saying things like "argv.argv" (i.e., the field names overlap with
variable names, since they're describing the use, not the type). Let's
give it a more neutral name.
I settled on "strvec" because "vector" is the name for a dynamic array
type in many programming languages. "strarray" would work, too, but it's
longer and a bit more awkward to say (and don't we all say these things
in our mind as we type them?).
A more extreme direction would be a generic data structure which stores
a NULL-terminated of _any_ type. That would be easy to do with void
pointers, but we'd lose some type safety for the existing cases. Plus it
raises questions about memory allocation and ownership. So I limited
myself here to changing names only, and not semantics. If we do find a
use for that more generic data type, we could perhaps implement it at a
lower level and then provide type-safe wrappers around it for strings.
But that can come later.
This patch does the minimum to convert the struct and function names in
the header and implementation, leaving a few things for follow-on
patches:
- files retain their original names for now
- struct field names are retained for now
- there's a preprocessor compat layer that lets most users remain the
same for now. The exception is headers which made a manual forward
declaration of the struct. I've converted them (and their dependent
function declarations) here.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-29 04:23:25 +08:00
|
|
|
struct strvec;
|
2018-05-31 15:23:39 +08:00
|
|
|
/*
|
|
|
|
* Determine what <prefix> values to pass to the peer in ref-prefix lines
|
|
|
|
* (see Documentation/technical/protocol-v2.txt).
|
|
|
|
*/
|
2018-05-17 07:48:21 +08:00
|
|
|
void refspec_ref_prefixes(const struct refspec *rs,
|
argv-array: rename to strvec
The name "argv-array" isn't very good, because it describes what the
data type can be used for (program argument arrays), not what it
actually is (a dynamically-growing string array that maintains a
NULL-terminator invariant). This leads to people being hesitant to use
it for other cases where it would actually be a good fit. The existing
name is also clunky to use. It's overly long, and the name often leads
to saying things like "argv.argv" (i.e., the field names overlap with
variable names, since they're describing the use, not the type). Let's
give it a more neutral name.
I settled on "strvec" because "vector" is the name for a dynamic array
type in many programming languages. "strarray" would work, too, but it's
longer and a bit more awkward to say (and don't we all say these things
in our mind as we type them?).
A more extreme direction would be a generic data structure which stores
a NULL-terminated of _any_ type. That would be easy to do with void
pointers, but we'd lose some type safety for the existing cases. Plus it
raises questions about memory allocation and ownership. So I limited
myself here to changing names only, and not semantics. If we do find a
use for that more generic data type, we could perhaps implement it at a
lower level and then provide type-safe wrappers around it for strings.
But that can come later.
This patch does the minimum to convert the struct and function names in
the header and implementation, leaving a few things for follow-on
patches:
- files retain their original names for now
- struct field names are retained for now
- there's a preprocessor compat layer that lets most users remain the
same for now. The exception is headers which made a manual forward
declaration of the struct. I've converted them (and their dependent
function declarations) here.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-29 04:23:25 +08:00
|
|
|
struct strvec *ref_prefixes);
|
2018-05-17 07:48:21 +08:00
|
|
|
|
2018-05-17 06:57:48 +08:00
|
|
|
#endif /* REFSPEC_H */
|