Сделать git статус показать неизмененные/неизменные отслеживаемые файлы? - программирование
Подтвердить что ты не робот

Сделать git статус показать неизмененные/неизменные отслеживаемые файлы?

Ниже приведен краткий пример фрагмента (который вы можете вставить в свой Linux-терминал), создавая новый репозиторий git и добавляя к нему некоторые файлы (с помощью git версии 1.7.9.5):

cd /tmp/
mkdir myrepo_git
cd myrepo_git/
git init
git config user.name "Your Name"
git config user.email [email protected]
echo "test" > file_tracked_unchanged.txt
echo "test" > file_tracked_changed.txt
echo "test" > file_untracked.txt
git add file_tracked_unchanged.txt 
git add file_tracked_changed.txt
git commit -m "initial commit"

Теперь, после первоначальной фиксации, я хочу изменить файлы file_tracked_changed.txt и сохранить остальные (здесь, только file_tracked_unchanged.txt) без изменений для следующего коммита. Ниже приведен фрагмент, который демонстрирует это, а различные выходы git status vs git ls-files (git вывод оболочки с префиксом #):

echo "test more" >> file_tracked_changed.txt

git status -uno
# # On branch master
# # Changes not staged for commit:
# #   (use "git add <file>..." to update what will be committed)
# #   (use "git checkout -- <file>..." to discard changes in working directory)
# #
# # modified:   file_tracked_changed.txt
# #
# no changes added to commit (use "git add" and/or "git commit -a")
git status
# # On branch master
# # Changes not staged for commit:
# #   (use "git add <file>..." to update what will be committed)
# #   (use "git checkout -- <file>..." to discard changes in working directory)
# #
# # modified:   file_tracked_changed.txt
# #
# # Untracked files:
# #   (use "git add <file>..." to include in what will be committed)
# #
# # file_untracked.txt
# no changes added to commit (use "git add" and/or "git commit -a")
git status -uno --short
#  M file_tracked_changed.txt
git status --short
#  M file_tracked_changed.txt
# ?? file_untracked.txt
git ls-files -v
# H file_tracked_changed.txt
# H file_tracked_unchanged.txt

git add file_tracked_changed.txt

git status -uno
# # On branch master
# # Changes to be committed:
# #   (use "git reset HEAD <file>..." to unstage)
# #
# # modified:   file_tracked_changed.txt
# #
# # Untracked files not listed (use -u option to show untracked files)
git status
# # On branch master
# # Changes to be committed:
# #   (use "git reset HEAD <file>..." to unstage)
# #
# # modified:   file_tracked_changed.txt
# #
# # Untracked files:
# #   (use "git add <file>..." to include in what will be committed)
# #
# # file_untracked.txt
git status -uno --short
# M  file_tracked_changed.txt
git status --short
# M  file_tracked_changed.txt
# ?? file_untracked.txt
git ls-files -v
# H file_tracked_changed.txt
# H file_tracked_unchanged.txt

Что я ищу, это команда, которая покажет все отслеживаемые файлы в каталоге (который git ls-files -v), с их точным статусом репозитория (который git ls-files не показывает, так как он показывает H как статус для всех отслеживаемых файлов). Например, я хотел бы получить что-то вроде псевдокода:

git status-tracked
# M file_tracked_changed.txt
# . file_tracked_unchanged.txt

... где точка . будет символом, обозначающим отслеживаемый, но неизменный файл (если я правильно помню, SVN может использовать для этого символ U).

В конечном счете, я хотел бы также показать статус всех файлов в каталоге, как в псевдокоде:

git status-tracked-and-untracked
# M file_tracked_changed.txt
# . file_tracked_unchanged.txt
# ?? file_untracked.txt

... но для меня более важно получить статус всех отслеживаемых файлов, как в псевдо git status-tracked выше.

Любая команда в git, которая уже делает что-то вроде этого?

4b9b3361

Ответ 1

Спасибо @sdaau. Я сделал несколько изменений, так что он работает намного быстрее и предоставляет результаты в том же формате, что и git status:

git ls-files | while read -r line;
do
    st=$(git status -s "$line");
    if [ -n "$st" ]; then
        echo "$st";
    else
        echo "   $line";
    fi;
done

Ответ 2

Благодаря @Andomar для подсказки git ls-tree; это то, что он показывает:

git ls-tree --name-status HEAD
# file_tracked_changed.txt
# file_tracked_unchanged.txt

... но мне нужны статусы :)

 

ОК, вот решение, вызывающее как ls-files, так и status, и чередование их с помощью синтаксического анализа bash:

git ls-files -cdmoskt --abbrev=8 | while read -r line; do \
  fn=$(echo "$line" | sed 's/.*\s\(\w\+\)/\1/'); \
  st=$(git status -s "$fn" | printf "%-02s " $(sed 's/\([[:print:]]\+\)\s.*/\1/')); \
  echo "$st- $line"; \
done

Если вы запустите это, как в примере OP, вы получите:

git ls-files -cdmoskt --abbrev=8 | while read -r line; do fn=$(echo "$line" | sed 's/.*\s\(\w\+\)/\1/'); st=$(git status -s "$fn" | printf "%-02s " $(sed 's/\([[:print:]]\+\)\s.*/\1/')); echo "$st- $line"; done
# ?? - ? file_untracked.txt
# M  - H 100644 52e7a08e 0  file_tracked_changed.txt
#    - H 100644 9daeafb9 0  file_tracked_unchanged.txt

... который в основном я хотел. (Я вернусь сюда, если мне повезет в преобразовании этого в псевдоним git).


EDIT: здесь как git alias (для ~/.gitconfig):

  ls-fstatus = "! cd $PWD/$GIT_PREFIX; git ls-files -cdmoskt --abbrev=8 | while read -r line; do \
    fn=$(echo \"$line\" | sed \"s/.*\\s\\([[:print:]]\\+\\)/\\1/\"); \
    st=$(git status -s "$fn" | printf \"%-02s \" $(sed \"s/\\([[:print:]]\\+\\)\\s.*/\\1/\")); \
    echo \"$st- $line\"; \
  done "

... поэтому можно просто вызвать git ls-fstatus в заданном подкаталоге git repo.

Ответ 3

Вдохновленный @RogerDueck answer, я создал script, который выполняет git ls-files и git status только один раз каждый. Он работает примерно в 15 раз быстрее на моем репо с ~ 1700 файлами, чуть менее 2 секунд.

EDIT: Добавлен ряд исправлений и некоторых unittests, перенесенных в GitHub: https://github.com/frnhr/git-fullstatus p >

Пример вывода:

 M some/file
D  another/file
 D more/files/blahblah
A  this/is/an/added/file/i/think
   an/unchanged_file
   another/unchanged_file

Ответ 4

git status -s | egrep -v '^\?\?'

Отфильтровывает строки, начинающиеся с ??, то есть без следов файлов.