#!/usr/bin/env bash # # Get SHA1 ID of commit or tree associated with given ID or HEAD. # Copyright (c) Petr Baudis, Pavel Roskin, Philip Pokorny 2005 # # If the ID is not provided, HEAD is used. The default behavior is to # show the commit ID. # # OPTIONS # ------- # -c:: Get commit ID # Get ID of commit matching the object ID (error out if it is not # a commit). This is the default if you do not pass any parameter # as well, but that is only for the human usage. For clarity, all # scripted usage of cg-object-id should use -c explicitly if it # wants a commit. # # -d:: Get commit string description # Get a commit description in form of a short string. It shows the # most recent tag in past of the commit and if it is not the commit # itself, it appends first few chars of the commit id to id. See # `git-describe`(1) for details. # # -n:: Disable object type checking # Normalize only - don't check the object type. # # -p:: Get parent commit ID(s) # Get ID of the first parent commit of a given revision or HEAD. # NOTE: Multiple SHA1s separated by newlines will be returned for # commits with multiple parents. # # -t:: Get tree ID # Get ID of tree associated with given commit or HEAD. # # OBJECT_ID:: # An ID resolving to a commit. USAGE="cg-object-id [-c | -d | -n | -p | -t] [OBJECT_ID]" . "${COGITO_LIB}"cg-Xlib deprecated_alias cg-object-id commit-id cg-commit-id parent-id cg-parent-id tree-id cg-tree-id # Normalize argument. The normalized SHA1 ID is put to $normid, # type is put to $type. normalize_id() { local id="$1" local revid= local valid= if [ ! "$id" ] || [ "$id" = "this" ]; then id=HEAD; fi revid="$(git-rev-parse --verify "$id" 2>/dev/null)" if [ "$revid" ] && [ ${#revid} -eq 40 ] && [ "${revid//[0-9a-f]/}" = "" ]; then id="$revid" valid=1 fi # date does the wrong thing for empty and single-letter ids if [ ${#id} -gt 1 ] && [ ! "$valid" ]; then reqsecs="$(date --date="$id" +'%s' 2>/dev/null)" if [ "$reqsecs" ]; then revid="$(git-rev-list "--min-age=$reqsecs" --max-count=1 HEAD)" if [ "$revid" ]; then id="$revid" valid=1 fi fi fi # If we don't have a 40-char ID by now, it's an error if [ ! "$valid" ]; then echo "Invalid id: $id" >&2 exit 1 fi type="$(git-cat-file -t "$id")" if [ "$type" = "tag" ]; then id="$(git-cat-file tag "$id" | head -n 1)" id="${id#object }" type= fi normid="$id" } show_commit= # this is really only for the options-exclusivity-checking describe= show_parent= show_tree= normalize_only= while optparse; do if optparse -c; then show_commit=1 elif optparse -d; then describe=1 elif optparse -n; then normalize_only=1 elif optparse -p; then show_parent=1 elif optparse -t; then show_tree=1 else optfail fi done # Compatibility code case "$_cg_cmd" in *parent*) show_parent=1;; *tree*) show_tree=1;; esac case "$show_commit$describe$show_parent$show_tree$normalize_only" in 11*) usage;; esac id="${ARGS[0]}" normalize_id "$id" if [ "$normalize_only" ]; then echo "$normid" exit 0 fi if [ "$describe" ]; then git-describe "$normid" exit 0 fi if [ "$show_parent" ]; then git-cat-file commit "$normid" | awk '/^parent/{print $2};/^$/{exit}' exit 0 fi [ "$type" ] || type="$(git-cat-file -t "$normid")" if [ "$show_tree" ]; then if [ "$type" = "commit" ]; then normid="$(git-cat-file commit "$normid" | sed -e 's/tree //;q')" type="$(git-cat-file -t "$normid")" fi if [ "$type" != "tree" ]; then echo "Invalid tree id: $normid" >&2 exit 1 fi else if [ "$type" != "commit" ]; then echo "Invalid commit id: $normid" >&2 exit 1 fi fi echo "$normid"