mirror of
https://github.com/git/git.git
synced 2026-01-17 14:21:57 +00:00
Often topics that are ready to advance are marked by indenting them before moving. Ignore these changes when comparing.
288 lines
5.5 KiB
Bash
Executable File
288 lines
5.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
accept_rerere="--rerere-autoupdate" generate=no update= diff= edit= stop_at_cut=
|
|
while case "$#,$1" in 0,*) break;; *,-*) ;; esac
|
|
do
|
|
case "$1" in
|
|
-n) accept_rerere= ;;
|
|
-e) edit=t ;;
|
|
-c) stop_at_cut=1 ;;
|
|
-c?*) stop_at_cut=${1#-c} ;;
|
|
-d) update=${2?"diff with what?"}
|
|
diff=yes
|
|
generate=yes
|
|
shift ;;
|
|
-u) update=${2?"update what?"}
|
|
generate=yes
|
|
shift ;;
|
|
*) generate=yes
|
|
break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
annotate_merge () {
|
|
test -f Meta/whats-cooking.txt || return 0
|
|
|
|
perl -e '
|
|
sub wildo_match {
|
|
s/^\s*//;
|
|
if (/^Will (?:\S+ ){0,2}(fast-track|keep|merge|drop|discard|cook|kick|defer|be re-?rolled)[,. ]/ ||
|
|
/^Not urgent/ || /^Not ready/ || /^Waiting for / ||
|
|
/^Needs? / || /^Expecting / || /^May want to /) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
my ($branch) = $ARGV[0];
|
|
my ($in_section, $in_desc);
|
|
my @msg = ();
|
|
while (<STDIN>) {
|
|
chomp;
|
|
if (/^\* $branch /) {
|
|
$in_section = 1;
|
|
next;
|
|
}
|
|
last if (/^[-*\[]/ && $in_section);
|
|
next unless $in_section;
|
|
s/^\s+//;
|
|
if (/^$/) {
|
|
$in_desc = 1;
|
|
}
|
|
next unless ($in_section && $in_desc);
|
|
next if (/Originally merged to '\''next'\'' on ([-0-9]+)/);
|
|
next if (wildo_match($_));
|
|
push @msg, "$_\n";
|
|
}
|
|
|
|
if ($in_section && @msg) {
|
|
open(my $fh, "-|", qw(git cat-file commit HEAD));
|
|
my @original = (<$fh>);
|
|
close $fh;
|
|
my @final;
|
|
$in_section = 0;
|
|
for (@original) {
|
|
if (!$in_section) {
|
|
$in_section = 1 if (/^$/);
|
|
next;
|
|
}
|
|
if (/^Conflicts:$/ && $in_section == 2) {
|
|
$in_section = 3;
|
|
}
|
|
|
|
if ($in_section == 3) {
|
|
$_ = "# $_";
|
|
}
|
|
push @final, $_;
|
|
if (/^$/ && $in_section == 1) {
|
|
push @final, @msg;
|
|
push @final, "\n";
|
|
$in_section = 2;
|
|
}
|
|
}
|
|
open($fh, "|-", qw(git commit --amend -F -));
|
|
print $fh @final;
|
|
close $fh;
|
|
}
|
|
' <Meta/whats-cooking.txt "$1"
|
|
}
|
|
|
|
case "$generate" in
|
|
no)
|
|
accept_rerere () {
|
|
if ! git write-tree 2>/dev/null >/dev/null
|
|
then
|
|
git rerere remaining
|
|
return 1
|
|
else
|
|
EDITOR=: git commit --no-verify
|
|
echo "Accepted previous resolution"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
mark_cut () {
|
|
test -n "$stop_at_cut" && return
|
|
|
|
count_since_last_cut=$(( $count_since_last_cut + 1 ))
|
|
test -z "$prev_cut" && return
|
|
git commit --allow-empty -m "$prev_cut"
|
|
prev_cut=
|
|
}
|
|
|
|
cut_seen=0 prev_cut= count_since_last_cut=0
|
|
while read branch eh
|
|
do
|
|
case "$branch" in '###') cut_seen=$(( $cut_seen + 1 )) ;; esac
|
|
if test -n "$stop_at_cut" && test $stop_at_cut -le $cut_seen
|
|
then
|
|
continue ;# slurp the remainder and skip
|
|
fi
|
|
|
|
case "$branch" in
|
|
'###')
|
|
if test "$count_since_last_cut" = 0
|
|
then
|
|
prev_cut=
|
|
else
|
|
echo >&2 "$branch $eh"
|
|
prev_cut="$branch $eh"
|
|
count_since_last_cut=0
|
|
fi
|
|
continue ;;
|
|
'#'* | '')
|
|
continue ;;
|
|
esac
|
|
|
|
case "$eh" in
|
|
"" | "#"*)
|
|
echo >&2 "* $branch"
|
|
|
|
save=$(git rev-parse --verify HEAD) &&
|
|
tip=$(git rev-parse --verify "$branch^0") &&
|
|
mb=$(git merge-base "$tip" "$save") ||
|
|
exit
|
|
|
|
test "$mb" = "$tip" && continue
|
|
|
|
mark_cut
|
|
|
|
EDITOR=: git merge $accept_rerere --edit "$branch" ||
|
|
accept_rerere ||
|
|
exit
|
|
|
|
annotate_merge "$branch" || exit
|
|
test -z "$edit" ||
|
|
git commit --amend || exit
|
|
|
|
this=$(git rev-parse --verify HEAD)
|
|
if test "$this" = "$save"
|
|
then
|
|
:
|
|
elif git show-ref -q --verify "refs/merge-fix/$branch"
|
|
then
|
|
echo >&2 "Fixing up the merge"
|
|
git cherry-pick --no-commit "refs/merge-fix/$branch" &&
|
|
EDITOR=: git commit --amend -a || exit
|
|
fi
|
|
;;
|
|
pick" "*)
|
|
echo >&2 "* $eh"
|
|
|
|
mark_cut
|
|
|
|
git cherry-pick "$branch" || exit ;;
|
|
*) echo >&2 "Eh? $branch $eh"; exit ;;
|
|
esac
|
|
done
|
|
exit
|
|
esac
|
|
|
|
if test -n "$update" && test $# = 0
|
|
then
|
|
set x $(sed -n -e '2s/^# //p' <"$update") &&
|
|
shift
|
|
fi
|
|
|
|
# Generation (or updating)
|
|
|
|
x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
|
|
x40="$x40$x40$x40$x40$x40$x40$x40$x40"
|
|
LF='
|
|
'
|
|
|
|
show_merge () {
|
|
case "$msg" in
|
|
"Merge branch '"*"'"*)
|
|
branch=$(expr "$msg" : "Merge branch '\(.*\)'")
|
|
merge_hier=heads/
|
|
;;
|
|
"Merge remote branch '"*"'"*)
|
|
branch=$(expr "$msg" : "Merge remote branch '\(.*\)'")
|
|
merge_hier=
|
|
;;
|
|
*)
|
|
echo 2>&1 "Huh?: $msg"
|
|
return
|
|
;;
|
|
esac &&
|
|
tip=$(git rev-parse --verify "refs/$merge_hier$branch" 2>/dev/null) &&
|
|
merged=$(git name-rev --refs="refs/$merge_hier$branch" "$other" 2>/dev/null) &&
|
|
merged=$(expr "$merged" : "$x40 \(.*\)") &&
|
|
test "$merged" != undefined || {
|
|
other=$(git log -1 --pretty='format:%s' $other) &&
|
|
merged="$branch :rebased? $other"
|
|
}
|
|
}
|
|
|
|
show_pick () {
|
|
case "$msg" in
|
|
"### "* | "###")
|
|
merged="$msg"
|
|
;;
|
|
*)
|
|
merged="$(git rev-parse --verify "$commit") pick $msg"
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
generate () {
|
|
PROGRAM=$1
|
|
shift
|
|
echo '#!/bin/sh'
|
|
echo "# $1"
|
|
echo 'case "$#,$1" in'
|
|
echo '1,-u|1,-d)'
|
|
echo " exec $PROGRAM" '"$1" "$0"'
|
|
echo 'esac'
|
|
echo "$PROGRAM" '"$@" <<\EOF'
|
|
git log --no-decorate --pretty=oneline --first-parent "$1" |
|
|
{
|
|
series=
|
|
while read commit msg
|
|
do
|
|
if other=$(git rev-parse -q --verify "$commit^2")
|
|
then
|
|
show_merge
|
|
else
|
|
show_pick
|
|
fi
|
|
|
|
if test -z "$series"
|
|
then
|
|
series="$merged"
|
|
else
|
|
series="$merged$LF$series"
|
|
fi
|
|
done
|
|
echo "$series"
|
|
}
|
|
echo EOF
|
|
}
|
|
|
|
if test -z "$update"
|
|
then
|
|
generate "$0" "$@"
|
|
elif test -z "$diff"
|
|
then
|
|
generate "$0" "$@" | diff -w -u "$update" -
|
|
if test $? = 0
|
|
then
|
|
echo >&2 "No changes."
|
|
else
|
|
echo >&2 -n "Update [y/N]? "
|
|
read yesno
|
|
case "$yesno" in
|
|
[Yy]*)
|
|
generate "$0" "$@" |
|
|
sed -e 's/ :rebased?.*//' >"$update" ;;
|
|
*)
|
|
echo >&2 "No update then." ;;
|
|
esac
|
|
fi
|
|
else
|
|
generate "$0" "$@" | diff -w -u "$update" -
|
|
fi
|