githelper.git/
githelper.pike
Branch:
Tag:
Non-build tags
All tags
No tags
2010-09-25
2010-09-25 20:39:18 by Marcus Comstedt <marcus@mc.pp.se>
aeab9a04f72c4d5b445fe3a62a38e24445af2a16 (
101
lines) (+
63
/-
38
)
[
Show
|
Annotate
]
Branch:
master
Improved attribute checking in server hook.
63:
return run_git("cat-file", "blob", sha); }
-
string get_committed_file(string sha, string filename)
+
string get_committed_file(string sha, string filename
, int|void allow_empty
)
{ string blob; string attrentry = run_git("ls-tree", sha, "--", filename);
-
+
if (allow_empty && !sizeof(attrentry))
+
return "";
if (2 != sscanf(attrentry, "%*o blob %s\t", blob)) fail("Unexpected output from git ls-tree\n"); return run_git("cat-file", "blob", blob);
198:
return all_attr; }
+
array(string) findattr(string attrname)
+
{
+
array(string) r = ({});
+
foreach(attrs, MatchAttr attr) {
+
int z=0;
+
foreach(attr->states, AttrState state)
+
if(state->attr == attrname && state->setto == ATTR_TRUE) {
+
z = 1;
+
break;
+
}
+
if (z)
+
r += ({ attr->name });
+
}
+
return r;
+
}
+
static string _sprintf(int type) { return type=='O' && sprintf("GitAttributes(%O)\n", attrs); }
360:
foreach(files_to_commit, string filename) { mapping(string:string|int) a = attrs->checkattr(filename); if(a->foreign_ident == GitAttributes.ATTR_TRUE) {
+
if (sizeof(run_git("ls-tree", sha+"^", "--", filename)) ||
+
!sizeof(run_git("ls-tree", sha, "--", filename))) {
write("File %s has the foreign_ident attribute. Please remove it before commit.\n", filename); return 1; }
-
+
}
if(stringp(a->block_commit) || a->block_commit == GitAttributes.ATTR_TRUE) {
-
+
if (sizeof(run_git("ls-tree", sha+"^", "--", filename)) ||
+
!sizeof(run_git("ls-tree", sha, "--", filename))) {
write("File %s is blocked from committing: %s\n", filename, replace((stringp(a->block_commit)? a->block_commit : "no explanation given"), "-", " ")); return 1; }
-
+
}
if(a->ident && a->ident != GitAttributes.ATTR_FALSE && a->ident != GitAttributes.ATTR_UNSET) { if (check_ident(sha, filename))
378:
return 0; }
-
int check_gitattributes_files(string sha, array(string) files_to_commit)
+
int check_gitattributes_files(string sha, array(string) files_to_commit
,
+
GitAttributes attrs
)
{ foreach(files_to_commit, string filename) if(has_suffix(filename, "/.gitattributes")) {
387:
} if(search(files_to_commit, ".gitattributes")>=0) {
-
string
diff = run
_
git("diff",
"-p", sha+"^", sha,
-
"
--
", ".gitattributes");
-
if
(
sizeof(diff
)
)
{
-
int pos
=
search
(
diff,
"
\n@@
")
;
-
if (pos >= 0
)
-
diff = diff[pos+1..]
;
-
foreach
(
diff/"\n",
string
line
)
-
if
(
sizeof
(
line) && search(line,
"foreign_ident")
>=0 &&
-
search
(
line, "[attr]"
)
!=
1 &&
-
(line[0]
=
='+'
||
line[0]=='
-
'))
{
-
int code, len
;
-
string
fn;
-
if(
sscanf
(
line
, "
%c
/
%s foreign_ident%n
"
, code, fn, len
)
!= 3
||
-
len !
=
sizeof(line
)
)
{
-
write("
Unsupported
change
of
foreign_ident
in .gitattributes\n
");
+
GitAttributes
old_attrs
=
+
GitAttributes(get_committed_file(sha+
"
^
", ".gitattributes"
, 1
)
)
;
+
+
array
(
string
)
new_f_e
=
sort
(
attrs->findattr(
"
foreign_ident
"));
+
array
(string)
old_f_e
=
sort
(
old_attrs->findattr
("foreign_ident")
);
+
array
(
string
)
added_fe
=
new_f_e
-
old_f_e;
+
array(string)
removed_fe
=
old_f_e
-
new_f_e
;
+
+
foreach(added_fe,
string
path)
{
+
if(
!has_prefix
(
path
, "/") ||
search(path,
"*")>
=
0
) {
+
write("
Added
unsupported
foreign_ident
:
%s\n",
path
);
return 1; }
-
if (
code=='
-
'
&&
search(files_to_commit
,
fn
)
<0
)
{
-
write("
Removed
foreign_ident
from
unstaged
file %s\n",
fn
);
+
path
=
path[1..];
+
if (
sizeof(run_git("ls
-
tree",
sha+"^",
"--"
,
path
))
||
+
!sizeof(run_git("ls-tree",
sha,
"--", path))) {
+
write("
Added
foreign_ident
to
unadded
file %s\n",
path
);
return 1; } }
-
+
+
foreach(removed_fe, string path) {
+
if(has_prefix(path, "/"))
+
path = path[1..];
+
if (search(files_to_commit, path)<0) {
+
write("Removed foreign_ident from unchanged file %s\n", path);
+
return 1;
} }
-
+
}
return 0; }
419:
write("Checking commit %s\n", sha); array(string) committed_files = split_z(run_git("diff", "--name-only", "-z", sha, sha+"^"));
-
string
attrentry
=
run
_
git
(
"ls-tree",
sha, "
--", "
.gitattributes"
);
-
string attrtext = "";
-
if (sizeof(attrentry)) {
-
string blob;
-
if (2 != sscanf(attrentry
,
"%*o blob %s\t", blob
)
)
-
fail("Unexpected output from git ls-tree\n")
;
-
attrtext = run_git("cat-file", "blob", blob);
-
}
+
string
attrtext
=
get
_
committed_file
(sha, ".gitattributes",
1
);
GitAttributes attrs = GitAttributes(attrtext); return check_blocker_attributes(sha, attrs, committed_files) ||
-
check_gitattributes_files(sha, committed_files);
+
check_gitattributes_files(sha, committed_files
, attrs
);
} int check_push(string old_sha, string new_sha, string ref_name)