githelper.git / githelper.pike

version» Context lines:

githelper.git/githelper.pike:534:   }      /* Checks run before accepting a push */      class PreReceiveHook   {    inherit CommitHookUtilsRepo;       static array(string) commits_to_check = ({});    -  int check_tag_push(string old_sha, string new_sha, string ref_name) +  int check_access(string ref_name, string user)    { -  +  /* Return 0 for no access, 1 for basic access, and 2 for full +  access (including rebase/delete branch, and move/delete tag) */ +  string shortref = ref_name; +  sscanf(shortref, "refs/%*[^/]/%s", shortref); +  if (has_prefix(shortref, "scratch/") || has_prefix(shortref, user+"/")) +  return 2; +  if (search(ref_name, "/x-") >= 0) { +  write("The ref %s can only be modified by its owner\n", ref_name); +  return 0; +  } +  return 1; +  } +  +  int check_tag_push(string old_sha, string new_sha, string ref_name, +  int access_level) +  { +  if (access_level >= 2) +  return 0; +     string oldtag =    String.trim_all_whites(run_git_ex(1, "rev-parse", "--verify",    "-q", ref_name));    if (sizeof(oldtag) && oldtag != new_sha) { -  write("Tag %s already exists with value %s, will not move it\n", -  ref_name, oldtag); +  write("Tag %s already exists with value %s, will not %s it\n", +  ref_name, oldtag, (new_sha == "0"*40? "delete":"move"));    return 1;    }    -  +  if (!sizeof(oldtag) && search(ref_name[10..], "/") >= 0) { +  write("Common tags are not allowed to contain /.\n"); +  return 1; +  } +     return 0;    }    -  int check_branch_push(string old_sha, string new_sha, string ref_name) +  int check_branch_push(string old_sha, string new_sha, string ref_name, +  int access_level)    {    if (old_sha == "0"*40) { -  // New branch, maybe check if the name is allowed... +  // New branch, check if the name is allowed... +  if (sscanf(ref_name, "refs/heads/%*[0-9.]%*c") < 2) { +  write("Main version branches can not be created remotely.\n"); +  return 1; +  } +  if (access_level < 2 && search(ref_name[11..], "/")>=0) { +  write("Common topic branch names are not allowed to contain /.\n"); +  return 1; +  }    return 0; -  +  } else if (new_sha == "0"*40) { +  // Delete old branch +  if (access_level < 2) { +  write("You may not delete branches which do not belong to you.\n"); +  return 1; +  } +  return 0;    } else { -  +  if (access_level >= 2) +  /* Skip checks */ +  return 0; +     string merge_base =    String.trim_all_whites(run_git("merge-base", old_sha, new_sha));    if (merge_base != old_sha) {    write("Push to %s is not fast-forward.\n", ref_name);    return 1;    }    array(string) fp_path = split_lf(run_git("rev-list", "--first-parent",    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));    return 0;    }    }       int check_push(string old_sha, string new_sha, string ref_name)    { -  +  string git_user = getenv("GIT_USER")||getenv("USER")||"nobody"; +  int access_level; +  if(!(access_level = check_access(ref_name, git_user))) return 1;    if (has_prefix(ref_name, "refs/tags/")) { -  return check_tag_push(old_sha, new_sha, ref_name); +  return check_tag_push(old_sha, new_sha, ref_name, access_level);    } else if (has_prefix(ref_name, "refs/heads/")) { -  return check_branch_push(old_sha, new_sha, ref_name); +  return check_branch_push(old_sha, new_sha, ref_name, access_level);    } else {    write("Trying to push a ref which is neither under refs/tags/ or refs/heads/...\n");    return 1;    }    }       int hook()    {    foreach(split_lf(Stdio.stdin->read()), string line) {    array(string) args = line / " ";