|
19 | 19 | { |
20 | 20 | key = "S"; |
21 | 21 | context = "commits"; |
22 | | - command = '' |
23 | | - /bin/sh -lc ' |
| 22 | + command = /* Bash */ '' |
24 | 23 | set -eu |
25 | 24 |
|
26 | | - rc=0 |
27 | | - oldest="$( |
28 | | - git log --reverse --format="%H%x09%s" HEAD | awk -F "\t" " |
29 | | - BEGIN { fixupCount = 0; resolvedCount = 0; nextIdx = 0; } |
30 | | - { |
31 | | - sha = \$1; |
32 | | - subject = \$2; |
33 | | - if (subject ~ /^(fixup! |squash! )/) { |
34 | | - fixupCount++; |
35 | | - targetSubject = subject; |
36 | | - sub(/^(fixup! |squash! )/, \"\", targetSubject); |
37 | | - targetSha = latest[targetSubject]; |
38 | | - if (targetSha != \"\") { |
39 | | - resolvedCount++; |
40 | | - used[targetSha] = 1; |
41 | | - } |
42 | | - } else { |
43 | | - nextIdx++; |
44 | | - idx[sha] = nextIdx; |
45 | | - latest[subject] = sha; |
46 | | - } |
47 | | - } |
48 | | - END { |
49 | | - if (fixupCount == 0) exit 2; |
50 | | - if (resolvedCount == 0) exit 3; |
51 | | - oldestSha = \"\"; |
52 | | - oldestIdx = 0; |
53 | | - for (sha in used) { |
54 | | - if (oldestSha == \"\" || idx[sha] < oldestIdx) { |
55 | | - oldestSha = sha; |
56 | | - oldestIdx = idx[sha]; |
57 | | - } |
58 | | - } |
59 | | - if (oldestSha == \"\") exit 4; |
60 | | - print oldestSha; |
61 | | - } |
62 | | - " |
63 | | - )" || rc=$? |
| 25 | + if ! git rev-parse --verify HEAD >/dev/null 2>&1; then |
| 26 | + echo "No commits found on this branch." |
| 27 | + exit 1 |
| 28 | + fi |
| 29 | +
|
| 30 | + workDir="''${TMPDIR:-/tmp}/lazygit-autosquash-$$" |
| 31 | + rm -rf "$workDir" |
| 32 | + mkdir -p "$workDir" |
| 33 | + trap 'rm -rf "$workDir"' EXIT HUP INT TERM |
| 34 | +
|
| 35 | + historyFile="$workDir/history" |
| 36 | + latestFile="$workDir/latest" |
| 37 | + orderFile="$workDir/order" |
| 38 | + usedFile="$workDir/used" |
| 39 | + tab="$(printf '\t')" |
| 40 | +
|
| 41 | + : > "$latestFile" |
| 42 | + : > "$orderFile" |
| 43 | + : > "$usedFile" |
| 44 | +
|
| 45 | + git --no-pager log --reverse --format='%H%x09%s' HEAD > "$historyFile" |
| 46 | +
|
| 47 | + fixupCount=0 |
| 48 | + resolvedCount=0 |
| 49 | +
|
| 50 | + while IFS= read -r line; do |
| 51 | + sha="''${line%%"$tab"*}" |
| 52 | + subject="''${line#*"$tab"}" |
| 53 | +
|
| 54 | + case "$subject" in |
| 55 | + "fixup! "*) |
| 56 | + fixupCount=$((fixupCount + 1)) |
| 57 | + targetSubject="''${subject#fixup! }" |
| 58 | + ;; |
| 59 | + "squash! "*) |
| 60 | + fixupCount=$((fixupCount + 1)) |
| 61 | + targetSubject="''${subject#squash! }" |
| 62 | + ;; |
| 63 | + *) |
| 64 | + printf '%s\t%s\n' "$sha" "$subject" >> "$latestFile" |
| 65 | + printf '%s\n' "$sha" >> "$orderFile" |
| 66 | + continue |
| 67 | + ;; |
| 68 | + esac |
64 | 69 |
|
65 | | - if [ "$rc" -eq 2 ]; then |
| 70 | + targetSha="" |
| 71 | + while IFS= read -r entry; do |
| 72 | + entrySha="''${entry%%"$tab"*}" |
| 73 | + entrySubject="''${entry#*"$tab"}" |
| 74 | +
|
| 75 | + if [ "$entrySubject" = "$targetSubject" ]; then |
| 76 | + targetSha="$entrySha" |
| 77 | + fi |
| 78 | + done < "$latestFile" |
| 79 | +
|
| 80 | + if [ -n "$targetSha" ]; then |
| 81 | + resolvedCount=$((resolvedCount + 1)) |
| 82 | + printf '%s\n' "$targetSha" >> "$usedFile" |
| 83 | + fi |
| 84 | + done < "$historyFile" |
| 85 | +
|
| 86 | + if [ "$fixupCount" -eq 0 ]; then |
66 | 87 | echo "No fixup!/squash! commits found on this branch." |
67 | 88 | exit 1 |
68 | | - elif [ "$rc" -eq 3 ]; then |
| 89 | + fi |
| 90 | +
|
| 91 | + if [ "$resolvedCount" -eq 0 ]; then |
69 | 92 | echo "Found fixup!/squash! commits, but could not resolve target commits." |
70 | 93 | exit 1 |
71 | | - elif [ "$rc" -ne 0 ] || [ -z "$oldest" ]; then |
72 | | - echo "Unable to determine oldest target commit." |
| 94 | + fi |
| 95 | +
|
| 96 | + oldestTargetSha="" |
| 97 | + while IFS= read -r candidateSha; do |
| 98 | + targetUsed=0 |
| 99 | +
|
| 100 | + while IFS= read -r usedSha; do |
| 101 | + if [ "$usedSha" = "$candidateSha" ]; then |
| 102 | + targetUsed=1 |
| 103 | + break |
| 104 | + fi |
| 105 | + done < "$usedFile" |
| 106 | +
|
| 107 | + if [ "$targetUsed" -eq 1 ]; then |
| 108 | + oldestTargetSha="$candidateSha" |
| 109 | + break |
| 110 | + fi |
| 111 | + done < "$orderFile" |
| 112 | +
|
| 113 | + if [ -z "$oldestTargetSha" ]; then |
| 114 | + echo "Unable to determine the oldest fixup target commit." |
73 | 115 | exit 1 |
74 | 116 | fi |
75 | 117 |
|
76 | | - GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash --no-verify "$oldest^" |
77 | | - ' |
| 118 | + if git rev-parse --verify "$oldestTargetSha^" >/dev/null 2>&1; then |
| 119 | + GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash --no-verify "$oldestTargetSha^" |
| 120 | + else |
| 121 | + GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash --no-verify --root |
| 122 | + fi |
78 | 123 | ''; |
79 | 124 | description = "Autosquash all fixup/squash commits (auto-detect oldest target, skip hooks)"; |
80 | 125 | loadingText = "Autosquashing fixup commits..."; |
|
0 commit comments