githelper.git
/
githelper.pike
version
»
Context lines:
10
20
40
80
file
none
3
githelper.git/githelper.pike:352:
GitAttributes attrs; private string git_dir; string get_git_dir() { return git_dir || (git_dir = String.trim_all_whites(run_git("rev-parse", "--git-dir"))); }
+
class Plugin
+
{
+
optional string check_message_body(string sha, array(string) headers,
+
string body);
+
+
optional int(0..1) check_commit(string branch, string sha,
+
array(string) paths);
+
}
+
+
Plugin plugin;
+
+
#ifdef COMMIT_PLUGIN
+
private class PluginHandler
+
{
+
mixed resolv(string symbol, string file)
+
{
+
switch(symbol) {
+
case "get_git_dir": return get_git_dir;
+
}
+
return master()->resolv(symbol, file);
+
}
+
}
+
+
private PluginHandler plugin_handler = PluginHandler();
+
+
protected void create()
+
{
+
string plugin_path = combine_path(get_git_dir(),
+
"hooks/githelper-plugins",
+
COMMIT_PLUGIN);
+
if (Stdio.exist(plugin_path)) {
+
program(Plugin) plugin_program =
+
compile_file(plugin_path, plugin_handler);
+
plugin = plugin_program();
+
} else {
+
write("NOTICE: Plugin %s not found.\n", plugin_path);
+
write("You may want to reinstall githelper.\n");
+
}
+
}
+
#endif
+
string get_file(string filename, int|void allow_empty); string get_old_file(string filename, int|void allow_empty); int entry_is_new(string filename) { return 0; } int find_expanded_ident(string data) { int p=0; while ((p = search(data, DOLLAR"Id", p))>=0) { if (data[p..p+3] != unexpanded_id) { int p2 = search(data, DOLLAR, p+3), p3 = search(data, "\n", p+3);
githelper.git/githelper.pike:471:
} } class CommitHookUtilsRepo { inherit CommitHookUtils; protected string sha; protected string parent;
+
protected mapping(string:array(string)) commit_paths = ([]);
+
string get_file(string filename, int|void allow_empty) { return get_committed_file(sha, filename, allow_empty); } string get_old_file(string filename, int|void allow_empty) { return get_committed_file(parent, filename, allow_empty); }
githelper.git/githelper.pike:492:
{ return (!sizeof(run_git("ls-tree", parent, "--", filename))) && sizeof(run_git("ls-tree", sha, "--", filename)); } string check_commit_msg(string commit) { string message = run_git("cat-file", "commit", commit); string encoding = 0; string headers = (message/"\n\n")[0];
+
string body = (message/"\n\n")[1..]*"\n\n";
foreach(headers/"\n", string headerline) { if(has_prefix(headerline, "encoding ")) encoding = headerline[9..]; }
-
return
check_encoding(message, encoding);
+
string
msg =
check_encoding(message, encoding);
+
+
if (msg) return msg;
+
+
if (plugin && plugin->check_message_body) {
+
return plugin->check_message_body(commit, headers/"\n", body);
}
-
+
return 0;
+
}
+
int check_commit(string sha) { if (!has_prefix(sha, "HEAD")) write("Checking commit %s\n", sha); this_program::sha = sha; array(string) parents = split_lf(run_git("rev-list", "--parents", "-n", "1", sha))[0] / " "; if (sizeof(parents) > 1) parent = parents[1]; // First parent, sha^ else parent = String.trim_all_whites(run_git("hash-object", "-t", "tree", "/dev/null")); // Empty tree
-
files_to_commit =
+
commit_paths[sha] =
files_to_commit =
split_z(run_git("diff", "--name-only", "-z", sha, parent)); attrs = GitAttributes(get_file(".gitattributes", 1)); string ts_test = check_commit_timestamps(sha); int err = 0; if (ts_test) { write("Invalid timestamps: %s\n", ts_test); err = 1; } string cm_test = check_commit_msg(sha); if (cm_test) {
githelper.git/githelper.pike:618:
ACCESS_EXISTING = 3, // May be updated to any previously existing commit. ACCESS_FULL = 4, // rebase/delete branch, move/delete tag, etc. }; protected mapping(string:AccessLevel) groups = ([ "scratch": ACCESS_FULL, ]); protected array(string) commits_to_check = ({});
+
protected mapping(string:array(string)) branch_commits = ([]);
+
protected void parse_groups(string user) { string git_dir = get_git_dir(); groups[user] = ACCESS_FULL; groups["tracking"] = ACCESS_EXISTING; string group_data = Stdio.read_bytes(combine_path(git_dir, "info/group")); if (!group_data) return;
githelper.git/githelper.pike:751:
"-n", "2", old_sha)); array(string) fp_path = split_lf(run_git("rev-list", "--first-parent", (sizeof(old_depth)<2? new_sha : old_sha+"^.."+new_sha))); if (search(fp_path, old_sha)<0) { write("Commit %s does not contain %s in its first-parent ancestry.\nDid you pull with merge instead of rebase?\n", new_sha, old_sha); return 1; }
-
commits
_to_check
+
= split_lf(run_git("rev-list", old_sha+".."+new_sha));
+
array(string)
commits =
+
reverse(
split_lf(run_git("rev-list", old_sha+".."+new_sha))
)
;
+
+
branch_commits[ref_name] += commits;
+
commits_to_check += commits;
return 0; } } int check_push(string git_user, string old_sha, string new_sha, string ref_name) { AccessLevel access_level; if(!(access_level = check_access(ref_name, git_user))) return 1; if (has_prefix(ref_name, "refs/tags/")) {
githelper.git/githelper.pike:785:
foreach(split_lf(Stdio.stdin->read()), string line) { array(string) args = line / " "; if(sizeof(args) != 3) fail("Unexpected input line to pre-receive hook: %s\n", line); if(check_push(git_user, @args)) return 1; } foreach(Array.uniq(commits_to_check), string sha) if(check_commit(sha)) return 1;
+
+
if (plugin && plugin->check_commit) {
+
foreach(sort(indices(branch_commits)), string branch) {
+
foreach(branch_commits[branch], string sha) {
+
if (plugin->check_commit(branch, sha, commit_paths[sha])) {
+
return 1;
+
}
+
}
+
}
+
}
+
return 0; } } /* Do housekeeping after a commit */ class PostCommitHook { inherit CommitHookUtilsRepo;