| 514 | } |
| 515 | |
| 516 | static void get_encrypted_files (std::vector<std::string>& files, const char* key_name) |
| 517 | { |
| 518 | // git ls-files -cz -- path_to_top |
| 519 | std::vector<std::string> ls_files_command; |
| 520 | ls_files_command.push_back("git"); |
| 521 | ls_files_command.push_back("ls-files"); |
| 522 | ls_files_command.push_back("-csz"); |
| 523 | ls_files_command.push_back("--"); |
| 524 | const std::string path_to_top(get_path_to_top()); |
| 525 | if (!path_to_top.empty()) { |
| 526 | ls_files_command.push_back(path_to_top); |
| 527 | } |
| 528 | |
| 529 | Coprocess ls_files; |
| 530 | std::istream* ls_files_stdout = ls_files.stdout_pipe(); |
| 531 | ls_files.spawn(ls_files_command); |
| 532 | |
| 533 | Coprocess check_attr; |
| 534 | std::ostream* check_attr_stdin = nullptr; |
| 535 | std::istream* check_attr_stdout = nullptr; |
| 536 | if (git_version() >= make_version(1, 8, 5)) { |
| 537 | // In Git 1.8.5 (released 27 Nov 2013) and higher, we use a single `git check-attr` process |
| 538 | // to get the attributes of all files at once. In prior versions, we have to fork and exec |
| 539 | // a separate `git check-attr` process for each file, since -z and --stdin aren't supported. |
| 540 | // In a repository with thousands of files, this results in an almost 100x speedup. |
| 541 | std::vector<std::string> check_attr_command; |
| 542 | check_attr_command.push_back("git"); |
| 543 | check_attr_command.push_back("check-attr"); |
| 544 | check_attr_command.push_back("--stdin"); |
| 545 | check_attr_command.push_back("-z"); |
| 546 | check_attr_command.push_back("filter"); |
| 547 | check_attr_command.push_back("diff"); |
| 548 | |
| 549 | check_attr_stdin = check_attr.stdin_pipe(); |
| 550 | check_attr_stdout = check_attr.stdout_pipe(); |
| 551 | check_attr.spawn(check_attr_command); |
| 552 | } |
| 553 | |
| 554 | while (ls_files_stdout->peek() != -1) { |
| 555 | std::string mode; |
| 556 | std::string object_id; |
| 557 | std::string stage; |
| 558 | std::string filename; |
| 559 | *ls_files_stdout >> mode >> object_id >> stage >> std::ws; |
| 560 | std::getline(*ls_files_stdout, filename, '\0'); |
| 561 | |
| 562 | if (is_git_file_mode(mode)) { |
| 563 | std::string filter_attribute; |
| 564 | |
| 565 | if (check_attr_stdin) { |
| 566 | filter_attribute = get_file_attributes(filename, *check_attr_stdin, *check_attr_stdout).first; |
| 567 | } else { |
| 568 | filter_attribute = get_file_attributes(filename).first; |
| 569 | } |
| 570 | |
| 571 | if (filter_attribute == attribute_name(key_name)) { |
| 572 | files.push_back(filename); |
| 573 | } |
no test coverage detected