send-email: detect and offer to skip backup files

Diligent people save output from format-patch to files, proofread and edit them and then finally send the result out. If the resulting files are sent out with "git send-email 0*", this ends up sending backup files (e.g. 0001-X.patch.backup or 0001-X.patch~) left by their editors next to the final version. Sending them with "git send-email 0*.patch" (if format-patch was run with the standard suffix) would avoid such an embarrassment, but not everybody is careful. After collecting files to be sent (and sorting them if read from a directory), notice when the file being sent out has the same name as the previous file, plus some suffix (e.g. 0001-X.patch was sent, and we are looking at 0001-X.patch.backup or 0001-X.patch~), and the suffix begins with a non-alnum (e.g. ".backup" or "~") and ask if the user really wants to send it out. Once the user skips sending such a "backup" file, remember the suffix and stop asking the same question (e.g. after skipping 0001-X.patch~, skip 0002-Y.patch~ without asking). Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Mar 17, 2016 at 22:40 UTC 531220ba500168bc5a2080df24dfd61705cafa3c
1 file changed +40
git-send-email.perl
+40
@@ -621,6 +621,8 @@ if (@rev_list_opts) {
621 push @files, $repo->command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts);
622 }
623
624 +@files = handle_backup_files(@files);
625 +
626 if ($validate) {
627 foreach my $f (@files) {
628 unless (-p $f) {
@@ -1726,6 +1728,44 @@ sub validate_patch {
1728 return;
1729 }
1730
1731 +sub handle_backup {
1732 + my ($last, $lastlen, $file, $known_suffix) = @_;
1733 + my ($suffix, $skip);
1734 +
1735 + $skip = 0;
1736 + if (defined $last &&
1737 + ($lastlen < length($file)) &&
1738 + (substr($file, 0, $lastlen) eq $last) &&
1739 + ($suffix = substr($file, $lastlen)) !~ /^[a-z0-9]/i) {
1740 + if (defined $known_suffix && $suffix eq $known_suffix) {
1741 + print "Skipping $file with backup suffix '$known_suffix'.\n";
1742 + $skip = 1;
1743 + } else {
1744 + my $answer = ask("Do you really want to send $file? (y|N): ",
1745 + valid_re => qr/^(?:y|n)/i,
1746 + default => 'n');
1747 + $skip = ($answer ne 'y');
1748 + if ($skip) {
1749 + $known_suffix = $suffix;
1750 + }
1751 + }
1752 + }
1753 + return ($skip, $known_suffix);
1754 +}
1755 +
1756 +sub handle_backup_files {
1757 + my @file = @_;
1758 + my ($last, $lastlen, $known_suffix, $skip, @result);
1759 + for my $file (@file) {
1760 + ($skip, $known_suffix) = handle_backup($last, $lastlen,
1761 + $file, $known_suffix);
1762 + push @result, $file unless $skip;
1763 + $last = $file;
1764 + $lastlen = length($file);
1765 + }
1766 + return @result;
1767 +}
1768 +
1769 sub file_has_nonascii {
1770 my $fn = shift;
1771 open(my $fh, '<', $fn)