We need only to consider newly added dependencies. For each of these deps we need to check if there is a path from this dep to the current HEAD. We use recursive_dep() for this task. Even if recursive_dep() uses a DFS traversal it will not run into an endless loop if there would be a cycle, because recursive_dep() takes .topdeps only from committed trees. And we require that the committed dependency graph has no cycles. Signed-off-by: Bert Wesarg <bert.wesarg@xxxxxxxxxxxxxx> --- Note, the dependency on bw/tred is only historical, it only depends on master. hooks/pre-commit.sh | 35 +++++++++++++++++++++++++++++++++-- 1 files changed, 33 insertions(+), 2 deletions(-) diff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh index 9d677e9..fd960a4 100644 hooks/pre-commit.sh --- a/hooks/pre-commit.sh +++ b/hooks/pre-commit.sh @@ -20,7 +20,8 @@ tg_util if head_=$(git symbolic-ref -q HEAD); then case "$head_" in refs/heads/*) - git rev-parse -q --verify "refs/top-bases${head_#refs/heads}" >/dev/null || exit 0;; + head_="${head_#refs/heads/}" + git rev-parse -q --verify "refs/top-bases/$head_" >/dev/null || exit 0;; *) exit 0;; esac @@ -35,4 +36,34 @@ fi [ -s "$root_dir/.topmsg" ] || die ".topmsg is missing" -# TODO: Verify .topdeps for valid branch names and against cycles +check_cycle_name() +{ + [ "$head_" != "$_dep" ] || + die "TopGit dependencies form a cycle: perpetrator is $_name" +} + +# we only need to check newly added deps and for these if a path exists to the +# current HEAD +git diff --cached "$root_dir/.topdeps" | + awk ' +BEGIN { in_hunk = 0; } +/^@@ / { in_hunk = 1; } +/^\+/ { if (in_hunk == 1) printf("%s\n", substr($0, 2)); } +/^[^@ +-]/ { in_hunk = 0; } +' | + while read newly_added; do + # check for self as dep + [ "$head_" != "$newly_added" ] || + die "Can't have myself as dep" + + # deps can be non-tgish but we can't run recurse_deps() on them + ref_exists "refs/top-bases/$newly_added" || + continue + + # recurse_deps uses dfs but takes the .topdeps from the tree, + # therefore no endless loop in the cycle-check + no_remotes=1 recurse_deps check_cycle_name "$newly_added" + done + + +# TODO: Verify .topdeps for valid branch names -- tg: (550c37a..) bw/check-for-dep-cycle (depends on: bw/tred) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html