contrib: remove "git-resurrect.sh"

The "git-resurrect.sh" script can be used to find traces of a branch tip in the reflog and resurrect that branch. Despite a couple of global cleanups, the script hasn't seen any activity since it was introduced in e1ff064e1bf (contrib git-resurrect: find traces of a branch name and resurrect it, 2009-02-04). Furthermore, the tool does not work with the "reftable" backend at all as it directly reads ".git/logs/HEAD". As reflogs are stored as part of the individual tables though that file wouldn't exist in a "reftable"- enabled repository. Last but not least, the tool doesn't even work unless it is explicitly invoked via `git resurrect` as it sources "git-sh-setup". As none of our build systems know to install this script, users thus have to go out of their way to really make it work, which is highly unlikely. Another source that indicates that this tool can be removed is a question for how to restore deleted branches on StackOverflow [1]. The top-voted answer uses git-reflog(1) directly and has received more than 3000 votes to date. While "git-resurrect.sh" is also mentioned, it only got 16 upvotes, and comments mention the above caveat that users have to do some manual setup to make it work. It's thus rather clear that the tool doesn't have a lot or even any users. Remove it. [1]: https://stackoverflow.com/questions/3640764/can-i-recover-a-branch-after-its-deletion-in-git Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 12, 2025 at 11:19 UTC bb9a9297d708827151442cba4d9f39eeede245a4
1 file changed -181
contrib/git-resurrect.sh deleted
-181
@@ -1,181 +0,0 @@
1 -#!/bin/sh
2 -
3 -USAGE="[-a] [-r] [-m] [-t] [-n] [-b <newname>] <name>"
4 -LONG_USAGE="git-resurrect attempts to find traces of a branch tip
5 -called <name>, and tries to resurrect it. Currently, the reflog is
6 -searched for checkout messages, and with -r also merge messages. With
7 --m and -t, the history of all refs is scanned for Merge <name> into
8 -other/Merge <other> into <name> (respectively) commit subjects, which
9 -is rather slow but allows you to resurrect other people's topic
10 -branches."
11 -
12 -OPTIONS_KEEPDASHDASH=
13 -OPTIONS_STUCKLONG=
14 -OPTIONS_SPEC="\
15 -git resurrect $USAGE
16 ---
17 -b,branch= save branch as <newname> instead of <name>
18 -a,all same as -l -r -m -t
19 -k,keep-going full rev-list scan (instead of first match)
20 -l,reflog scan reflog for checkouts (enabled by default)
21 -r,reflog-merges scan for merges recorded in reflog
22 -m,merges scan for merges into other branches (slow)
23 -t,merge-targets scan for merges of other branches into <name>
24 -n,dry-run don't recreate the branch"
25 -
26 -. git-sh-setup
27 -
28 -search_reflog () {
29 - sed -ne 's~^\([^ ]*\) .* checkout: moving from '"$1"' .*~\1~p' \
30 - < "$GIT_DIR"/logs/HEAD
31 -}
32 -
33 -search_reflog_merges () {
34 - git rev-parse $(
35 - sed -ne 's~^[^ ]* \([^ ]*\) .* merge '"$1"':.*~\1^2~p' \
36 - < "$GIT_DIR"/logs/HEAD
37 - )
38 -}
39 -
40 -oid_pattern=$(git hash-object --stdin </dev/null | sed -e 's/./[0-9a-f]/g')
41 -
42 -search_merges () {
43 - git rev-list --all --grep="Merge branch '$1'" \
44 - --pretty=tformat:"%P %s" |
45 - sed -ne "/^$oid_pattern \($oid_pattern\) Merge .*/ {s//\1/p;$early_exit}"
46 -}
47 -
48 -search_merge_targets () {
49 - git rev-list --all --grep="Merge branch '[^']*' into $branch\$" \
50 - --pretty=tformat:"%H %s" --all |
51 - sed -ne "/^\($oid_pattern\) Merge .*/ {s//\1/p;$early_exit} "
52 -}
53 -
54 -dry_run=
55 -early_exit=q
56 -scan_reflog=t
57 -scan_reflog_merges=
58 -scan_merges=
59 -scan_merge_targets=
60 -new_name=
61 -
62 -while test "$#" != 0; do
63 - case "$1" in
64 - -b|--branch)
65 - shift
66 - new_name="$1"
67 - ;;
68 - -n|--dry-run)
69 - dry_run=t
70 - ;;
71 - --no-dry-run)
72 - dry_run=
73 - ;;
74 - -k|--keep-going)
75 - early_exit=
76 - ;;
77 - --no-keep-going)
78 - early_exit=q
79 - ;;
80 - -m|--merges)
81 - scan_merges=t
82 - ;;
83 - --no-merges)
84 - scan_merges=
85 - ;;
86 - -l|--reflog)
87 - scan_reflog=t
88 - ;;
89 - --no-reflog)
90 - scan_reflog=
91 - ;;
92 - -r|--reflog_merges)
93 - scan_reflog_merges=t
94 - ;;
95 - --no-reflog_merges)
96 - scan_reflog_merges=
97 - ;;
98 - -t|--merge-targets)
99 - scan_merge_targets=t
100 - ;;
101 - --no-merge-targets)
102 - scan_merge_targets=
103 - ;;
104 - -a|--all)
105 - scan_reflog=t
106 - scan_reflog_merges=t
107 - scan_merges=t
108 - scan_merge_targets=t
109 - ;;
110 - --)
111 - shift
112 - break
113 - ;;
114 - *)
115 - usage
116 - ;;
117 - esac
118 - shift
119 -done
120 -
121 -test "$#" = 1 || usage
122 -
123 -all_strategies="$scan_reflog$scan_reflog_merges$scan_merges$scan_merge_targets"
124 -if test -z "$all_strategies"; then
125 - die "must enable at least one of -lrmt"
126 -fi
127 -
128 -branch="$1"
129 -test -z "$new_name" && new_name="$branch"
130 -
131 -if test ! -z "$scan_reflog"; then
132 - if test -r "$GIT_DIR"/logs/HEAD; then
133 - candidates="$(search_reflog $branch)"
134 - else
135 - die 'reflog scanning requested, but' \
136 - '$GIT_DIR/logs/HEAD not readable'
137 - fi
138 -fi
139 -if test ! -z "$scan_reflog_merges"; then
140 - if test -r "$GIT_DIR"/logs/HEAD; then
141 - candidates="$candidates $(search_reflog_merges $branch)"
142 - else
143 - die 'reflog scanning requested, but' \
144 - '$GIT_DIR/logs/HEAD not readable'
145 - fi
146 -fi
147 -if test ! -z "$scan_merges"; then
148 - candidates="$candidates $(search_merges $branch)"
149 -fi
150 -if test ! -z "$scan_merge_targets"; then
151 - candidates="$candidates $(search_merge_targets $branch)"
152 -fi
153 -
154 -candidates="$(git rev-parse $candidates | sort -u)"
155 -
156 -if test -z "$candidates"; then
157 - hint=
158 - test "z$all_strategies" != "ztttt" \
159 - && hint=" (maybe try again with -a)"
160 - die "no candidates for $branch found$hint"
161 -fi
162 -
163 -echo "** Candidates for $branch **"
164 -for cmt in $candidates; do
165 - git --no-pager log --pretty=tformat:"%ct:%h [%cr] %s" --abbrev-commit -1 $cmt
166 -done \
167 -| sort -n | cut -d: -f2-
168 -
169 -newest="$(git rev-list -1 $candidates)"
170 -if test ! -z "$dry_run"; then
171 - printf "** Most recent: "
172 - git --no-pager log -1 --pretty=tformat:"%h %s" $newest
173 -elif ! git rev-parse --verify --quiet $new_name >/dev/null; then
174 - printf "** Restoring $new_name to "
175 - git --no-pager log -1 --pretty=tformat:"%h %s" $newest
176 - git branch $new_name $newest
177 -else
178 - printf "Most recent: "
179 - git --no-pager log -1 --pretty=tformat:"%h %s" $newest
180 - echo "** $new_name already exists, doing nothing"
181 -fi