cogito: understand permissions written as "100755"
[cogito.git] / cg-object-id
blob2283bcde1b4d26a55b23cd4e24e70d9ec7f2da72
1 #!/usr/bin/env bash
3 # Get the SHA1 id of an object associated with the given symbolic id
4 # Copyright (c) Petr Baudis, Pavel Roskin, Philip Pokorny 2005
6 # Resolves a given symbolic id to the raw SHA1 id (or a symbolic
7 # description when passed the '-d' parameter). The symbolic id can be
8 # an SHA1 id, a unique starting segment of an existing SHA1 id, a ref
9 # name, date, empty string, etc. See the 'COMMIT_ID' description in
10 # cogito(7) for the full list.
12 # Normally, you do not use this command directly (except with the '-d'
13 # parameter), but it is used in other Cogito scripts to resolve passed
14 # object identifiers. If the ID is not provided, HEAD is assumed. The
15 # default behavior is to show the commit ID, but you should always
16 # explicitly write '-c' if using this in a script.
18 # OPTIONS
19 # -------
20 # -b:: Get branch name
21 # Get name of the current branch.
23 # -c:: Get commit ID
24 # Get ID of commit matching the object ID (error out if it is not
25 # a commit). This is the default if you do not pass any parameter
26 # as well, but that is only for the human usage. For clarity, all
27 # scripted usage of cg-object-id should use -c explicitly if it
28 # wants a commit.
30 # -d:: Get commit string description
31 # Get a commit description in form of a short string. It shows the
32 # most recent tag in past of the commit and if it is not the commit
33 # itself, it appends first few chars of the commit id to id. See
34 # `git-describe`(1) for details.
36 # -n:: Disable object type checking
37 # Normalize only - don't check the object type.
39 # -p:: Get parent commit ID(s)
40 # Get ID of the first parent commit of a given revision or HEAD.
41 # NOTE: Multiple SHA1s separated by newlines will be returned for
42 # commits with multiple parents.
44 # -t:: Get tree ID
45 # Get ID of tree associated with given commit or HEAD.
47 # OBJECT_ID::
48 # An ID resolving to a commit.
50 # Testsuite: Partial (used in many tests but a dedicated testsuite is missing)
52 USAGE="cg-object-id [-b | -c | -d | -n | -p | -t] [OBJECT_ID]"
53 _git_wc_unneeded=1
55 . "${COGITO_LIB}"cg-Xlib
58 # Normalize argument. The normalized SHA1 ID is put to $normid,
59 # type is put to $type.
60 normalize_id()
62 local id="$1"
63 local revid=
64 local valid=
66 if [ ! "$id" ] || [ "$id" = "this" ]; then
67 id=HEAD;
70 revid="$(git-rev-parse --verify "$id" 2>/dev/null)"
71 if [ "$revid" ] && [ ${#revid} -eq 40 ] && [ "${revid//[0-9a-f]/}" = "" ]; then
72 id="$revid"
73 valid=1
76 # date does the wrong thing for empty and single-letter ids
77 if [ ${#id} -gt 1 ] && [ ! "$valid" ]; then
78 reqsecs="$(date --date="$id" +'%s' 2>/dev/null)"
80 if [ "$reqsecs" ]; then
81 revid="$(git-rev-list "--min-age=$reqsecs" --max-count=1 HEAD)"
82 if [ "$revid" ]; then
83 id="$revid"
84 valid=1
89 # If we don't have a 40-char ID by now, it's an error
90 if [ ! "$valid" ]; then
91 echo "Invalid id: $id" >&2
92 exit 1
95 type="$(git-cat-file -t "$id")"
96 if [ "$type" = "tag" ]; then
97 id="$(git-cat-file tag "$id" | head -n 1)"
98 id="${id#object }"
99 type=
102 normid="$id"
107 show_commit= # this is really only for the options-exclusivity-checking
108 describe=
109 show_parent=
110 show_tree=
111 normalize_only=
112 while optparse; do
113 if optparse -b; then
114 # one-shot
115 echo "$_git_head"
116 exit
117 elif optparse -c; then
118 show_commit=1
119 elif optparse -d; then
120 describe=1
121 elif optparse -n; then
122 normalize_only=1
123 elif optparse -p; then
124 show_parent=1
125 elif optparse -t; then
126 show_tree=1
127 else
128 optfail
130 done
132 # Compatibility code
133 case "$_cg_cmd" in
134 *parent*) show_parent=1;;
135 *tree*) show_tree=1;;
136 esac
138 case "$show_commit$describe$show_parent$show_tree$normalize_only" in
139 11*) usage;;
140 esac
142 id="${ARGS[0]}"
143 normalize_id "$id"
145 if [ "$normalize_only" ]; then
146 echo "$normid"
147 exit 0
149 if [ "$describe" ]; then
150 git-describe "$normid"
151 exit 0
155 if [ "$show_parent" ]; then
156 git-rev-list --parents -n 1 "$normid" | tr ' ' '\n' | tail -n +2
157 exit 0
160 [ "$type" ] || type="$(git-cat-file -t "$normid")"
161 if [ "$show_tree" ]; then
162 if [ "$type" = "commit" ]; then
163 normid="$(git-cat-file commit "$normid" | sed -e 's/tree //;q')"
164 type="$(git-cat-file -t "$normid")"
167 if [ "$type" != "tree" ]; then
168 echo "Invalid tree id: $normid" >&2
169 exit 1
171 else
172 if [ "$type" != "commit" ]; then
173 echo "Invalid commit id: $normid" >&2
174 exit 1
178 echo "$normid"