* Re: Retroactively change email signature?
From: Stephen Sinclair @ 2008-01-02 22:06 UTC (permalink / raw)
To: git
In-Reply-To: <alpine.LFD.1.00.0801021316080.3010@woody.linux-foundation.org>
Thanks, I was able to use git-filter-branch to accomplish what I wanted.
I should have mentioned in the original email that it is not a widely
distributed repo, so I'm not too worried about breaking things at this
point. I guess for a larger project it might be a problem, so I
probably just wouldn't do it.
> BUT! See also the big bold-face warning: using "filter-branch" will not
> change old commits, it will create a series of *new* commits that bear a
> striking resemblance to the old ones, but are not the same. So you'll have
> a totally new history.
Got it, thanks.
I'll just have to remember to git-config properly next time I do this.
One thing that's a bit odd for me is that I use a different email
address for this particular project..
Conveniently I'm able to use git-config to set an email address
locally for this repo, however I have to remember to do this every
time I clone it somewhere. Not a problem, necessarily, but perhaps
just a matter of training myself.
For example, I have a clone of this repo on a Linux, Windows, and OS X
machine, and also another clone for each on my laptop.. git is
actually turning out to be great for doing all this swapping between
machines, but it does take a little training to remember to set the
configuration, since there's no central repo to ask me for my username
and password before I can commit.
cheers,
Steve
^ permalink raw reply
* Re: How to structure a project distributed with varyingly interdependent feature branches?
From: Junio C Hamano @ 2008-01-02 22:12 UTC (permalink / raw)
To: Matt McCutchen; +Cc: git
In-Reply-To: <1199139613.2360.83.camel@localhost>
Matt McCutchen <matt@mattmccutchen.net> writes:
> Rsync presents a unique challenge because it has a number of long-term
> feature patches that are maintained and distributed with the main source
> code. Furthermore, some of the patches depend on other patches.
> ...
> 1. How to properly represent the history of an individual branch and
> update it when the trunk (or the branch on which it depends) changes.
> Right now, Wayne updates the branch by rebasing; unfortunately, if the
> trunk changes in such a way that one of the intermediate commits no
> longer makes sense, it is impossible to update the branch while
> preserving a record that the intermediate commit once existed.
I take this to mean a situation like this:
* There is a series of patch X Y Z that implements some nicety
not present in the mainline yet. This set applies to older
codebase at point A.
* Newer codebase B does things differently from codebase A and
patch X is no longer needed --- IOW, what X achieves on top
of A has already been incorporated somewhere between A and B.
Applying Y and Z suffices to obtain that nice feature on top
of B.
.---X---Y---Z .---Y'--Z'
/ /
---o---A---o---.....---o---B
This is natively expressed with git, if your history were like
this:
.----------X------Y-------Z
/ \
---o---A---o---....---M---....---B
and you publish Z. People who would want to apply the series to
their codebase simply merge Z. The patch dependency of X is
captured in the mainline history because the effect of X is
incorporated to the mainline as a merge at M. If the point they
want to apply the series is older than point M (where patch X
becomes unnecessary because of the mainline change), X, Y and Z
will be brought in, while people basing on commits newer than M
will pull in only Y and Z (because they already have X).
But that works only in theory and with a developer with perfect
vision. Nobody would be able to forsee that X would become such
a crucial change when it is developed. Often you would just
create a regular commit M somewhere between A and B that has the
effect of X, and later regret that you had made a separate X
forked from an earlier A and recorded M as a merge.
People use quilt (or guilt) to manage patch stacks for things
like this.
Having said that, I think you can maintain a single patch series
(say the above X-Y-Z) and publish it as a few variants for
downloaders as a prefabricated set of branches.
Say if you have this (the first picture), you do not create Y'-Z'
history (again, M is the point patch X becomes unnecessary, but
we live in the real world and it was not recorded as a merge of
X into the mainline):
.---X---Y---Z
/
/
/
---o---A---o---.....---M---...---o---B
and X-Y-Z _is_ what you would maintain and keep tweaking. You
can publish Z and people who would want to "apply" the series
can cleanly apply X-Y-Z (or merge Z if they are git users).
But people who would want to "apply" the series to codebase
newer than point M would individually need to resolve conflicts
or know X is unneeded for them. To alleviate this, you would
publish _another_ commit:
.---X---Y---Z
/ \
/ Z'
/ /
---o---A---o---.....---M---...---o---B
That is, you merge Z to newer mainline for them to create Z',
and:
* publish Z' for git users --- they can merge this to their
codebase that is newer than M and they do not have to resolve
conflicts you needed to resolve, arising from the overlap
between X and M, when you created Z'.
* publish diff between M-Z', for non git users who would want
to apply it with "patch".
You suggested that you would keep rebasing X--Y--Z while
improving the long living patch series. You would recreate Z'
whenever the series is updated (and rerere will hopefully help
you re-resolve the conflicts between X and M automatically).
^ permalink raw reply
* Re: Stitching together private svn repo and public git repo
From: Dmitry Potapov @ 2008-01-02 22:13 UTC (permalink / raw)
To: Charles Bailey; +Cc: Gregory Jefferis, git
In-Reply-To: <20080102214005.GA10924@hashpling.org>
On Jan 3, 2008 12:40 AM, Charles Bailey <charles@hashpling.org> wrote:
> You could then do this with a 'git filter-branch --parent-filter' to
> rewrite the parents of the merge commits. As far as I can see, you
> would need to call filter-branch once per merge to rewrite everything
> from the merge commit forwards.
I believe there is a much easier way to do that using .git/info/grafts
The first step is to create .git/info/grafts, which specifies commit-id
and its parents for each commit that you want to change. Then you
can check the result using gitk, and if you are satisfied with what
you see then you run git filter-branch on it to convert 'fake' parents
into real ones.
Dmitry
^ permalink raw reply
* Re: Git and securing a repository
From: Linus Torvalds @ 2008-01-02 22:17 UTC (permalink / raw)
To: Gonzalo Garramu?o; +Cc: Felipe Balbi, git
In-Reply-To: <477B6199.6070601@advancedsl.com.ar>
On Wed, 2 Jan 2008, Gonzalo Garramu?o wrote:
>
> I was really looking for a permission based system that was part of git itself
> (and thus more portable and easier to admin), and not the OS. Something akin
> to what perforce or even CVS can do.
Well, git by design doesn't do that.
That doesn't mean that it has to be OS-level permissions (in fact, it
generally shouldn't), it just means that git wasn't really meant to care
about permissions itself, and you the user management and permissions
should come from "outside".
That outside *can* be OS-level things like just permissions on files, but
more commonly it's things like SSH keys and using the git hooks. In other
words, pretty much by design, git is meant to be the *core* SCM
infrastructure, and then you layer your user management on top of it as a
*separate* layer.
An example of that would probably be gitosis, but I haven't used it
myself. For the kernel, people literally tend to just use SSH accounts,
and not any central repository at all (ie the kind of crazy "central repo
access control rules" that centralized repos need are just not necessary
at all in a more distributed usage model).
See
http://eagain.net/gitweb/?p=gitosis.git
http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way
for a quick starting point on gitosis, if that suits your needs (there's
more, google is your friend).
Linus
^ permalink raw reply
* Re: [PATCH] receive-pack: check object type of sha1 before using them as commits
From: Linus Torvalds @ 2008-01-02 22:21 UTC (permalink / raw)
To: Martin Koegler; +Cc: Junio C Hamano, git
In-Reply-To: <11992595612601-git-send-email-mkoegler@auto.tuwien.ac.at>
On Wed, 2 Jan 2008, Martin Koegler wrote:
>
> - old_commit = (struct commit *)parse_object(old_sha1);
> - new_commit = (struct commit *)parse_object(new_sha1);
> + old_object = parse_object(old_sha1);
> + new_object = parse_object(new_sha1);
I think it would be better to use
old_object = lookup_commit_reference(old_sha1);
if (!old_object)
return "bad ref";
new_object = lookup_commit_reference(new_sha1);
if (!new_object)
return "bad ref";
which will write a slightly more useful error message if it's not a commit
(ie it will use the "check_commit()" function in commit.c)
Linus
^ permalink raw reply
* Re: Stitching together private svn repo and public git repo
From: Charles Bailey @ 2008-01-02 22:46 UTC (permalink / raw)
To: Dmitry Potapov; +Cc: Gregory Jefferis, git
In-Reply-To: <37fcd2780801021413g5f2a602dkb9fc289a13517375@mail.gmail.com>
On Thu, Jan 03, 2008 at 01:13:54AM +0300, Dmitry Potapov wrote:
> I believe there is a much easier way to do that using .git/info/grafts
> The first step is to create .git/info/grafts, which specifies commit-id
> and its parents for each commit that you want to change. Then you
> can check the result using gitk, and if you are satisfied with what
> you see then you run git filter-branch on it to convert 'fake' parents
> into real ones.
>
> Dmitry
>
Oh yes, this is much easier. Unless I'm missing something, the
documentation on grafts is fairly sparse, though. They are mentioned
(almost in passing) in git help filter-branch but the file format is
only documented in repository-layout.txt which seems more developer
than user oriented.
Charles.
^ permalink raw reply
* Re: [PATCH] receive-pack: check object type of sha1 before using them as commits
From: Junio C Hamano @ 2008-01-02 22:57 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Martin Koegler, git
In-Reply-To: <alpine.LFD.1.00.0801021418510.3010@woody.linux-foundation.org>
Linus Torvalds <torvalds@linux-foundation.org> writes:
> On Wed, 2 Jan 2008, Martin Koegler wrote:
>>
>> - old_commit = (struct commit *)parse_object(old_sha1);
>> - new_commit = (struct commit *)parse_object(new_sha1);
>> + old_object = parse_object(old_sha1);
>> + new_object = parse_object(new_sha1);
>
> I think it would be better to use
>
> old_object = lookup_commit_reference(old_sha1);
> if (!old_object)
> return "bad ref";
> new_object = lookup_commit_reference(new_sha1);
> if (!new_object)
> return "bad ref";
>
> which will write a slightly more useful error message if it's not a commit
> (ie it will use the "check_commit()" function in commit.c)
Hmmm... Three points.
* lookup_commit_reference() is silent if the object pointed at
by old/new SHA-1 is missing.
* when storing in refs/heads, we do not want to have committish
but we do want an actual commit object.
* returning like that the user cannot tell which ref had the
error.
^ permalink raw reply
* Re: [PATCH] Optimize prefixcmp()
From: René Scharfe @ 2008-01-03 0:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Marco Costalba, Git Mailing List
In-Reply-To: <7v1w90xdpe.fsf@gitster.siamese.dyndns.org>
Junio C Hamano schrieb:
> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
>
>> prefixcmp() was already optimized before -- only for a different use
>> case. At a number of callsites the prefix is a string literal, which
>> allowed the compiler to perform the strlen() call at compile time.
>>
>> The patch increases the text size considerably: the file "git" is
>> 2,620,938 without and 2,640,450 with the patch in my build (there are
>> 136 callsites in builtin*.c). The new version of prefixcmp() shouldn't
>> be inlined any more, as the benefit of doing so is gone.
>
> Yuck, you are absolutely right. The late thread may have been
> well intentioned but resulted in this regression. Sorry about
> that.
>
> I presume that all callers with constant prefix are outside
> performance critical parts? Can we simply uninline the function
> in that case?
Most of them seem to be non-critical performance-wise. They are part of
code to parse parameters or config files. Exceptions are the commit
message parsing code used for --pretty=format (which can't be an issue
given that prefixcmp() was made the way it's now to speed up this code
path) and half of the callsites in fast-import.c.
René
^ permalink raw reply
* Re: [PATCH] Avoid a useless prefix lookup in strbuf_expand()
From: René Scharfe @ 2008-01-03 0:45 UTC (permalink / raw)
To: Marco Costalba; +Cc: Git Mailing List, Junio C Hamano, Johannes Schindelin
In-Reply-To: <e5bfff550801021027i6d6a399cob96ae3c840661884@mail.gmail.com>
Marco Costalba schrieb:
> If we go on complex stuff then we can bite the bullet and use a text
> matcher state machine, but again, I still think that the best way is
> to avoid the 99% unusless loop and use only a (slightly) beefed up
> switch case instead.
>
> I would think you agree with me that searching if a string is found in
> a string vector then pass the _same_ string to another function that
> (practically) redoes *the same* check using a switch statement is not
> the best optimization one can think about.
The loop makes implementing the callback function a bit easier, since
you don't need to cover all cases; the input is already checked by
strbuf_expand().
Anyway, here's your patch again with a few small changes: the
placeholders array is gone as you suggested, the cases for %Cx, %ax and
%cx are check for unknown placeholders and the callback function returns
the number of bytes it consumed as size_t.
All in all: less code, slightly more complex callback functions (needs
to return the length of the consumed placeholder or 0 if the input
doesn't match a placeholder) and increased speed. I have to admit that
I start to like it. :-)
I tried to cover all cases of valid and invalid input; did I miss any?
René
pretty.c | 143 ++++++++++++++++++++++++++------------------------------------
strbuf.c | 19 ++++-----
strbuf.h | 4 +-
3 files changed, 70 insertions(+), 96 deletions(-)
diff --git a/pretty.c b/pretty.c
index 5b1078b..c0e9c8a 100644
--- a/pretty.c
+++ b/pretty.c
@@ -282,8 +282,8 @@ static char *logmsg_reencode(const struct commit *commit,
return out;
}
-static void format_person_part(struct strbuf *sb, char part,
- const char *msg, int len)
+static size_t format_person_part(struct strbuf *sb, char part,
+ const char *msg, int len)
{
int start, end, tz = 0;
unsigned long date;
@@ -297,36 +297,36 @@ static void format_person_part(struct strbuf *sb, char part,
end--;
if (part == 'n') { /* name */
strbuf_add(sb, msg, end);
- return;
+ return 1;
}
if (start >= len)
- return;
+ return 1;
/* parse email */
for (end = start + 1; end < len && msg[end] != '>'; end++)
; /* do nothing */
if (end >= len)
- return;
+ return 1;
if (part == 'e') { /* email */
strbuf_add(sb, msg + start, end - start);
- return;
+ return 1;
}
/* parse date */
for (start = end + 1; start < len && isspace(msg[start]); start++)
; /* do nothing */
if (start >= len)
- return;
+ return 1;
date = strtoul(msg + start, &ep, 10);
if (msg + start == ep)
- return;
+ return 1;
if (part == 't') { /* date, UNIX timestamp */
strbuf_add(sb, msg + start, ep - (msg + start));
- return;
+ return 1;
}
/* parse tz */
@@ -341,17 +341,19 @@ static void format_person_part(struct strbuf *sb, char part,
switch (part) {
case 'd': /* date */
strbuf_addstr(sb, show_date(date, tz, DATE_NORMAL));
- return;
+ return 1;
case 'D': /* date, RFC2822 style */
strbuf_addstr(sb, show_date(date, tz, DATE_RFC2822));
- return;
+ return 1;
case 'r': /* date, relative */
strbuf_addstr(sb, show_date(date, tz, DATE_RELATIVE));
- return;
+ return 1;
case 'i': /* date, ISO 8601 */
strbuf_addstr(sb, show_date(date, tz, DATE_ISO8601));
- return;
+ return 1;
}
+
+ return 0; /* unknown person part */
}
struct chunk {
@@ -432,8 +434,8 @@ static void parse_commit_header(struct format_commit_context *context)
context->commit_header_parsed = 1;
}
-static void format_commit_item(struct strbuf *sb, const char *placeholder,
- void *context)
+static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
+ void *context)
{
struct format_commit_context *c = context;
const struct commit *commit = c->commit;
@@ -443,23 +445,23 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
/* these are independent of the commit */
switch (placeholder[0]) {
case 'C':
- switch (placeholder[3]) {
- case 'd': /* red */
+ if (!prefixcmp(placeholder + 1, "red")) {
strbuf_addstr(sb, "\033[31m");
- return;
- case 'e': /* green */
+ return 4;
+ } else if (!prefixcmp(placeholder + 1, "green")) {
strbuf_addstr(sb, "\033[32m");
- return;
- case 'u': /* blue */
+ return 6;
+ } else if (!prefixcmp(placeholder + 1, "blue")) {
strbuf_addstr(sb, "\033[34m");
- return;
- case 's': /* reset color */
+ return 5;
+ } else if (!prefixcmp(placeholder + 1, "reset")) {
strbuf_addstr(sb, "\033[m");
- return;
- }
+ return 6;
+ } else
+ return 0;
case 'n': /* newline */
strbuf_addch(sb, '\n');
- return;
+ return 1;
}
/* these depend on the commit */
@@ -469,34 +471,34 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
switch (placeholder[0]) {
case 'H': /* commit hash */
strbuf_addstr(sb, sha1_to_hex(commit->object.sha1));
- return;
+ return 1;
case 'h': /* abbreviated commit hash */
if (add_again(sb, &c->abbrev_commit_hash))
- return;
+ return 1;
strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
DEFAULT_ABBREV));
c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
- return;
+ return 1;
case 'T': /* tree hash */
strbuf_addstr(sb, sha1_to_hex(commit->tree->object.sha1));
- return;
+ return 1;
case 't': /* abbreviated tree hash */
if (add_again(sb, &c->abbrev_tree_hash))
- return;
+ return 1;
strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.sha1,
DEFAULT_ABBREV));
c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
- return;
+ return 1;
case 'P': /* parent hashes */
for (p = commit->parents; p; p = p->next) {
if (p != commit->parents)
strbuf_addch(sb, ' ');
strbuf_addstr(sb, sha1_to_hex(p->item->object.sha1));
}
- return;
+ return 1;
case 'p': /* abbreviated parent hashes */
if (add_again(sb, &c->abbrev_parent_hashes))
- return;
+ return 1;
for (p = commit->parents; p; p = p->next) {
if (p != commit->parents)
strbuf_addch(sb, ' ');
@@ -505,14 +507,14 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
}
c->abbrev_parent_hashes.len = sb->len -
c->abbrev_parent_hashes.off;
- return;
+ return 1;
case 'm': /* left/right/bottom */
strbuf_addch(sb, (commit->object.flags & BOUNDARY)
? '-'
: (commit->object.flags & SYMMETRIC_LEFT)
? '<'
: '>');
- return;
+ return 1;
}
/* For the rest we have to parse the commit header. */
@@ -520,66 +522,41 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
parse_commit_header(c);
switch (placeholder[0]) {
- case 's':
+ case 's': /* subject */
strbuf_add(sb, msg + c->subject.off, c->subject.len);
- return;
- case 'a':
- format_person_part(sb, placeholder[1],
- msg + c->author.off, c->author.len);
- return;
- case 'c':
- format_person_part(sb, placeholder[1],
- msg + c->committer.off, c->committer.len);
- return;
- case 'e':
+ return 1;
+ case 'a': /* author ... */
+ if (format_person_part(sb, placeholder[1],
+ msg + c->author.off,
+ c->author.len))
+ return 2;
+ else
+ return 0;
+ case 'c': /* committer ... */
+ if (format_person_part(sb, placeholder[1],
+ msg + c->committer.off,
+ c->committer.len))
+ return 2;
+ else
+ return 0;
+ case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
- return;
- case 'b':
+ return 1;
+ case 'b': /* body */
strbuf_addstr(sb, msg + c->body_off);
- return;
+ return 1;
}
+ return 0; /* unknown placeholder */
}
void format_commit_message(const struct commit *commit,
const void *format, struct strbuf *sb)
{
- const char *placeholders[] = {
- "H", /* commit hash */
- "h", /* abbreviated commit hash */
- "T", /* tree hash */
- "t", /* abbreviated tree hash */
- "P", /* parent hashes */
- "p", /* abbreviated parent hashes */
- "an", /* author name */
- "ae", /* author email */
- "ad", /* author date */
- "aD", /* author date, RFC2822 style */
- "ar", /* author date, relative */
- "at", /* author date, UNIX timestamp */
- "ai", /* author date, ISO 8601 */
- "cn", /* committer name */
- "ce", /* committer email */
- "cd", /* committer date */
- "cD", /* committer date, RFC2822 style */
- "cr", /* committer date, relative */
- "ct", /* committer date, UNIX timestamp */
- "ci", /* committer date, ISO 8601 */
- "e", /* encoding */
- "s", /* subject */
- "b", /* body */
- "Cred", /* red */
- "Cgreen", /* green */
- "Cblue", /* blue */
- "Creset", /* reset color */
- "n", /* newline */
- "m", /* left/right/bottom */
- NULL
- };
struct format_commit_context context;
memset(&context, 0, sizeof(context));
context.commit = commit;
- strbuf_expand(sb, format, placeholders, format_commit_item, &context);
+ strbuf_expand(sb, format, format_commit_item, &context);
}
static void pp_header(enum cmit_fmt fmt,
diff --git a/strbuf.c b/strbuf.c
index b9b194b..7bb087c 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -137,11 +137,12 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
strbuf_setlen(sb, sb->len + len);
}
-void strbuf_expand(struct strbuf *sb, const char *format,
- const char **placeholders, expand_fn_t fn, void *context)
+void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn,
+ void *context)
{
for (;;) {
- const char *percent, **p;
+ const char *percent;
+ size_t consumed;
percent = strchrnul(format, '%');
strbuf_add(sb, format, percent - format);
@@ -149,14 +150,10 @@ void strbuf_expand(struct strbuf *sb, const char *format,
break;
format = percent + 1;
- for (p = placeholders; *p; p++) {
- if (!prefixcmp(format, *p))
- break;
- }
- if (*p) {
- fn(sb, *p, context);
- format += strlen(*p);
- } else
+ consumed = fn(sb, format, context);
+ if (consumed)
+ format += consumed;
+ else
strbuf_addch(sb, '%');
}
}
diff --git a/strbuf.h b/strbuf.h
index 36d61db..faec229 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -103,8 +103,8 @@ static inline void strbuf_addbuf(struct strbuf *sb, struct strbuf *sb2) {
}
extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
-typedef void (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
-extern void strbuf_expand(struct strbuf *sb, const char *format, const char **placeholders, expand_fn_t fn, void *context);
+typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
+extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context);
__attribute__((format(printf,2,3)))
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
^ permalink raw reply related
* Re: Retroactively change email signature?
From: David Brown @ 2008-01-03 0:53 UTC (permalink / raw)
To: Stephen Sinclair; +Cc: git
In-Reply-To: <9b3e2dc20801021406h46a73ef3ye0c4613d6472a4b3@mail.gmail.com>
On Wed, Jan 02, 2008 at 05:06:37PM -0500, Stephen Sinclair wrote:
>For example, I have a clone of this repo on a Linux, Windows, and OS X
>machine, and also another clone for each on my laptop.. git is
>actually turning out to be great for doing all this swapping between
>machines, but it does take a little training to remember to set the
>configuration, since there's no central repo to ask me for my username
>and password before I can commit.
You can set the user.email and user.name globally with 'git config --global
user.email ...' and the likes, but that only works if you use the same ID.
It'd be nice if there was something that could be put in the global
user.email to require each repository to override that. On one machine, my
password file doesn't have my name in it, and I kind of get this behavior
by default, but it be nice to be able to do it for real.
Anyone have ideas on how this could be done?
Dave
^ permalink raw reply
* Re: [ANNOUNCE] ugit: the pythonic git gui
From: David @ 2008-01-03 3:20 UTC (permalink / raw)
To: Guilhem Bonnefille; +Cc: git
In-Reply-To: <8b65902a0801020242x425b792xbfa5ee69a13c2573@mail.gmail.com>
On Jan 2, 2008 2:42 AM, Guilhem Bonnefille <guilhem.bonnefille@gmail.com> wrote:
> Hi,
>
> Good to learn a new GUI is available for Git.
>
> But, for people like me, not enougth curious to install the software,
> do you have any screenshots somewhere?
> --
> Guilhem BONNEFILLE
Cool, thank you.
I've posted some screenshots on http://ugit.justroots.com/
I don't have any fancy mac or windows installers at the moment (Linux
is my primary platform) though I am working on packaging soon.
-David
^ permalink raw reply
* Re: Git and securing a repository
From: Shawn O. Pearce @ 2008-01-03 3:58 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Gonzalo Garramuño, David Symonds, git
In-Reply-To: <m3ir2co5s4.fsf@roke.D-201>
Jakub Narebski <jnareb@gmail.com> wrote:
> Gonzalo Garramuño <ggarra@advancedsl.com.ar> writes:
> > David Symonds wrote:
> >>
> >> You can do arbitrarily-fine-grained authentication via the
> >> pre-receive hook.
> >
> > Can you provide some more info? Looking at the kernel.org git docs,
> > the pre-receive hook seems very limited as no parameters are allowed.
> > So I'm not sure how an authentication system could be created.
If you read the documentation carefully you will note that the
pre-receive hook receives input on stdin; 1 line of data per ref
that is being pushed with the old/new SHA-1 values and the ref
name. The hook exits 0 to allow all changes to take place and
can exit > 0 to abort and disallow all updates.
This is a "batch" form of the update hook.
> > It also seems to be a push hook only (not invoked on pulls).
>
> Some of read-only (fetch only) access protocols do not support
> authentication: http, ftp, rsync, git. Authentication is provided only
> for access via ssh and for push via https (WebDAV).
Authentication could be supported for http, ftp, or ssh based fetch,
but there you are relying on the server that provides access to do
the authentication and authorization for you; typically that will
boil down to UNIX filesystem read permission. Though with HTTP
and a fancy Apache config it doesn't have to be.
> There is example update hook in contrib/hooks, named update-paranoid,
> which could be base of what you want. Note that you probably rather
> use newer pre-receive hook instead of older update hook.
update-paranoid uses the update hook rather than pre-receive to
allow it to allow/deny on a per-ref basis. One of the flaws of
the pre-receive hook "API" is it is an all-or-nothing proposition.
So by using the "older" update hook update-paranoid can make its
decision on a per-ref basis and allow some refs to change in this
push but abort/deny others. I find that useful but not everyone
might.
> AFAIK both update and pre-receive hooks are invoked also on fetch...
> but I might be mistaken.
No, they are *not* invoked on fetch. Currently no hooks execute
during fetch; either on the server *or* on the client side of
the connection.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
From: Dmitry Kakurin @ 2008-01-03 4:07 UTC (permalink / raw)
To: Steffen Prohaska
Cc: Git Mailing List, Johannes Sixt, Junio C Hamano,
Johannes Schindelin
In-Reply-To: <0FFA1D0A-DB70-446C-9C43-A6FBAEFE7CA4@zib.de>
On Jan 1, 2008 10:52 AM, Steffen Prohaska <prohaska@zib.de> wrote:
> In conclusion, using setenv() as in the original code instead of
> set_git_dir() should be safe and this patch is not needed.
>
> I tend to revert the changes in msysgit and see if we hit any
> problems. But I'll wait until 1.5.4 is released.
>
> Steffen
Please don't revert this change. I've made it in response to git clone
failing, commit 855f254b2b5b083a63fc8d7709a42e2cbdc5a136.
--
- Dmitry
^ permalink raw reply
* Re: Git and securing a repository
From: Gonzalo Garramuño @ 2008-01-03 5:36 UTC (permalink / raw)
To: Shawn O. Pearce, git
In-Reply-To: <20080103035838.GA24004@spearce.org>
Shawn O. Pearce wrote:
>
> If you read the documentation carefully you will note that the
> pre-receive hook receives input on stdin; 1 line of data per ref
> that is being pushed with the old/new SHA-1 values and the ref
> name. The hook exits 0 to allow all changes to take place and
> can exit > 0 to abort and disallow all updates.
>
Sure, but I cannot pass any sort of authentication to the script other
than rely on environment variables or system calls, as git will not
provide anything else.
To do proper authentication on a file or directory basis, I have to mix
two things then:
A user/group base authentication/login based likely on unix permissions
and ssh AND a pre-receive hook script that finds the user/group name and
then checks whether the user can change that particular file/directory.
I hope the ref name is the (relative) path name to the file and not just
the file's basename.
If so, I can see that most of what I want to do is possible. It is just
pretty far from being elegant or easy to set up.
To distinguish a bad commit due to tabs for example from an actual
permission trouble. I'm assuming that the stderr/stdout of git hooks is
redirected back to the client?
Even with all of that, it seems it is still not possible to limit pulls
to a certain directory only, right?
Anyway, I think I more or less have the answer I (sadly) expected.
Git's authorization mechanism is pretty much a roll your own type thing.
I'll check out the python authorization script that Linus mentioned to
see if that alleviates setup troubles a bit.
--
Gonzalo Garramuño
ggarra@advancedsl.com.ar
AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy
^ permalink raw reply
* Re: Git and securing a repository
From: Shawn O. Pearce @ 2008-01-03 4:45 UTC (permalink / raw)
To: Gonzalo Garramuño; +Cc: git
In-Reply-To: <477C7459.3020402@advancedsl.com.ar>
Gonzalo Garramuo <ggarra@advancedsl.com.ar> wrote:
> Shawn O. Pearce wrote:
> >
> >If you read the documentation carefully you will note that the
> >pre-receive hook receives input on stdin; 1 line of data per ref
> >that is being pushed with the old/new SHA-1 values and the ref
> >name. The hook exits 0 to allow all changes to take place and
> >can exit > 0 to abort and disallow all updates.
> >
>
> Sure, but I cannot pass any sort of authentication to the script other
> than rely on environment variables or system calls, as git will not
> provide anything else.
Correct.
> To do proper authentication on a file or directory basis, I have to mix
> two things then:
>
> A user/group base authentication/login based likely on unix permissions
> and ssh AND a pre-receive hook script that finds the user/group name and
> then checks whether the user can change that particular file/directory.
>
> I hope the ref name is the (relative) path name to the file and not just
> the file's basename.
No, the ref name is the name of the branch being modified. If there
is only one branch in your repository its probably always going to
be the default name of "refs/heads/master".
If you want to know what files the user has changed you need to
diff the two SHA-1s (old against new) to come up with the names of
the files being changed; e.g.:
git diff-tree -r $old $new
The update-paranoid hook in contrib has support for doing this
built-in and can allow A/M/D type changes on specific file paths,
entire directories, or any regex pattern that matches the above.
I use this at day-job to prevent users from doing stupid things to
directories they shouldn't be changing on particular branches.
> To distinguish a bad commit due to tabs for example from an actual
> permission trouble. I'm assuming that the stderr/stdout of git hooks is
> redirected back to the client?
You need to diff the old against the new (or use rev-list to list
all of the commits between old and new and then get the patch for
each of those commits) to determine if the commit is "bad" or not.
Remember that a single git-push can upload hundreds of commits in
one shot to the receiving repository.
But yes, both stdout and stderr of the hook are tied to the stderr
of the client running git-push. So error messages produced by
the hook to explain why the push is being denied are visible to
the end-user who is executing git-push. Again, update-paranoid
uses this to tell you if the "committer" line in commit objects is
invalid, or if you are changing a file you shouldn't be.
> Even with all of that, it seems it is still not possible to limit pulls
> to a certain directory only, right?
No. Git pretty much requires that when you have access to fetch/pull
a repository you have access to *all* of that repository. Limiting to
a subdirectory would actually require moving that entire subdirectory
into its own repository and using git-submodule instead to manage it.
> Anyway, I think I more or less have the answer I (sadly) expected.
> Git's authorization mechanism is pretty much a roll your own type thing.
> I'll check out the python authorization script that Linus mentioned to
> see if that alleviates setup troubles a bit.
Its a distributed version control system. All peers are equal.
Most security in Git is handled by only pulling from sources you
trust, and never allowing someone to push stuff into a repository
you own.
As such it also usually boils down to UNIX filesystem security; what
I let you see is what you can see, what I firewall and hide from
you is what you cannot see. Quite simple when you think about it,
but then you are moving away from a centralized development model
and going to a distributed one... which is what Git was built for.
--
Shawn.
^ permalink raw reply
* Re: Git and securing a repository
From: Bruno Cesar Ribas @ 2008-01-03 4:30 UTC (permalink / raw)
To: Shawn O. Pearce
Cc: Jakub Narebski, Gonzalo Garramuño, David Symonds, git
In-Reply-To: <20080103035838.GA24004@spearce.org>
I lost ohter mails, so replying here =)
I wrote sometime ago i wrote[1] a bunch of BASH scripts to manage SSH_ACL and "internal"
plugin is to manage GIT repositories.
It is simple and you can grant access to a user for R or W. And there is NO
need to create more users just a "git" user is nice.
I'm re-writing it to become more flexible about configuration and to add more
plugins.
We are using it at C3SL[2] to manage our projects and Write permissions are
set because we don't want some developers pushing to anothers projects.
bruno
[1]http://www.inf.ufpr.br/ribas/ssh_acl/
[2]http://www.c3sl.ufpr.br
On Wed, Jan 02, 2008 at 10:58:38PM -0500, Shawn O. Pearce wrote:
> Jakub Narebski <jnareb@gmail.com> wrote:
> > Gonzalo Garramuño <ggarra@advancedsl.com.ar> writes:
> > > David Symonds wrote:
> > >>
> > >> You can do arbitrarily-fine-grained authentication via the
> > >> pre-receive hook.
> > >
> > > Can you provide some more info? Looking at the kernel.org git docs,
> > > the pre-receive hook seems very limited as no parameters are allowed.
> > > So I'm not sure how an authentication system could be created.
>
> If you read the documentation carefully you will note that the
> pre-receive hook receives input on stdin; 1 line of data per ref
> that is being pushed with the old/new SHA-1 values and the ref
> name. The hook exits 0 to allow all changes to take place and
> can exit > 0 to abort and disallow all updates.
>
> This is a "batch" form of the update hook.
>
> > > It also seems to be a push hook only (not invoked on pulls).
> >
> > Some of read-only (fetch only) access protocols do not support
> > authentication: http, ftp, rsync, git. Authentication is provided only
> > for access via ssh and for push via https (WebDAV).
>
> Authentication could be supported for http, ftp, or ssh based fetch,
> but there you are relying on the server that provides access to do
> the authentication and authorization for you; typically that will
> boil down to UNIX filesystem read permission. Though with HTTP
> and a fancy Apache config it doesn't have to be.
>
> > There is example update hook in contrib/hooks, named update-paranoid,
> > which could be base of what you want. Note that you probably rather
> > use newer pre-receive hook instead of older update hook.
>
> update-paranoid uses the update hook rather than pre-receive to
> allow it to allow/deny on a per-ref basis. One of the flaws of
> the pre-receive hook "API" is it is an all-or-nothing proposition.
>
> So by using the "older" update hook update-paranoid can make its
> decision on a per-ref basis and allow some refs to change in this
> push but abort/deny others. I find that useful but not everyone
> might.
>
> > AFAIK both update and pre-receive hooks are invoked also on fetch...
> > but I might be mistaken.
>
> No, they are *not* invoked on fetch. Currently no hooks execute
> during fetch; either on the server *or* on the client side of
> the connection.
>
> --
> Shawn.
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Bruno Ribas - ribas@c3sl.ufpr.br
http://web.inf.ufpr.br/ribas
C3SL: http://www.c3sl.ufpr.br
^ permalink raw reply
* Re: Git and securing a repository
From: Gonzalo Garramuño @ 2008-01-03 6:08 UTC (permalink / raw)
To: Shawn O. Pearce, git
In-Reply-To: <20080103044552.GB24004@spearce.org>
Shawn O. Pearce wrote:
>
> Its a distributed version control system. All peers are equal.
> Most security in Git is handled by only pulling from sources you
> trust, and never allowing someone to push stuff into a repository
> you own.
>
Regarding that... is there a way to control the umask of a git clone
independent of the actual umask of the user or directories inside the
repository? Ideally, on the server side?
That is, for sensitive repositories, I would like "git clone" to always
clone that repository with 0700 permissions, so that the silly mistake
of cloning a sensitive repository into a public directory and forgetting
to restrict its permissions can be avoided completely.
--
Gonzalo Garramuño
ggarra@advancedsl.com.ar
AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy
^ permalink raw reply
* Re: Git and securing a repository
From: Shawn O. Pearce @ 2008-01-03 5:19 UTC (permalink / raw)
To: Gonzalo Garramuño; +Cc: git
In-Reply-To: <477C7BF8.2090406@advancedsl.com.ar>
Gonzalo Garramuo <ggarra@advancedsl.com.ar> wrote:
> Shawn O. Pearce wrote:
> >
> >Its a distributed version control system. All peers are equal.
> >Most security in Git is handled by only pulling from sources you
> >trust, and never allowing someone to push stuff into a repository
> >you own.
> >
>
> Regarding that... is there a way to control the umask of a git clone
> independent of the actual umask of the user or directories inside the
> repository? Ideally, on the server side?
>
> That is, for sensitive repositories, I would like "git clone" to always
> clone that repository with 0700 permissions, so that the silly mistake
> of cloning a sensitive repository into a public directory and forgetting
> to restrict its permissions can be avoided completely.
No.
For a local clone (same UNIX system) you could probably easily
modify git-clone.sh to consult the config file of the source
repository to obtain recommended initial permissions, or just use
the source repository's directory permissions as the new clone's
initial permissions. But not everyone would want that behavior.
For a remote clone (different systems) the config file of the source
repository isn't easily available. So its not easily used to get
that setting. The git protocol would have to be extended to make
transfer of parts of the config file possible. We've talked about
this in the past but have never had a compelling application to
cause patches to be submitted for it.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
From: Steffen Prohaska @ 2008-01-03 6:02 UTC (permalink / raw)
To: Dmitry Kakurin
Cc: Git Mailing List, Johannes Sixt, Junio C Hamano,
Johannes Schindelin
In-Reply-To: <a1bbc6950801022007w164d050bhf8a8a8c0ad6736b@mail.gmail.com>
On Jan 3, 2008, at 5:07 AM, Dmitry Kakurin wrote:
> On Jan 1, 2008 10:52 AM, Steffen Prohaska <prohaska@zib.de> wrote:
>> In conclusion, using setenv() as in the original code instead of
>> set_git_dir() should be safe and this patch is not needed.
>>
>> I tend to revert the changes in msysgit and see if we hit any
>> problems. But I'll wait until 1.5.4 is released.
>>
>> Steffen
>
> Please don't revert this change. I've made it in response to git clone
> failing, commit 855f254b2b5b083a63fc8d7709a42e2cbdc5a136.
I know. But I cannot reproduce the error.
Do you have a test case that demonstrates the problem?
I either want to see the patch upstream in official git or revert
it in msysgit. But I cannot answer the questions that were
raised after I sent the patch (see earlier in this thread). And
I can't see the problem that your patch solves, even after
spending some time on reading and instrumenting code.
Steffen
^ permalink raw reply
* Re: [PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
From: Dmitry Kakurin @ 2008-01-03 6:26 UTC (permalink / raw)
To: Steffen Prohaska
Cc: Git Mailing List, Johannes Sixt, Junio C Hamano,
Johannes Schindelin
In-Reply-To: <42F546CE-2564-4DFB-B260-FD50BD51F2BB@zib.de>
On Jan 2, 2008 10:02 PM, Steffen Prohaska <prohaska@zib.de> wrote:
>
>
> On Jan 3, 2008, at 5:07 AM, Dmitry Kakurin wrote:
>
> > On Jan 1, 2008 10:52 AM, Steffen Prohaska <prohaska@zib.de> wrote:
> >> In conclusion, using setenv() as in the original code instead of
> >> set_git_dir() should be safe and this patch is not needed.
> >>
> >> I tend to revert the changes in msysgit and see if we hit any
> >> problems. But I'll wait until 1.5.4 is released.
> >>
> >> Steffen
> >
> > Please don't revert this change. I've made it in response to git clone
> > failing, commit 855f254b2b5b083a63fc8d7709a42e2cbdc5a136.
>
> I know. But I cannot reproduce the error.
>
> Do you have a test case that demonstrates the problem?
>
> I either want to see the patch upstream in official git or revert
> it in msysgit. But I cannot answer the questions that were
> raised after I sent the patch (see earlier in this thread). And
> I can't see the problem that your patch solves, even after
> spending some time on reading and instrumenting code.
I remember that the problem was as simple as git clone or git clone
--bare failing.
Also I'm not sure if it matters but I'm running Vista.
There is also a chance that code has changed since then and this
problem went away.
--
- Dmitry
^ permalink raw reply
* Re: [PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
From: Steffen Prohaska @ 2008-01-03 7:53 UTC (permalink / raw)
To: Dmitry Kakurin
Cc: Git Mailing List, Johannes Sixt, Junio C Hamano,
Johannes Schindelin
In-Reply-To: <a1bbc6950801022226k32cfd9b9t62939b3cbedef247@mail.gmail.com>
On Jan 3, 2008, at 7:26 AM, Dmitry Kakurin wrote:
> On Jan 2, 2008 10:02 PM, Steffen Prohaska <prohaska@zib.de> wrote:
>>
>>
>> On Jan 3, 2008, at 5:07 AM, Dmitry Kakurin wrote:
>>
>>> On Jan 1, 2008 10:52 AM, Steffen Prohaska <prohaska@zib.de> wrote:
>>>> In conclusion, using setenv() as in the original code instead of
>>>> set_git_dir() should be safe and this patch is not needed.
>>>>
>>>> I tend to revert the changes in msysgit and see if we hit any
>>>> problems. But I'll wait until 1.5.4 is released.
>>>>
>>>> Steffen
>>>
>>> Please don't revert this change. I've made it in response to git
>>> clone
>>> failing, commit 855f254b2b5b083a63fc8d7709a42e2cbdc5a136.
>>
>> I know. But I cannot reproduce the error.
>>
>> Do you have a test case that demonstrates the problem?
>>
>> I either want to see the patch upstream in official git or revert
>> it in msysgit. But I cannot answer the questions that were
>> raised after I sent the patch (see earlier in this thread). And
>> I can't see the problem that your patch solves, even after
>> spending some time on reading and instrumenting code.
>
> I remember that the problem was as simple as git clone or git clone
> --bare failing.
This is what I understood from the commit message.
I need a script that I can run to see the error. All tests that
come with git pass (on my machine).
> Also I'm not sure if it matters but I'm running Vista.
It only matters if you see an error on Vista that I don't see on
XP. If this was the case I'd debug on Vista.
> There is also a chance that code has changed since then and this
> problem went away.
Maybe.
Steffen
^ permalink raw reply
* [RFH] On a script for submodules
From: Imran M Yousuf @ 2008-01-03 9:07 UTC (permalink / raw)
To: git
Hi All,
I started writing a script intended for modular (Git modules)
projects. The script can be found at
http://repo.or.cz/w/git-modules-bs.git. This is a very rudimentary
version and I intend to make it more useful for developers who work
with multiple modules. I would also like to mention that I am not an
expert shell scripter thus probably have made several mistakes in the
script; I would really appreciate if someone would take their time to
suggest me improvements. I would also like to get some feedbacks as
what else could be added here. A brief description can be found in the
following posting.
http://imyousuf-tech.blogs.smartitengineering.com/2008/01/propagating-git-commands-to-its.html
Thank you,
--
Imran M Yousuf
^ permalink raw reply
* Re: [PATCH] Avoid a useless prefix lookup in strbuf_expand()
From: Junio C Hamano @ 2008-01-03 9:08 UTC (permalink / raw)
To: René Scharfe; +Cc: Marco Costalba, Git Mailing List, Johannes Schindelin
In-Reply-To: <477C301D.7060509@lsrfire.ath.cx>
René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> The loop makes implementing the callback function a bit easier, since
> you don't need to cover all cases; the input is already checked by
> strbuf_expand().
>
> Anyway, here's your patch again with a few small changes: the
> placeholders array is gone as you suggested, the cases for %Cx, %ax and
> %cx are check for unknown placeholders and the callback function returns
> the number of bytes it consumed as size_t.
>
> All in all: less code, slightly more complex callback functions (needs
> to return the length of the consumed placeholder or 0 if the input
> doesn't match a placeholder) and increased speed. I have to admit that
> I start to like it. :-)
I'll let Marco bench it and hopefully Ack with an updated
(final) commit log message.
I think Dscho and Marco's earlier prefixcmp() optimization to
avoid strlen() can stay, but with "inline" removed. That should
be equivalent to the version before the optimization, both from
the point of view of the code footprint and callchain length,
but still avoid strlen() cost.
Due to lack of better place the patch below moves it to strbuf.c
which probably is the closest collection of "stringy" stuff.
$ size git ;# with the attached patch
text data bss dec hex filename
731144 13456 263464 1008064 f61c0 git
$ size ../git.build/git ;# before Dscho's patch
text data bss dec hex filename
731272 13456 263464 1008192 f6240 ../git.build/git
$ size ~/bin/git ;# with Dscho's patch
text data bss dec hex filename
740736 13456 263464 1017656 f8738 /home/junio/bin/git
You earlier said 2,620,938 vs 2,640,450 and I think you meant
what "ls -l" reports. I suspect it is not a very good measure,
but the numbers here are:
$ ls -l git ;# with the attached patch
-rwxrwxr-x 83 junio src 3345237 2008-01-03 00:53 git
$ ls -l ../git.build/git ;# before Dscho's patch
-rwxrwxr-x 83 junio src 3364803 2008-01-03 01:01 ../git.build/git
$ ls -l ~/bin/git ;# with Dscho's patch
-rwxr-xr-x 83 junio src 3389299 2008-01-02 15:18 /home/junio/bin/git
-- >8 --
Uninline prefixcmp()
Now the routine is an open-coded loop that avoids an extra
strlen() in the previous implementation, it got a bit too big to
be inlined. Uninlining it makes code footprint smaller but the
result still retains the avoidance of strlen() cost.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
git-compat-util.h | 11 ++---------
strbuf.c | 9 +++++++++
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index 7059cbd..b6ef544 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -122,6 +122,8 @@ extern void set_die_routine(void (*routine)(const char *err, va_list params) NOR
extern void set_error_routine(void (*routine)(const char *err, va_list params));
extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
+extern int prefixcmp(const char *str, const char *prefix);
+
#ifdef NO_MMAP
#ifndef PROT_READ
@@ -396,15 +398,6 @@ static inline int sane_case(int x, int high)
return x;
}
-static inline int prefixcmp(const char *str, const char *prefix)
-{
- for (; ; str++, prefix++)
- if (!*prefix)
- return 0;
- else if (*str != *prefix)
- return (unsigned char)*prefix - (unsigned char)*str;
-}
-
static inline int strtoul_ui(char const *s, int base, unsigned int *result)
{
unsigned long ul;
diff --git a/strbuf.c b/strbuf.c
index b9b194b..5efcfc8 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,5 +1,14 @@
#include "cache.h"
+int prefixcmp(const char *str, const char *prefix)
+{
+ for (; ; str++, prefix++)
+ if (!*prefix)
+ return 0;
+ else if (*str != *prefix)
+ return (unsigned char)*prefix - (unsigned char)*str;
+}
+
/*
* Used as the default ->buf value, so that people can always assume
* buf is non NULL and ->buf is NUL terminated even for a freshly
^ permalink raw reply related
* Re: Git and securing a repository
From: Jakub Narebski @ 2008-01-03 9:11 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20080103035838.GA24004@spearce.org>
Shawn O. Pearce wrote:
> Jakub Narebski <jnareb@gmail.com> wrote:
> > AFAIK both update and pre-receive hooks are invoked also on fetch...
> > but I might be mistaken.
>
> No, they are *not* invoked on fetch. Currently no hooks execute
> during fetch; either on the server *or* on the client side of
> the connection.
Errr... I think at least post-update hook (the one with
git-update-server-info by default) is invoked on fetch.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: Git and securing a repository
From: Junio C Hamano @ 2008-01-03 9:36 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Shawn O. Pearce, git
In-Reply-To: <200801031011.29050.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> writes:
> Shawn O. Pearce wrote:
>> Jakub Narebski <jnareb@gmail.com> wrote:
>
>> > AFAIK both update and pre-receive hooks are invoked also on fetch...
>> > but I might be mistaken.
>>
>> No, they are *not* invoked on fetch. Currently no hooks execute
>> during fetch; either on the server *or* on the client side of
>> the connection.
>
> Errr... I think at least post-update hook (the one with
> git-update-server-info by default) is invoked on fetch.
Please don't think then. Instead check your facts before
posting to avoid wasting bandwidth and people's time. The
post-update hook is run on the remote end when you push into it.
I do not particularly like hooks that act after an operation is
initiated locally and act solely on local data. This is maybe
because I still consider git tools building blocks suitable for
higher level scripting more than other people do.
There are five valid reasons you might want a hook to a git
operation:
(1) A hook that countermands the normal decision made by the
underlying command. Examples of this class are the update
hook and the pre-commit hook.
(2) A hook that operates on data generated after the command
starts to run. The ability to munge the commit log message
by the commit-msg hook is an example.
(3) A hook that operates on the remote end of the connection
that you may not otherwise have access to other than over
the git protocol. An example is the post-update hook.
(4) A hook that runs under a lock that is acquired by the
command for mutual exclusion. Currently there is no
example, but if we allowed the update hook to modify the
commit that was pushed through send-pack => receive-pack
pair, which was discussed on the list a while ago, it would
be a good example of this.
(5) A hook that is run differently depending on the outcome of
the command. The post-merge hook conditionally run by
git-pull is an example of this (it is not even run if no
merge takes place). Another example is the post-checkout
hook that gets information that is otherwise harder to get
(namely, if it was a branch checkout or file checkout --
you can figure it out by examining the command line but
that already is part of the processing git-checkout does
anyway, so no need to force duplicating that code in the
userland).
You cannot do an equivalent operation from outside the git
command for the above classes of operations. You need hooks
for them.
On the other hand, if you want to always cause an action after
running a git opeation locally, you do not have to have a hook.
You can just run them yourself, or have "git myfetch" wrapper
that does whatever you want after running "git fetch". Only
when the combination of the underlying command and something
else is widely useful, _and_ that something else needs
flexibility, a hook is warranted (if that something else is
always the same thing, it is better to fold that into the
underlying command).
^ 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