Может ли git фиксировать пустые версии новых непустых файлов?

Может ли git зафиксировать пустые версии некоторых файлов? Дело в том, что мне нужно, чтобы новые (неотслеживаемые), непустые файлы были сначала добавлены и зафиксированы как пустые файлы, чтобы пометить их содержимое как новое и просмотреть (полный , неотслеживаемый файл не должен быть добавлен в индекс; git diff должно показывать только что добавленное содержимое путем сравнения файла с его зафиксированной пустой версией).

Есть git add -N file…, который ставит в индекс file с пустым содержимым, но это говорит только о том, что file будет добавлено, а git commit жалуется, что файл не добавлен. Дело в том, что добавлять надо не текущую, непустую версию, а только пустую версию нового файла.

Есть ли способ сделать это?

PS: этот вопрос задан в контексте программы, которая автоматически добавляет файлы в репозиторий git (моя программа следует тому, что пишут студенты). Незафиксированный код — это код, который мне еще предстоит утвердить. Таким образом, состояние, в котором запускается программа, созданная учащимся, должно быть пустым, даже если моя программа только что обнаружила новую непустую программу в их домашнем каталоге; это выполняется путем автоматической фиксации новой пустой версии любого нового файла студенческой программы в репозитории git. Таким образом, новые строки кода, которые они пишут, выглядят как новое добавленное содержимое по сравнению с последней зафиксированной ревизией git.


person Eric O Lebigot    schedule 20.11.2010    source источник
comment
Я честно не понимаю вашей проблемы. touch empty-file && git add empty-file && git commit у меня работает.   -  person joschi    schedule 20.11.2010
comment
git diff отлично работает для вновь созданного файла. Если вы сравните состояние, когда файл не существовал, с diff, когда в нем есть содержимое, вы увидите все добавленные строки, точно такой же diff, как при сравнении с пустым файлом. (Только модели разные.)   -  person Cascabel    schedule 20.11.2010
comment
@joschi: Проблема в том, что у меня много новых непустых файлов. Использование подхода Свена № 1 более громоздко, чем использование его аккуратного подхода git-plumbing.   -  person Eric O Lebigot    schedule 21.11.2010
comment
@Jefromi: Дело в том, что не должно быть состояния / версии, в которой файл имеет содержимое (только версия, в которой файл пуст). Таким образом, новые непустые файлы не должны быть зафиксированы, потому что это способ для меня, как учителя, пометить код ученика как еще не утвержденный.   -  person Eric O Lebigot    schedule 21.11.2010
comment
@EOL: Но тогда, до утверждения, код не отслеживается! Страшный! Вы можете использовать фиксацию, чтобы пометить отправку кода, затем отметить одобрение, внеся поправку с подписью вне строки, или зафиксировать его в отправленной ветке, а затем выбрать вишню или объединить ее в утвержденную ветку...   -  person Cascabel    schedule 21.11.2010
comment
@Jefromi: неотслеживаемый код вообще не проблема, когда я слежу за тем, что делают ученики в моем классе. История их развития мне ни к чему - не вижу в этом ничего страшного. Мне нужно только быстро просмотреть то, что каждый студент добавлял поверх того, что я одобрил в их коде. Используя git add -p, я могу легко отметить, какие строки больше не требуют моего внимания. Я не вижу, как могут помочь коммиты выбора вишни, поскольку одобренный код может быть добавлен только через git add -p и гранулярные коммиты. Может быть, я полностью упускаю из виду вашу мысль? :)   -  person Eric O Lebigot    schedule 21.11.2010
comment
Хм, меня просто пугает мысль о том, что что-то потенциально важное может быть за пределами контроля версий. Но если это действительно не имеет значения, то я думаю, что все хорошо!   -  person Cascabel    schedule 22.11.2010
comment
@Jefromi: я бы побоялся. :) Учащиеся по-прежнему могут использовать контроль версий для своего кода, если захотят. Программное обеспечение для контроля версий достаточно универсально, чтобы делать другие вещи, кроме контроля версий, и поэтому я использую его, чтобы отметить, какие части кода студентов я должен обсудить с ними.   -  person Eric O Lebigot    schedule 22.11.2010
comment
Примечание. В Git 2.5 (второй квартал 2015 г.) git commit больше не будет жаловаться на новый файл, который будет добавлен позже: см. stackoverflow.com/ а/30341632/6309   -  person VonC    schedule 20.05.2015
comment
Я считаю это полезным, когда вам нужно создать новый файл построчно.   -  person minexew    schedule 11.04.2020


Ответы (2)


Честно говоря, я не очень понимаю, для чего это полезно. Я бы попытался исправить процесс рецензирования, а не портить историю. Но если вы действительно хотите это сделать, вот несколько способов:

  1. Прагматический подход:

    mv file out-of-way
    touch file
    git add file
    mv out-of-way file
    
  2. Фарфоровый подход:

    git add -N file
    git add -p file
    

    ... и просто ответьте "нет" на вопрос, следует ли добавить один фрагмент. (Очевидно, это больше не работает в 2019 году.)

  3. Сантехнический подход:

    Во-первых, убедитесь, что в базе данных объектов существует пустой объект:

    git hash-object -w --stdin < /dev/null
    

    Это вернет SHA1 пустого большого двоичного объекта (то есть e69de29bb2d1d6434b8b29ae775ad8c2e48c5391). Вы должны создать этот объект только один раз. Теперь вы можете создавать пустые файлы в индексе с помощью

    git update-index --add --cacheinfo 0644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file
    
person Sven Marnach    schedule 20.11.2010
comment
@Sven: Большое спасибо! Сантехнический подход для меня идеален: он легко автоматизируется, и по делу (вторая догадка, зачем мне это нужно, не так актуальна, хотя :) ). Это полезно для отслеживания того, какой новый код мои ученики добавляют в свой домашний каталог, используя git diff в моих локальных копиях своих программ. Код, который я еще не утвердил, не должен быть зафиксирован, но продолжает отображаться как новые добавленные строки (по сравнению с пустым файлом), пока он не зафиксирован (т.е. одобрен). - person Eric O Lebigot; 21.11.2010
comment
@EOL: вы также можете легко автоматизировать касание, добавление, затем копирование. - person Cascabel; 21.11.2010
comment
@EOL: извините за грубость - просто хотел указать, что я не рекомендую делать то, что я объяснил в этом ответе. Я думаю, что подходы, которые Джефроми предлагает в комментариях к вашему вопросу, обеспечивают более гибкие (и более надежные) рабочие процессы. - person Sven Marnach; 21.11.2010
comment
@Sven: Спасибо за приятные, успокаивающие слова. :) Подход Джефроми в принципе хорош, но мне пришлось бы использовать вашу версию (т.е. ваш подход №1). Я использую rsync для локального копирования (удаленных) файлов учеников. Таким образом, новые файлы отображаются как неотслеживаемые файлы, а их содержимое уже скопировано в локальную структуру каталогов. Ваш подход №3 идеально подходит для моей ситуации, и я использовал его в своей программе наблюдения. - person Eric O Lebigot; 21.11.2010
comment
@EOL: я имел в виду рабочие процессы, описанные Джефроми в комментариях к вашему вопросу, например. имеют отдельные ветви commited и accepted. Это был бы один из способов исправить процесс рецензирования, а не портить историю. - person Sven Marnach; 22.11.2010
comment
@Свен: понятно. Мне действительно не нужна выделенная ветка. :) Если они хотят использовать контроль версий, это их дело. Мне не нужен контроль версий как таковой, а нужно только пометить части их кода как правильные. Таким образом, мне нужна только принятая ветка... а это значит, что достаточно одной главной ветки! :) - person Eric O Lebigot; 22.11.2010
comment
Фарфоровый подход, похоже, здесь не работает: git commit говорит file: not added yet error: Error building trees, и аналогичная ошибка от git stash. Сантехнический подход работает. - person p00ya; 23.06.2011
comment
Почему это полезно? Я переписываю ветку, чтобы ее было легко просматривать, и я хотел бы начать с шаблонного коммита, который добавляет новые пустые файлы и включает их в процесс сборки. Дальнейшие коммиты добавляют в эти файлы код для новых функций. - person Patrick Sanan; 06.03.2019
comment
У меня тоже проблемы с фарфоровым способом. Когда я добавляю файл с помощью git add <file> -N, он отображается как новый файл, когда я делаю git status. Однако выполнение git add -p и выбор no, по-видимому, не дают никакого эффекта, и пустой файл не добавляется в индекс. - person HelloGoodbye; 17.10.2019
comment
@HelloGoodbye По-видимому, поведение git в этом крайнем случае изменилось за девять лет, прошедшие с тех пор, как я опубликовал этот ответ, поэтому я уберу второй подход. - person Sven Marnach; 17.10.2019
comment
Ах. Кажется, порвался фарфор. ;) - person HelloGoodbye; 18.10.2019

Автоматически добавлять все пустые файлы и папки


Принудительно добавить все файлы

$ git add -Af

Вы можете автоматически добавить файл .gitignore в каждую пустую папку.

$ find $PATH_TO_REPOSITORY -type d ! -path "*.git*" -empty -exec cp .gitignore '{}'/ \;

Вы можете автоматически добавить файл .gitkeep в каждую пустую папку.

$ find $PATH_TO_REPOSITORY -type d ! -path "*.git*" -empty -exec touch '{}'/.gitkeep \;
person Nathan Weiler    schedule 22.04.2020
comment
Привет Натан. Вопрос конкретно касается непустых файлов. Вы уверены, что это не просто общий ответ на копирование? - person minexew; 22.04.2020