* Re: Git SSH Authentication
From: Junio C Hamano @ 2012-02-11 7:54 UTC (permalink / raw)
To: Sitaram Chamarty; +Cc: isawk, git
In-Reply-To: <CAMK1S_jmY5KvBH8z6YKszroMai4O5ULeCBYGAGFT4CgVUAfmwg@mail.gmail.com>
Sitaram Chamarty <sitaramc@gmail.com> writes:
> Common causes of pubkey access fail:
>
> - wrong pubkey being offered: if you are using ssh-agent, make sure
> you have 'ssh-add'ed the key you want to offer. Confirm with 'ssh-add
> -l'
A failure related to this I saw is to have (too) many keys in ssh-agent,
and running ssh without telling it which exact key to use. The client
tries each key in turn and the server rejects the connection attempt after
seeing too many keys tried. "ssh -v" is useful to diagnose this mode of
failure, and an entry in ~/.ssh/config like:
Host example.com
User myusernameoverthere
IdentityFile ~/.ssh/id_rsa-for-example.com
would fix it.
^ permalink raw reply
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Michael Haggerty @ 2012-02-11 7:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Tom Grennan, pclouds, git, krh, jasampler
In-Reply-To: <7vaa4qnk4u.fsf@alter.siamese.dyndns.org>
On 02/11/2012 04:06 AM, Junio C Hamano wrote:
> Tom Grennan <tmgrennan@gmail.com> writes:
>> The following series implements !<pattern> with: git-tag, git-branch, and
>> git-for-each-ref.
>>
>> This still requires Documentation and unit test updates but I think these are
>> close to functionally complete.
>
> Do we allow a refname whose pathname component begins with '!', by the
> way? If we do, how does a user look for a tag whose name is "!xyzzy"?
> "Naming your tag !xyzzy used to be allowed but it is now forbidden after
> this patch" is not an acceptable answer---it is called a regression. If
> the negation operator were "^" or something that we explicitly forbid from
> a refname, we wouldn't have such a problem.
According to git-check-ref-format(1), '!' are allowed in reference
names. (Whether that was a good idea is another question, but now we
have to support it.)
So using "^" would be an option. A problem is that the new meaning is
not consistent with the use of "^" in rev-list, and therefore would (1)
be confusing and (2) prevent the addition of a similar syntax in rev-list.
Currently,
git rev-list A B ^C
means "revisions reachable from A or B but not from C". (For simplicity
assume that A, B, and C are literal reference names without wildcards.)
The proposal, amended to use "^" instead of "!", is that
git for-each-ref A B ^C
should mean "the reference names A and B but not C". Therefore, the command
git rev-list $(git for-each-ref A B ^C)
, which consistency suggests should do the same thing as the first
command, would in fact be equivalent to
git rev-list A B
Moreover, it *would* be nice to have this kind of exclude-branch-name
syntax in rev-parse. Many times I have wanted to type the equivalent of
gitk --all --not-branch=remotes/korg/*
That is, "show the commits starting at *all branches except for the
specified branches*". This is different than "show *the commits
starting at all branches* except for *the commits reachable from the
specified branches*", because I want to see the *complete* history of
the non-excluded branches. (Is there an easy way to do this now?) The
proposed functionality is a step forward; I could type
gitk $(git for-each-ref !remotes/korg/*)
But it would be even nicer if this could be expressed directly in rev-parse.
In summary, I suggest we consider using a more verbose syntax for this
new functionality (probably via one or more new options, for example
--not-branch=PATTERN, --not-tag=PATTERN, and/or --not-ref=PATTERN) that
cannot be confused with the existing syntax for excluding commits.
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Junio C Hamano @ 2012-02-11 7:50 UTC (permalink / raw)
To: Tom Grennan; +Cc: pclouds, git, krh, jasampler
In-Reply-To: <7vaa4qnk4u.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> ... Same
> for 1c, which I highly suspect will introduce regression without
> looking at the code (for-each-ref is prefix-match only), ...
This part needs correction. for-each-ref matches the command line
arguments differently from branch --list and tag --list in two important
ways.
(1) It allows (not "only" which was a mistake in my earlier message)
prefix matching, e.g. "for-each-ref refs/heads/", in addition to
fnmatch(); and
(2) The fnmatch() call is made with FNM_PATHMAME, which "branch --list"
and "tag --list" does not use.
Strictly speaking, therefore, if you make all three commands to use the
same matching logic, there is no way to avoid regression. If you choose
to use fnmatch() without FNM_PATHNAME, then for-each-ref suddenly starts
matching wildcards across name hierarchy boundary '/' for a pattern that
does not match today, e.g. "git for-each-ref 'refs/heads/*'" was a good
way to grab only the integration branches while excluding individual topic
branches such as refs/heads/tg/tag-points-at, but this technique can no
longer be used for such a purpose, which is an unpleasant regression.
I personally think that it was an annoying UI mistake that we let branch
and tag call fnmatch without FNM_PATHNAME, but we cannot fix it lightly,
either. People who use hierchical branch names (e.g. maint-1.0/$topic,
maint-2.0/$topic, and feature-2.0/$topic) may already be used to list all
the topics on the maintenance tracks with "branch --list 'maint*'", and we
need to keep "branch --list" and "tag --list" working as they expect.
One possible way forward (now I am talking about a longer term solution)
would be to introduce
refname_match_pattern(const char *refname,
const char **pattern,
unsigned flags);
where flags can tell the implementation if FNM_PATHNAME should be used,
and if prefix matching should be attempted, so that the three commands
share the single same matching function while still retaining their
current behaviour in the initial round. Inside the implementation, we
would use good old fnmatch(), with or without FNM_PATHNAME, depending on
the flags the caller passes.
In a future versions, we may want to have "branch/tag --list" also ask for
FNM_PATHNAME (this *is* a backward incompatible change, so it needs to be
performed across major version boundary, with backward compatibility
configurations, deprecation warnings and whole nine yards). Under the new
match function, today's "branch --list 'maint*'" needs to be spelled as
"branch --list 'maint*/*'" or something. The prefix matching is probably
safer to enable by default without causing big regression hassle if we
limit the prefix match to only patterns that end with an explicit slash,
as users already *know* today's "branch --list tg/" would not match
anything (because the pattern does not even match a brahch 'tg', so it is
unlikely they are using it and expecting only 'tg' to match), which means
that is an unlikely input we can safely give new meaning to match anything
under tg/ hierarchy.
^ permalink raw reply
* [PATCH 2/2] Revert be7c6d4 (pack-refs: remove newly empty directories)
From: Nguyễn Thái Ngọc Duy @ 2012-02-11 7:55 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Nguyễn Thái Ngọc Duy
In-Reply-To: <1328946907-31650-1-git-send-email-pclouds@gmail.com>
The functionality is taken over by prune_empty_dirs. Only code is
reverted. The added test remains to verify.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
pack-refs.c | 32 --------------------------------
1 files changed, 0 insertions(+), 32 deletions(-)
diff --git a/pack-refs.c b/pack-refs.c
index bb3a9c4..746211e 100644
--- a/pack-refs.c
+++ b/pack-refs.c
@@ -60,37 +60,6 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
return 0;
}
-/*
- * Remove empty parents, but spare refs/ and immediate subdirs.
- * Note: munges *name.
- */
-static void try_remove_empty_parents(char *name)
-{
- char *p, *q;
- int i;
- p = name;
- for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */
- while (*p && *p != '/')
- p++;
- /* tolerate duplicate slashes; see check_refname_format() */
- while (*p == '/')
- p++;
- }
- for (q = p; *q; q++)
- ;
- while (1) {
- while (q > p && *q != '/')
- q--;
- while (q > p && *(q-1) == '/')
- q--;
- if (q == p)
- break;
- *q = '\0';
- if (rmdir(git_path("%s", name)))
- break;
- }
-}
-
static int prune_empty_dirs(const char *path)
{
int nr_entries = 0, pathlen = strlen(path);
@@ -151,7 +120,6 @@ static void prune_ref(struct ref_to_prune *r)
if (lock) {
unlink_or_warn(git_path("%s", r->name));
unlock_ref(lock);
- try_remove_empty_parents(r->name);
}
}
--
1.7.8.36.g69ee2
^ permalink raw reply related
* [PATCH 1/2] pack-refs: remove all empty directories under $GIT_DIR/refs
From: Nguyễn Thái Ngọc Duy @ 2012-02-11 7:55 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Nguyễn Thái Ngọc Duy
In-Reply-To: <1328891127-17150-1-git-send-email-pclouds@gmail.com>
Deleting refs does not remove parent directories if they are empty.
Empty directories add extra overhead to startup time of most of git
commands because they have to traverse $GIT_DIR/refs.
Some directories are kept by this patch even if they are empty (refs,
refs/heads and refs/tags). The first one is one of git repository
signature. The rest is created by init-db, one may expect them to always
be there.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
v2, no more refs code change.
Part of the reason I do not want to update delete_ref() is because it
won't remove empty directories in existing repositories.
pack-refs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/pack-refs.c b/pack-refs.c
index f09a054..bb3a9c4 100644
--- a/pack-refs.c
+++ b/pack-refs.c
@@ -91,6 +91,58 @@ static void try_remove_empty_parents(char *name)
}
}
+static int prune_empty_dirs(const char *path)
+{
+ int nr_entries = 0, pathlen = strlen(path);
+ DIR *dir;
+ struct dirent *de;
+ char *subpath;
+
+ dir = opendir(git_path("%s", path));
+
+ if (!dir)
+ return 0;
+
+ subpath = xmalloc(pathlen + 257);
+ memcpy(subpath, path, pathlen);
+ if (pathlen && path[pathlen-1] != '/')
+ subpath[pathlen++] = '/';
+
+ while ((de = readdir(dir)) != NULL) {
+ struct stat st;
+ int namelen;
+
+ if (de->d_name[0] == '.') {
+ if (strcmp(de->d_name, "..") && strcmp(de->d_name, "."))
+ nr_entries++;
+ continue;
+ }
+ nr_entries++;
+ namelen = strlen(de->d_name);
+ if (namelen > 255)
+ continue;
+ if (has_extension(de->d_name, ".lock"))
+ continue;
+ memcpy(subpath + pathlen, de->d_name, namelen+1);
+ if (stat(git_path("%s", subpath), &st) < 0)
+ continue;
+ if (S_ISDIR(st.st_mode)) {
+ int removed = prune_empty_dirs(subpath);
+ if (removed)
+ nr_entries--;
+ continue;
+ }
+ }
+ free(subpath);
+ closedir(dir);
+ if (nr_entries == 0 &&
+ strcmp(path, "refs") &&
+ strcmp(path, "refs/heads") &&
+ strcmp(path, "refs/tags"))
+ return rmdir(git_path("%s", path)) == 0;
+ return 0;
+}
+
/* make sure nobody touched the ref, and unlink */
static void prune_ref(struct ref_to_prune *r)
{
@@ -109,6 +161,7 @@ static void prune_refs(struct ref_to_prune *r)
prune_ref(r);
r = r->next;
}
+ prune_empty_dirs("refs");
}
static struct lock_file packed;
--
1.7.8.36.g69ee2
^ permalink raw reply related
* Re: [PATCHv2 1/4] refs: add common refname_match_patterns()
From: Michael Haggerty @ 2012-02-11 7:12 UTC (permalink / raw)
To: Tom Grennan; +Cc: pclouds, git, gitster, krh, jasampler
In-Reply-To: <1328926618-17167-2-git-send-email-tmgrennan@gmail.com>
On 02/11/2012 03:16 AM, Tom Grennan wrote:
> diff --git a/refs.h b/refs.h
> index 00ba1e2..13015ba 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -152,4 +152,12 @@ int update_ref(const char *action, const char *refname,
> const unsigned char *sha1, const unsigned char *oldval,
> int flags, enum action_on_err onerr);
>
> +/**
> + * Returns:
> + * 1 with NULL patterns
> + * 0 if refname fnmatch()es any ! prefaced pattern
> + * 1 if refname fnmatch()es any pattern
> + */
> +extern int refname_match_patterns(const char **patterns, const char *refname);
> +
> #endif /* REFS_H */
This comment is unclear and incomplete.
1. What does "NULL patterns" mean? Your code fails if patterns==NULL,
so I guess you mean "1 if there are no patterns in the list".
2. Since the three conditions are not mutually exclusive, you should say
how they are connected. I believe that you want something like "A
otherwise B otherwise C".
3. You haven't specified what happens if refname matches neither a
!-prefixed pattern nor a non-!-prefixed pattern. Does this behavior
depend on which types of patterns were present in the list?
I see that you have described the behavior more completely in the commit
message for patch 2/4, but the commit message is not enough: this
behavior should be described precisely in both code comments (when the
function is defined) and in the user documentation (when the
functionality is added to a command).
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: [PATCH v2 28/51] refs.c: rename ref_array -> ref_dir
From: Michael Haggerty @ 2012-02-11 6:33 UTC (permalink / raw)
To: Junio C Hamano
Cc: Jeff King, git, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips
In-Reply-To: <7v62fepew8.fsf@alter.siamese.dyndns.org>
On 02/10/2012 10:17 PM, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
>>> If everything_local() is trying to check that the references are in the
>>> local repository plus alternates, then it is incorrect that
>>> everything_local() doesn't consider alternate references in its
>>> determination. My guess is that this is the case, and that something
>>> like the following might be the fix:
>>
>> Junio could answer more authoritatively than I, but I am pretty sure it
>> is the latter. The point is to skip the expensive find_common
>> negotiation if we know that there are no objects to fetch. Thus the
>> "local" here is "do we have them on this side of the git-protocol
>> connection", not "do we have them in our non-alternates repository".
>
> Correct. The function is about "do we need to get any object from the
> other side?" optimization.
Thanks for your feedback. I have just submitted a patch series [1] that
attempts to fix this problem.
Michael
[1] http://thread.gmane.org/gmane.comp.version-control.git/190488
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* [PATCH 4/7] fetch-pack.c: inline insert_alternate_refs()
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
The logic of the (single) caller is clearer without encapsulating this
one line in a function.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
builtin/fetch-pack.c | 7 +------
1 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 9bd2096..dbe9acb 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -256,11 +256,6 @@ static void insert_one_alternate_ref(const struct ref *ref, void *unused)
rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL);
}
-static void insert_alternate_refs(void)
-{
- for_each_alternate_ref(insert_one_alternate_ref, NULL);
-}
-
#define INITIAL_FLUSH 16
#define PIPESAFE_FLUSH 32
#define LARGE_FLUSH 1024
@@ -295,7 +290,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
marked = 1;
for_each_ref(rev_list_insert_ref, NULL);
- insert_alternate_refs();
+ for_each_alternate_ref(insert_one_alternate_ref, NULL);
fetching = 0;
for ( ; refs ; refs = refs->next) {
--
1.7.9
^ permalink raw reply related
* [PATCH 7/7] refs: remove the extra_refs API
From: mhagger @ 2012-02-11 6:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
The extra_refs provided a kludgy way to create fake references at a
global level in the hope that they would only affect some particular
code path. The last user of this API been rewritten, so strip this
stuff out before somebody else gets the bad idea of using it.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 23 +----------------------
refs.h | 8 --------
2 files changed, 1 insertions(+), 30 deletions(-)
diff --git a/refs.c b/refs.c
index b8843bb..c9f6835 100644
--- a/refs.c
+++ b/refs.c
@@ -183,12 +183,6 @@ static struct ref_cache {
static struct ref_entry *current_ref;
-/*
- * Never call sort_ref_array() on the extra_refs, because it is
- * allowed to contain entries with duplicate names.
- */
-static struct ref_array extra_refs;
-
static void clear_ref_array(struct ref_array *array)
{
int i;
@@ -289,16 +283,6 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
}
}
-void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
-{
- add_ref(&extra_refs, create_ref_entry(refname, sha1, flag, 0));
-}
-
-void clear_extra_refs(void)
-{
- clear_ref_array(&extra_refs);
-}
-
static struct ref_array *get_packed_refs(struct ref_cache *refs)
{
if (!refs->did_packed) {
@@ -733,16 +717,11 @@ fallback:
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
int trim, int flags, void *cb_data)
{
- int retval = 0, i, p = 0, l = 0;
+ int retval = 0, p = 0, l = 0;
struct ref_cache *refs = get_ref_cache(submodule);
struct ref_array *packed = get_packed_refs(refs);
struct ref_array *loose = get_loose_refs(refs);
- struct ref_array *extra = &extra_refs;
-
- for (i = 0; i < extra->nr; i++)
- retval = do_one_ref(base, fn, trim, flags, cb_data, extra->refs[i]);
-
sort_ref_array(packed);
sort_ref_array(loose);
while (p < packed->nr && l < loose->nr) {
diff --git a/refs.h b/refs.h
index 00ba1e2..33202b0 100644
--- a/refs.h
+++ b/refs.h
@@ -56,14 +56,6 @@ extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refn
*/
extern void add_packed_ref(const char *refname, const unsigned char *sha1);
-/*
- * Extra refs will be listed by for_each_ref() before any actual refs
- * for the duration of this process or until clear_extra_refs() is
- * called. Only extra refs added before for_each_ref() is called will
- * be listed on a given call of for_each_ref().
- */
-extern void add_extra_ref(const char *refname, const unsigned char *sha1, int flags);
-extern void clear_extra_refs(void);
extern int ref_exists(const char *);
extern int peel_ref(const char *refname, unsigned char *sha1);
--
1.7.9
^ permalink raw reply related
* [PATCH 5/7] everything_local(): mark alternate refs as complete
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Objects in an alternate object database are already available to the
local repository and therefore don't need to be fetched. So mark them
as complete in everything_local().
This fixes a test in t5700.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
builtin/fetch-pack.c | 6 ++++++
t/t5700-clone-reference.sh | 2 +-
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index dbe9acb..0e8560f 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -581,6 +581,11 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
*refs = newlist;
}
+static void mark_alternate_complete(const struct ref *ref, void *unused)
+{
+ mark_complete(NULL, ref->old_sha1, 0, NULL);
+}
+
static int everything_local(struct ref **refs, int nr_match, char **match)
{
struct ref *ref;
@@ -609,6 +614,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
if (!args.depth) {
for_each_ref(mark_complete, NULL);
+ for_each_alternate_ref(mark_alternate_complete, NULL);
if (cutoff)
mark_recent_complete_commits(cutoff);
}
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 2dafee8..783f988 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -167,7 +167,7 @@ test_expect_success 'prepare branched repository' '
rm -f "$U.K"
-test_expect_failure 'fetch with incomplete alternates' '
+test_expect_success 'fetch with incomplete alternates' '
git init K &&
echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
(
--
1.7.9
^ permalink raw reply related
* [PATCH 6/7] clone: do not add alternate references to extra_refs
From: mhagger @ 2012-02-11 6:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Alternate references are directly (and now, correctly) handled by
fetch-pack, so there is no need to inform fetch-pack about them via
the extra_refs back channel.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
builtin/clone.c | 12 ------------
1 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 279fdf0..b15fccb 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -232,9 +232,6 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
{
char *ref_git;
struct strbuf alternate = STRBUF_INIT;
- struct remote *remote;
- struct transport *transport;
- const struct ref *extra;
/* Beware: real_path() and mkpath() return static buffer */
ref_git = xstrdup(real_path(item->string));
@@ -249,14 +246,6 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
strbuf_addf(&alternate, "%s/objects", ref_git);
add_to_alternates_file(alternate.buf);
strbuf_release(&alternate);
-
- remote = remote_get(ref_git);
- transport = transport_get(remote, ref_git);
- for (extra = transport_get_remote_refs(transport); extra;
- extra = extra->next)
- add_extra_ref(extra->name, extra->old_sha1, 0);
-
- transport_disconnect(transport);
free(ref_git);
return 0;
}
@@ -500,7 +489,6 @@ static void update_remote_refs(const struct ref *refs,
const char *msg)
{
if (refs) {
- clear_extra_refs();
write_remote_refs(mapped_refs);
if (option_single_branch)
write_followtags(refs, msg);
--
1.7.9
^ permalink raw reply related
* [PATCH 0/7] Make alternates affect fetch behavior
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
From: Michael Haggerty <mhagger@alum.mit.edu>
It used to be that alternate references were not considered "complete"
when fetching via fetch-pack. This failure was not so obvious because
the big benefit of alternates is seen when cloning, and clone used a
different data path: it put the alternate references into extra refs
(which makes them look like references within the local repository).
This patch series teaches fetch-pack to treat objects that are
available via alternates as "complete".
Once that is fixed, clone doesn't need to use the special extra_refs
kludge, so change that.
And once that is changed, the extra_refs API is no longer needed at
all, so remove it.
Michael Haggerty (7):
t5700: document a failure of alternates to affect fetch
clone.c: move more code into the "if (refs)" conditional
fetch-pack.c: rename some parameters from "path" to "refname"
fetch-pack.c: inline insert_alternate_refs()
everything_local(): mark alternate refs as complete
clone: do not add alternate references to extra_refs
refs: remove the extra_refs API
builtin/clone.c | 51 +++++++++++++++++--------------------------
builtin/fetch-pack.c | 23 ++++++++++---------
refs.c | 23 +-------------------
refs.h | 8 -------
t/t5700-clone-reference.sh | 34 ++++++++++++++++++++++++++--
5 files changed, 64 insertions(+), 75 deletions(-)
--
1.7.9
^ permalink raw reply
* [PATCH 3/7] fetch-pack.c: rename some parameters from "path" to "refname"
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
The parameters denote reference names, which are no longer 1:1 with
filesystem paths.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
builtin/fetch-pack.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 6207ecd..9bd2096 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -58,9 +58,9 @@ static void rev_list_push(struct commit *commit, int mark)
}
}
-static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int rev_list_insert_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
- struct object *o = deref_tag(parse_object(sha1), path, 0);
+ struct object *o = deref_tag(parse_object(sha1), refname, 0);
if (o && o->type == OBJ_COMMIT)
rev_list_push((struct commit *)o, SEEN);
@@ -68,9 +68,9 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int
return 0;
}
-static int clear_marks(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int clear_marks(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
- struct object *o = deref_tag(parse_object(sha1), path, 0);
+ struct object *o = deref_tag(parse_object(sha1), refname, 0);
if (o && o->type == OBJ_COMMIT)
clear_commit_marks((struct commit *)o,
@@ -493,7 +493,7 @@ done:
static struct commit_list *complete;
-static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+static int mark_complete(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
struct object *o = parse_object(sha1);
--
1.7.9
^ permalink raw reply related
* [PATCH 2/7] clone.c: move more code into the "if (refs)" conditional
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
The bahavior of a bunch of code before the "if (refs)" statement also
depends on whether refs is set, so make the logic clearer by shifting
this code into the if statement.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
builtin/clone.c | 39 ++++++++++++++++++++-------------------
1 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index c62d4b5..279fdf0 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -813,28 +813,28 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
}
refs = transport_get_remote_refs(transport);
- mapped_refs = refs ? wanted_peer_refs(refs, refspec) : NULL;
- /*
- * transport_get_remote_refs() may return refs with null sha-1
- * in mapped_refs (see struct transport->get_refs_list
- * comment). In that case we need fetch it early because
- * remote_head code below relies on it.
- *
- * for normal clones, transport_get_remote_refs() should
- * return reliable ref set, we can delay cloning until after
- * remote HEAD check.
- */
- for (ref = refs; ref; ref = ref->next)
- if (is_null_sha1(ref->old_sha1)) {
- complete_refs_before_fetch = 0;
- break;
- }
+ if (refs) {
+ mapped_refs = wanted_peer_refs(refs, refspec);
+ /*
+ * transport_get_remote_refs() may return refs with null sha-1
+ * in mapped_refs (see struct transport->get_refs_list
+ * comment). In that case we need fetch it early because
+ * remote_head code below relies on it.
+ *
+ * for normal clones, transport_get_remote_refs() should
+ * return reliable ref set, we can delay cloning until after
+ * remote HEAD check.
+ */
+ for (ref = refs; ref; ref = ref->next)
+ if (is_null_sha1(ref->old_sha1)) {
+ complete_refs_before_fetch = 0;
+ break;
+ }
- if (!is_local && !complete_refs_before_fetch && refs)
- transport_fetch_refs(transport, mapped_refs);
+ if (!is_local && !complete_refs_before_fetch)
+ transport_fetch_refs(transport, mapped_refs);
- if (refs) {
remote_head = find_ref_by_name(refs, "HEAD");
remote_head_points_at =
guess_remote_head(remote_head, mapped_refs, 0);
@@ -852,6 +852,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
}
else {
warning(_("You appear to have cloned an empty repository."));
+ mapped_refs = NULL;
our_head_points_at = NULL;
remote_head_points_at = NULL;
remote_head = NULL;
--
1.7.9
^ permalink raw reply related
* [PATCH 1/7] t5700: document a failure of alternates to affect fetch
From: mhagger @ 2012-02-11 6:20 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Jakub Narebski, Heiko Voigt, Johan Herland,
Michael Haggerty
In-Reply-To: <1328941261-29746-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
If an alternate supplies some, but not all, of the objects needed for
a fetch, fetch-pack nevertheless generates "want" lines for the
alternate objects that are present. Demonstrate this problem via a
failing test.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
t/t5700-clone-reference.sh | 34 +++++++++++++++++++++++++++++++---
1 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index c4c375a..2dafee8 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -52,13 +52,13 @@ test_cmp expected current'
cd "$base_dir"
-rm -f "$U"
+rm -f "$U.D"
test_expect_success 'cloning with reference (no -l -s)' \
-'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U"'
+'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U.D"'
test_expect_success 'fetched no objects' \
-'! grep "^want" "$U"'
+'! grep "^want" "$U.D"'
cd "$base_dir"
@@ -153,4 +153,32 @@ test_expect_success 'clone with reference from a tagged repository' '
git clone --reference=A A I
'
+test_expect_success 'prepare branched repository' '
+ git clone A J &&
+ (
+ cd J &&
+ git checkout -b other master^ &&
+ echo other > otherfile &&
+ git add otherfile &&
+ git commit -m other &&
+ git checkout master
+ )
+'
+
+rm -f "$U.K"
+
+test_expect_failure 'fetch with incomplete alternates' '
+ git init K &&
+ echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
+ (
+ cd K &&
+ git remote add J "file://$base_dir/J" &&
+ GIT_DEBUG_SEND_PACK=3 git fetch J 3>"$U.K"
+ ) &&
+ master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
+ ! grep "^want $master_object" "$U.K" &&
+ tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) &&
+ ! grep "^want $tag_object" "$U.K"
+'
+
test_done
--
1.7.9
^ permalink raw reply related
* Re: User authentication in GIT
From: Sitaram Chamarty @ 2012-02-11 5:17 UTC (permalink / raw)
To: supadhyay; +Cc: git
In-Reply-To: <1328893056653-7273350.post@n2.nabble.com>
On Fri, Feb 10, 2012 at 10:27 PM, supadhyay <supadhyay@imany.com> wrote:
> Now my confusion is my existing source code repository directory path during
> migration /home/GITAdmin/migration/<repository.git> and now through gitolite
> I want to manage both users and repositories but through gitolite it add
> repository in different path /home/GITAdmin/repositories/<repository.git>.
>
>
> Can you please help how through gitolite I can add new repository on to the
> same my exisitng migrated repository directory?
gitolite keeps all its repos in whatever directory is pointed to by
$REPO_BASE in the rc file. This is $HOME/repositories by default but
you can change it to whatever you want. Instructions for changing it
are in the 4th bullet of
http://sitaramc.github.com/gitolite/rc.html#gitolite_rc_rarely_changed_variables_
If you are moving existing repos into gitolite, be sure to read
http://sitaramc.github.com/gitolite/moverepos.html -- if you do it
wrong you may end up without the crucial "update" hook and then all
access control will fail.
^ permalink raw reply
* Re: Git SSH Authentication
From: Sitaram Chamarty @ 2012-02-11 5:05 UTC (permalink / raw)
To: isawk; +Cc: git
In-Reply-To: <loom.20120211T045801-602@post.gmane.org>
On Sat, Feb 11, 2012 at 9:31 AM, isawk <kwasi.gyasiagyei@4things.co.za> wrote:
> I'm unable to authenticate with git through ssh public key/password-less
> authentication.
>
> # git push origin master
> # Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
> # fatal: The remote end hung up unexpectedly
if it didn't ask you for a password when pubkey access failed, that's
non-default. Someone explicitly told sshd to do that.
Common causes of pubkey access fail:
- wrong pubkey being used: run your ssh with '-vv' and look for
"offered". make sure the pubkey that is being offered has been added
to the server side ~/.ssh/authorized_keys
- wrong pubkey being offered: if you are using ssh-agent, make sure
you have 'ssh-add'ed the key you want to offer. Confirm with 'ssh-add
-l'
- wrong permissions on server side: sshd is very picky about
permissions. Any directory component of $HOME/.ssh having g+w or o+w
will make it refuse. Or wrong ownership (for example if you created a
file using root).
- AllowUsers setting on server side /etc/ssh/ssd_config: this item
is not set by default, which allows everyone to log in. But if
someone set it in for some reason, then the git user must also be
added to it.
In general, looking in server side /var/log/auth.log or
/var/log/secure or some such file will give you more information.
^ permalink raw reply
* Re: [PATCH 2/3] help.c: make term_columns() cached and export it
From: Nguyen Thai Ngoc Duy @ 2012-02-11 4:36 UTC (permalink / raw)
To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber
In-Reply-To: <1328891972-23695-3-git-send-email-zbyszek@in.waw.pl>
2012/2/10 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
> Since term_columns() will usually fail, when a pager is installed,
> the cache is primed before the pager is installed. If a pager is not
> installed, then the cache will be set on first use.
Conflict alert. term_columns() is also moved out of help.c in
nd/columns series on pu, commit cb0850f (Save terminal width before
setting up pager - 2012-02-04)
>
> Conforms to The Single UNIX Specification, Version 2
> (http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).
>
> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
> help.c | 37 +++++++++++++++++++++++++++++--------
> help.h | 2 ++
> pager.c | 5 +++++
> 3 files changed, 36 insertions(+), 8 deletions(-)
>
> diff --git a/help.c b/help.c
> index bc15066..5d1cb1d 100644
> --- a/help.c
> +++ b/help.c
> @@ -5,26 +5,47 @@
> #include "help.h"
> #include "common-cmds.h"
>
> -/* most GUI terminals set COLUMNS (although some don't export it) */
> -static int term_columns(void)
> +/*
> + * Cache for term_columns() value. Set on first use or when
> + * installing a pager and replacing stdout.
> + */
> +static int term_columns_cache;
> +
> +/*
> + * Return cached value (if set) or $COLUMNS (if set and positive) or
> + * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
> + *
> + * $COLUMNS even if set, is usually not exported, so
> + * the variable can be used to override autodection.
> + */
> +int term_columns(void)
> {
> - char *col_string = getenv("COLUMNS");
> + char *col_string;
> int n_cols;
>
> - if (col_string && (n_cols = atoi(col_string)) > 0)
> - return n_cols;
> + if (term_columns_cache)
> + return term_columns_cache;
> +
> + col_string = getenv("COLUMNS");
> + if (col_string && (n_cols = atoi(col_string)) > 0) {
> + term_columns_cache = n_cols;
> + return term_columns_cache;
> + }
>
> #ifdef TIOCGWINSZ
> {
> struct winsize ws;
> if (!ioctl(1, TIOCGWINSZ, &ws)) {
> - if (ws.ws_col)
> - return ws.ws_col;
> + if (ws.ws_col) {
> + term_columns_cache = ws.ws_col;
> + return term_columns_cache;
> + }
> }
> }
> #endif
>
> - return 80;
> + term_columns_cache = 80;
> + return term_columns_cache;
> }
>
> void add_cmdname(struct cmdnames *cmds, const char *name, int len)
> diff --git a/help.h b/help.h
> index b6b12d5..880a4b4 100644
> --- a/help.h
> +++ b/help.h
> @@ -29,4 +29,6 @@ extern void list_commands(const char *title,
> struct cmdnames *main_cmds,
> struct cmdnames *other_cmds);
>
> +extern int term_columns(void);
> +
> #endif /* HELP_H */
> diff --git a/pager.c b/pager.c
> index 975955b..e7032de 100644
> --- a/pager.c
> +++ b/pager.c
> @@ -1,6 +1,7 @@
> #include "cache.h"
> #include "run-command.h"
> #include "sigchain.h"
> +#include "help.h"
>
> #ifndef DEFAULT_PAGER
> #define DEFAULT_PAGER "less"
> @@ -76,6 +77,10 @@ void setup_pager(void)
> if (!pager)
> return;
>
> + /* prime the term_columns() cache before it is too
> + * late and stdout is replaced */
> + (void) term_columns();
> +
> setenv("GIT_PAGER_IN_USE", "true", 1);
>
> /* spawn the pager */
> --
> 1.7.9.263.g4be11.dirty
>
--
Duy
^ permalink raw reply
* Git SSH Authentication
From: isawk @ 2012-02-11 4:01 UTC (permalink / raw)
To: git
I'm unable to authenticate with git through ssh public key/password-less
authentication.
# git push origin master
# Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
# fatal: The remote end hung up unexpectedly
git version
git version 1.7.8.4
git user
has .ssh/authorized_keys containing public key, but still nothing. I'm confused
on how to go about fixing this issue.
^ permalink raw reply
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Junio C Hamano @ 2012-02-11 3:06 UTC (permalink / raw)
To: Tom Grennan; +Cc: pclouds, git, krh, jasampler
In-Reply-To: <1328926618-17167-1-git-send-email-tmgrennan@gmail.com>
Tom Grennan <tmgrennan@gmail.com> writes:
>>If we pursue this, it may be best to first add match_patterns() to ./refs.[ch]
>>then incrementally modify these builtin commands to use it.
>
> The following series implements !<pattern> with: git-tag, git-branch, and
> git-for-each-ref.
>
> This still requires Documentation and unit test updates but I think these are
> close to functionally complete.
>
>>>About the '!' for exclusion, maybe it's better to move from fnmatch()
>>>as matching machinery to pathspec. Then when git learns negative
>>>pathspec [1], we have this feature for free.
>>>
>>>[1] http://thread.gmane.org/gmane.comp.version-control.git/189645/focus=190072
>
> After looking at this some more, I don't understand the value of replacing
> libc:fnmatch(). Or are you just referring to '--exclude' instead of
> [!]<pattern> argument parsing?
I have not formed a firm opinion on Nguyen's idea to reuse pathspec
matching infrastructure for this purpose, so I wouldn't comment on that
part. It certainly looks attractive, as it allows users to learn one and
only one extended matching syntax, but at the same time, it has a risk to
mislead people to think that the namespace for refs is similar to that of
the filesystem paths, which I see as a mild downside.
In any case, I do not like the structure of this series. If it followed
our usual pattern, it would consist of patches in this order:
- Patch 1 would extract match_pattern() from builtin/tag.c and introduce
the new helper function refname_match_patterns() to refs.c. It updates
the call sites of match_pattern() in builtin/tag.c, match_patterns() in
builtin/branch.c, and the implementation of grab_single_ref() in
builtin/for-each-ref.c with a call to the new helper function.
This step can and probably should be done as three sub-steps. 1a would
move builtin/tag.c::match_pattern() to refs.::refname_match_patterns(),
1b would use the new helper in builtin/branch.c and 1c would do the
same for builtin/for-each-ref.c.
It is important that this patch does so without introducing any new
functionality to the new function over the old one. When done this way,
there is no risk of introducing new bugs at 1a because it is purely a
code movement and renaming; 1b could introduce a bug that changes
semantics for bulitin/branch.c if its match_patterns() does things
differently from match_pattern() lifted from builtin/tag.c, and if it
is found out to be buggy, we can discard 1b without discarding 1a. Same
for 1c, which I highly suspect will introduce regression without
looking at the code (for-each-ref is prefix-match only), that can
safely be discarded.
This is to make it easier to ensure that the update does not introduce
new bugs.
- Patch 2 would then add the new functionality to the new helper. It
would also adjust the documentation of the three end user facing
commands to describe the fallout coming from this change, and adds new
tests to make sure future changes will not break this new
functionality.
That is, first refactor and clean-up without adding anything new, and then
build new stuff on solidified ground.
Do we allow a refname whose pathname component begins with '!', by the
way? If we do, how does a user look for a tag whose name is "!xyzzy"?
"Naming your tag !xyzzy used to be allowed but it is now forbidden after
this patch" is not an acceptable answer---it is called a regression. If
the negation operator were "^" or something that we explicitly forbid from
a refname, we wouldn't have such a problem.
^ permalink raw reply
* [PATCHv2 1/4] refs: add common refname_match_patterns()
From: Tom Grennan @ 2012-02-11 2:16 UTC (permalink / raw)
To: pclouds; +Cc: git, gitster, krh, jasampler
In-Reply-To: <20120210185516.GA4903@tgrennan-laptop>
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
refs.c | 14 ++++++++++++++
refs.h | 8 ++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/refs.c b/refs.c
index b8843bb..b42eb4a 100644
--- a/refs.c
+++ b/refs.c
@@ -1057,6 +1057,20 @@ int refname_match(const char *abbrev_name, const char *full_name, const char **r
return 0;
}
+int refname_match_patterns(const char **patterns, const char *refname)
+{
+ int given_match_pattern = 0, had_match = 0;
+
+ for (; *patterns; patterns++)
+ if (**patterns != '!') {
+ given_match_pattern = 1;
+ if (!fnmatch(*patterns, refname, 0))
+ had_match = 1;
+ } else if (!fnmatch(*patterns+1, refname, 0))
+ return 0;
+ return given_match_pattern ? had_match : 1;
+}
+
static struct ref_lock *verify_lock(struct ref_lock *lock,
const unsigned char *old_sha1, int mustexist)
{
diff --git a/refs.h b/refs.h
index 00ba1e2..13015ba 100644
--- a/refs.h
+++ b/refs.h
@@ -152,4 +152,12 @@ int update_ref(const char *action, const char *refname,
const unsigned char *sha1, const unsigned char *oldval,
int flags, enum action_on_err onerr);
+/**
+ * Returns:
+ * 1 with NULL patterns
+ * 0 if refname fnmatch()es any ! prefaced pattern
+ * 1 if refname fnmatch()es any pattern
+ */
+extern int refname_match_patterns(const char **patterns, const char *refname);
+
#endif /* REFS_H */
--
1.7.8
^ permalink raw reply related
* [PATCHv2 2/4] tag: use refs.c:refname_match_patterns()
From: Tom Grennan @ 2012-02-11 2:16 UTC (permalink / raw)
To: pclouds; +Cc: git, gitster, krh, jasampler
In-Reply-To: <20120210185516.GA4903@tgrennan-laptop>
This will exclude tags matching patterns prefaced with the '!'
character. This has precedence over other matching patterns.
For example,
$ git tag -l \!*-rc? v1.7.8*
v1.7.8
v1.7.8.1
v1.7.8.2
v1.7.8.3
v1.7.8.4
$ git tag -l v1.7.8* \!*-rc?
v1.7.8
v1.7.8.1
v1.7.8.2
v1.7.8.3
v1.7.8.4
This is equivalent to,
$ git tag -l v1.7.8* | grep -v '\-rc.'
Without a matching pattern, filter all tags with the "!" patterns,
$ ./git-tag -l \!*-rc?
gitgui-0.10.0
gitgui-0.10.1
gitgui-0.10.2
...
v1.7.8.3
v1.7.8.4
v1.7.9
That is equivalent to,
$ git tag -l | grep -v '\-rc.'
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
Documentation/git-tag.txt | 10 ++++++----
builtin/tag.c | 15 ++-------------
2 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 53ff5f6..56ea2fa 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
+'git tag' [-n[<num>]] -l [--contains <commit>] [[!]<pattern>...]
'git tag' -v <tagname>...
DESCRIPTION
@@ -75,13 +75,15 @@ OPTIONS
If no number is given to `-n`, only the first line is printed.
If the tag is not annotated, the commit message is displayed instead.
--l <pattern>::
---list <pattern>::
+-l [!]<pattern>::
+--list [!]<pattern>::
List tags with names that match the given pattern (or all if no
pattern is given). Running "git tag" without arguments also
lists all tags. The pattern is a shell wildcard (i.e., matched
using fnmatch(3)). Multiple patterns may be given; if any of
- them matches, the tag is shown.
+ them matches, the tag is shown. If the pattern is prefaced with
+ the '!' character, all tags matching the pattern are filtered
+ from the list.
--contains <commit>::
Only list tags which contain the specified commit.
diff --git a/builtin/tag.c b/builtin/tag.c
index 31f02e8..7f99424 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -19,7 +19,7 @@
static const char * const git_tag_usage[] = {
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
"git tag -d <tagname>...",
- "git tag -l [-n[<num>]] [<pattern>...]",
+ "git tag -l [-n[<num>]] [[!]<pattern>...]",
"git tag -v <tagname>...",
NULL
};
@@ -30,17 +30,6 @@ struct tag_filter {
struct commit_list *with_commit;
};
-static int match_pattern(const char **patterns, const char *ref)
-{
- /* no pattern means match everything */
- if (!*patterns)
- return 1;
- for (; *patterns; patterns++)
- if (!fnmatch(*patterns, ref, 0))
- return 1;
- return 0;
-}
-
static int in_commit_list(const struct commit_list *want, struct commit *c)
{
for (; want; want = want->next)
@@ -88,7 +77,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
{
struct tag_filter *filter = cb_data;
- if (match_pattern(filter->patterns, refname)) {
+ if (refname_match_patterns(filter->patterns, refname)) {
int i;
unsigned long size;
enum object_type type;
--
1.7.8
^ permalink raw reply related
* [PATCHv2 4/4] for-each-ref: use refs.c:refname_match_patterns()
From: Tom Grennan @ 2012-02-11 2:16 UTC (permalink / raw)
To: pclouds; +Cc: git, gitster, krh, jasampler
In-Reply-To: <20120210185516.GA4903@tgrennan-laptop>
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
builtin/for-each-ref.c | 23 +++--------------------
1 files changed, 3 insertions(+), 20 deletions(-)
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index b01d76a..2c9cc47 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -781,25 +781,8 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
struct refinfo *ref;
int cnt;
- if (*cb->grab_pattern) {
- const char **pattern;
- int namelen = strlen(refname);
- for (pattern = cb->grab_pattern; *pattern; pattern++) {
- const char *p = *pattern;
- int plen = strlen(p);
-
- if ((plen <= namelen) &&
- !strncmp(refname, p, plen) &&
- (refname[plen] == '\0' ||
- refname[plen] == '/' ||
- p[plen-1] == '/'))
- break;
- if (!fnmatch(p, refname, FNM_PATHNAME))
- break;
- }
- if (!*pattern)
- return 0;
- }
+ if (!refname_match_patterns(cb->grab_pattern, refname))
+ return 0;
/*
* We do not open the object yet; sort may only need refname
@@ -974,7 +957,7 @@ static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
}
static char const * const for_each_ref_usage[] = {
- "git for-each-ref [options] [<pattern>]",
+ "git for-each-ref [options] [[!]<pattern>...]",
NULL
};
--
1.7.8
^ permalink raw reply related
* [PATCHv2 3/4] branch: use refs.c:refname_match_patterns()
From: Tom Grennan @ 2012-02-11 2:16 UTC (permalink / raw)
To: pclouds; +Cc: git, gitster, krh, jasampler
In-Reply-To: <20120210185516.GA4903@tgrennan-laptop>
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
builtin/branch.c | 16 ++--------------
1 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 7095718..7dfc693 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -266,18 +266,6 @@ struct append_ref_cb {
int ret;
};
-static int match_patterns(const char **pattern, const char *refname)
-{
- if (!*pattern)
- return 1; /* no pattern always matches */
- while (*pattern) {
- if (!fnmatch(*pattern, refname, 0))
- return 1;
- pattern++;
- }
- return 0;
-}
-
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -312,7 +300,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
if ((kind & ref_list->kinds) == 0)
return 0;
- if (!match_patterns(cb->pattern, refname))
+ if (!refname_match_patterns(cb->pattern, refname))
return 0;
commit = NULL;
@@ -542,7 +530,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
detached = (detached && (kinds & REF_LOCAL_BRANCH));
- if (detached && match_patterns(pattern, "HEAD"))
+ if (detached && refname_match_patterns(pattern, "HEAD"))
show_detached(&ref_list);
for (i = 0; i < ref_list.index; i++) {
--
1.7.8
^ permalink raw reply related
* Re: [RFC/PATCH] tag: make list exclude !<pattern>
From: Tom Grennan @ 2012-02-11 2:16 UTC (permalink / raw)
To: pclouds; +Cc: git, gitster, krh, jasampler
In-Reply-To: <20120210185516.GA4903@tgrennan-laptop>
On Fri, 10 Feb 2012 10:55:16 -0800, Tom Grennan wrote:
>On Fri, Feb 10, 2012 at 01:34:26PM +0700, Nguyen Thai Ngoc Duy wrote:
>>On Fri, Feb 10, 2012 at 2:43 AM, Tom Grennan <tmgrennan@gmail.com> wrote:
>>> Please see the following patch which filters the tag list of "!" prefaced
>>> patterns. If this is deemed desirable and correct, I'll resubmit with updated
>>> documentation and unit tests.
>>
>>git-branch, git-tag and git-for-each-ref are in the same family. I
>>think it's good to that all three commands share things, like this
>>pattern matching.
>
>Yes, git-branch and git-tag could now use a common match_patterns() but
>git-for-each-ref needs some rearranging; as will: git-describe,
>git-replace, git-ls-remote, git-name-rev, and git-show-branch.
>
>If we pursue this, it may be best to first add match_patterns() to ./refs.[ch]
>then incrementally modify these builtin commands to use it.
The following series implements !<pattern> with: git-tag, git-branch, and
git-for-each-ref.
This still requires Documentation and unit test updates but I think these are
close to functionally complete.
>>About the '!' for exclusion, maybe it's better to move from fnmatch()
>>as matching machinery to pathspec. Then when git learns negative
>>pathspec [1], we have this feature for free.
>>
>>[1] http://thread.gmane.org/gmane.comp.version-control.git/189645/focus=190072
After looking at this some more, I don't understand the value of replacing
libc:fnmatch(). Or are you just referring to '--exclude' instead of
[!]<pattern> argument parsing?
---
Tom Grennan (4):
refs: add common refname_match_patterns()
tag: use refs.c:refname_match_patterns()
branch: use refs.c:refname_match_patterns()
for-each-ref: use refs.c:refname_match_patterns()
Documentation/git-tag.txt | 10 ++++++----
builtin/branch.c | 16 ++--------------
builtin/for-each-ref.c | 23 +++--------------------
builtin/tag.c | 15 ++-------------
refs.c | 14 ++++++++++++++
refs.h | 8 ++++++++
6 files changed, 35 insertions(+), 51 deletions(-)
--
1.7.8
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox