mob: Use 4 decimals in SI output
[sunny256-utils.git] / git-dangling
blobbc5717454b15b219f3c10e740ac62d8e739bc473
1 #!/bin/sh
3 #==============================================================================
4 # git-dangling
5 # File ID: 13613774-3334-11e0-bfdc-fefdb24f8e10
7 # Create branches on every dangling commit
9 # Author: Øyvind A. Holm <sunny@sunbase.org>
10 # License: GNU General Public License version 2 or later.
11 #==============================================================================
13 progname=git-dangling
14 VERSION=0.3.0
16 opt_blobs=0
17 opt_checkpart=0
18 opt_deleteonly=0
19 opt_help=0
20 opt_quiet=0
21 opt_verbose=0
22 while test -n "$1"; do
23 case "$1" in
24 -b|--blobs) opt_blobs=1; shift ;;
25 -c|--check-part) opt_checkpart=1; shift ;;
26 -D|--delete-only) opt_deleteonly=1; shift ;;
27 -h|--help) opt_help=1; shift ;;
28 -q|--quiet) opt_quiet=$(($opt_quiet + 1)); shift ;;
29 -v|--verbose) opt_verbose=$(($opt_verbose + 1)); shift ;;
30 --version) echo $progname $VERSION; exit 0 ;;
31 --) shift; break ;;
33 if printf '%s\n' "$1" | grep -q ^-; then
34 echo "$progname: $1: Unknown option" >&2
35 exit 1
36 else
37 break
39 break ;;
40 esac
41 done
42 opt_verbose=$(($opt_verbose - $opt_quiet))
44 if test "$opt_help" = "1"; then
45 test $opt_verbose -gt 0 && { echo; echo $progname $VERSION; }
46 cat <<END
48 Restore dangling branches, tags or blobs. Branches will be stored as
49 commit-[SHA1], tags as tag-[SHA1] and blobs as blob-[SHA1].
51 Usage: $progname [options]
53 Options:
55 -b, --blobs
56 Store dangling blobs as blob-[SHA1] files.
57 -c, --check-part
58 Check if any commit-* branches are part of any other branch. Does
59 not scan for dangling objects.
60 -D, --delete-only
61 Only delete commit-* branches and tag-* tags, don't check for
62 dangling branches, tags or blobs.
63 -h, --help
64 Show this help.
65 -q, --quiet
66 Be more quiet. Can be repeated to increase silence.
67 -v, --verbose
68 Increase level of verbosity. Can be repeated.
69 --version
70 Print version information.
72 END
73 exit 0
76 bannedfile=$HOME/.git-dangling-banned
77 dangfile=.git/dangling-result.tmp
79 store_blobs=0
80 if test "$opt_blobs" = "1"; then
81 store_blobs=1
84 if test "$opt_checkpart" = "1"; then
85 # Check if commit-* branches are part of any other branch
86 for f in $(git branch | cut -c 3- | grep '^commit-'); do
87 echo ============ $progname: $f
88 git branch -a --contains=$f | grep -v "^ $f\$"
89 done
90 exit
93 if test "$opt_deleteonly" = "1"; then
94 # Delete all commit-* branches
95 git branch | cut -c 3- | grep -E '^commit-[0-9a-f]{40}$' |
96 grep -Ev commit-0{40} | xargs -r git branch -D
98 # Delete all tag-* tags
99 git tag | grep -E '^tag-[0-9a-f]{40}$' | while read f; do
100 git tag -d "$f"
101 done
102 exit
105 cd "$(git rev-parse --show-toplevel)" || {
106 echo $progname: Could not chdir to top level of repo >&2
107 exit 1
109 test -d .git/. || dangfile=$(basename $dangfile)
111 git fsck --no-reflogs >$dangfile
112 for f in `grep "^dangling commit" $dangfile | cut -f 3 -d ' '`; do
113 git branch commit-$f $f && echo $progname: Creating commit-$f
114 done
115 for f in `grep "^dangling tag" $dangfile | cut -f 3 -d ' '`; do
116 git tag tag-$f $f && echo $progname: Creating tag-$f
117 done
118 if test "$store_blobs" = "1"; then
119 for f in `grep "^dangling blob" $dangfile | cut -f 3 -d ' '`; do
120 git show $f >blob-$f && echo $progname: Creating blob-$f
121 done
123 git delete-banned
124 test "$dangfile" = "$(basename $dangfile)" && rm $dangfile
125 exit 0
127 # vim: set ts=8 sw=8 sts=8 noet fo+=w tw=79 fenc=UTF-8 :