diff --git a/build b/build index 8f0892f2..7adae0a9 100755 --- a/build +++ b/build @@ -275,7 +275,14 @@ if [ ! -e "$libgit2_tarball" ]; then fi fi libgit2_url=https://github.com/romkatv/libgit2/archive/"$libgit2_version".tar.gz - command wget -O "$libgit2_tmp" -- "$libgit2_url" + if ! command wget -O "$libgit2_tmp" -- "$libgit2_url"; then + command which wget + command ls -lAd -- "$outdir" + command ls -lA -- "$outdir" + command ls -lAd -- "$outdir"/deps + command ls -lA -- "$outdir"/deps + exit 1 + fi command mv -f -- "$libgit2_tmp" "$libgit2_tarball" else >&2 echo "[error] file not found: deps/libgit2-"$libgit2_version".tar.gz" diff --git a/gitstatus.prompt.sh b/gitstatus.prompt.sh index f27bcc39..8ee28de0 100644 --- a/gitstatus.prompt.sh +++ b/gitstatus.prompt.sh @@ -86,6 +86,7 @@ gitstatus_stop && gitstatus_start -s -1 -u -1 -c -1 -d -1 # On every prompt, fetch git status and set GITSTATUS_PROMPT. PROMPT_COMMAND=gitstatus_prompt_update +PROMPT_DIRTRIM=3 # Enable promptvars so that ${GITSTATUS_PROMPT} in PS1 is expanded. shopt -s promptvars diff --git a/src/dir.cc b/src/dir.cc index e7ce7141..39cf1c2c 100644 --- a/src/dir.cc +++ b/src/dir.cc @@ -106,14 +106,14 @@ bool ListDir(int dir_fd, Arena& arena, std::vector& entries, bool precomp }; constexpr size_t kBufSize = 8 << 10; - entries.clear(); + const size_t orig_size = entries.size(); while (true) { char* buf = static_cast(arena.Allocate(kBufSize, alignof(linux_dirent64))); // Save 256 bytes for the rainy day. int n = syscall(SYS_getdents64, dir_fd, buf, kBufSize - 256); if (n < 0) { - entries.clear(); + entries.resize(orig_size); return false; } for (int pos = 0; pos < n;) { @@ -131,9 +131,9 @@ bool ListDir(int dir_fd, Arena& arena, std::vector& entries, bool precomp } if (case_sensitive) { - SortEntries(entries.data(), entries.data() + entries.size()); + SortEntries(entries.data() + orig_size, entries.data() + entries.size()); } else { - SortEntries(entries.data(), entries.data() + entries.size()); + SortEntries(entries.data() + orig_size, entries.data() + entries.size()); } return true; @@ -211,7 +211,7 @@ char* DirenvConvert(Arena& arena, struct dirent& ent, bool do_convert) { bool ListDir(int dir_fd, Arena& arena, std::vector& entries, bool precompose_unicode, bool case_sensitive) { - entries.clear(); + const size_t orig_size = entries.size(); dir_fd = dup(dir_fd); if (dir_fd < 0) return false; DIR* dir = fdopendir(dir_fd); @@ -225,10 +225,10 @@ bool ListDir(int dir_fd, Arena& arena, std::vector& entries, bool precomp entries.push_back(DirenvConvert(arena, *ent, precompose_unicode)); } if (errno) { - entries.clear(); + entries.resize(orig_size); return false; } - StrSort(entries.data(), entries.data() + entries.size(), case_sensitive); + StrSort(entries.data() + orig_size, entries.data() + entries.size(), case_sensitive); return true; } diff --git a/src/dir.h b/src/dir.h index 42ab29bb..4d4cf3da 100644 --- a/src/dir.h +++ b/src/dir.h @@ -25,11 +25,11 @@ namespace gitstatus { -// On error, clears entries and returns false. Does not throw. +// On error, leaves entries unchaged and returns false. Does not throw. // -// On success, fills entries with the names of files from the specified directory and returns true. -// Every entry is a null-terminated string. At -1 offset is its d_type. All elements point into the -// arena. They are sorted either by strcmp or strcasecmp depending on case_sensitive. +// On success, appends names of files from the specified directory to entries and returns true. +// Every appended entry is a null-terminated string. At -1 offset is its d_type. All elements +// point into the arena. They are sorted either by strcmp or strcasecmp depending on case_sensitive. // // Does not close dir_fd. // diff --git a/src/index.cc b/src/index.cc index ae8ca54c..4d66876b 100644 --- a/src/index.cc +++ b/src/index.cc @@ -242,6 +242,7 @@ std::vector ScanDirs(git_index* index, int root_fd, IndexDir* const dir.st = st; } + entries.clear(); arena.Reuse(); if (!ListDir(*dir_fd, arena, entries, caps.precompose_unicode, caps.case_sensitive)) { AddUnmached(""); diff --git a/src/tag_db.cc b/src/tag_db.cc index 31b150bd..52cbaede 100644 --- a/src/tag_db.cc +++ b/src/tag_db.cc @@ -155,6 +155,8 @@ void TagDb::ReadLooseTags() { int dir_fd = open(dirname.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC); if (dir_fd < 0) return; ON_SCOPE_EXIT(&) { CHECK(!close(dir_fd)) << Errno(); }; + // TODO: recursively traverse directories so that the file refs/tags/foo/bar gets interpreted + // as the tag foo/bar. See https://github.com/romkatv/gitstatus/issues/254. (void)ListDir(dir_fd, loose_arena_, loose_tags_, /* precompose_unicode = */ false, /* case_sensitive = */ true); }