get_ref_dir(): return early if directory cannot be read
[gitweb.git] / git-add--interactive.perl
index 4f08fe704bbaff64613ab07630a71da8bf8bbca0..d948aa88dba11d1d7d87f6a523c698cf4f4848f1 100755 (executable)
@@ -45,6 +45,9 @@
 my $normal_color = $repo->get_color("", "reset");
 
 my $use_readkey = 0;
+my $use_termcap = 0;
+my %term_escapes;
+
 sub ReadMode;
 sub ReadKey;
 if ($repo->config_bool("interactive.singlekey")) {
                Term::ReadKey->import;
                $use_readkey = 1;
        };
+       eval {
+               require Term::Cap;
+               my $termcap = Term::Cap->Tgetent;
+               foreach (values %$termcap) {
+                       $term_escapes{$_} = 1 if /^\e/;
+               }
+               $use_termcap = 1;
+       };
 }
 
 sub colored {
@@ -257,6 +268,7 @@ sub get_empty_tree {
 # FILE:                is file different from index?
 # INDEX_ADDDEL:        is it add/delete between HEAD and index?
 # FILE_ADDDEL: is it add/delete between index and file?
+# UNMERGED:    is the path unmerged
 
 sub list_modified {
        my ($only) = @_;
@@ -307,16 +319,10 @@ sub list_modified {
                }
        }
 
-       for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
+       for (run_cmd_pipe(qw(git diff-files --numstat --summary --raw --), @tracked)) {
                if (($add, $del, $file) =
                    /^([-\d]+)  ([-\d]+)        (.*)/) {
                        $file = unquote_path($file);
-                       if (!exists $data{$file}) {
-                               $data{$file} = +{
-                                       INDEX => 'unchanged',
-                                       BINARY => 0,
-                               };
-                       }
                        my ($change, $bin);
                        if ($add eq '-' && $del eq '-') {
                                $change = 'binary';
@@ -335,6 +341,18 @@ sub list_modified {
                        $file = unquote_path($file);
                        $data{$file}{FILE_ADDDEL} = $adddel;
                }
+               elsif (/^:[0-7]+ [0-7]+ [0-9a-f]+ [0-9a-f]+ (.) (.*)$/) {
+                       $file = unquote_path($2);
+                       if (!exists $data{$file}) {
+                               $data{$file} = +{
+                                       INDEX => 'unchanged',
+                                       BINARY => 0,
+                               };
+                       }
+                       if ($1 eq 'U') {
+                               $data{$file}{UNMERGED} = 1;
+                       }
+               }
        }
 
        for (sort keys %data) {
@@ -1067,6 +1085,14 @@ sub prompt_single_character {
                ReadMode 'cbreak';
                my $key = ReadKey 0;
                ReadMode 'restore';
+               if ($use_termcap and $key eq "\e") {
+                       while (!defined $term_escapes{$key}) {
+                               my $next = ReadKey 0.5;
+                               last if (!defined $next);
+                               $key .= $next;
+                       }
+                       $key =~ s/\e/^[/;
+               }
                print "$key" if defined $key;
                print "\n";
                return $key;
@@ -1171,6 +1197,10 @@ sub apply_patch_for_checkout_commit {
 
 sub patch_update_cmd {
        my @all_mods = list_modified($patch_mode_flavour{FILTER});
+       error_msg "ignoring unmerged: $_->{VALUE}\n"
+               for grep { $_->{UNMERGED} } @all_mods;
+       @all_mods = grep { !$_->{UNMERGED} } @all_mods;
+
        my @mods = grep { !($_->{BINARY}) } @all_mods;
        my @them;