Як поставити лише частину нового файлу з git?


222

Я люблю git add - інтерактивний . Зараз це частина мого щоденного робочого процесу.

Проблема здається, що вона не працює з незавершеними файлами. Що я хочу зробити, це відстежувати новий файл, але лише додати його, тобто деякі частини цього нового файлу ще не готові до постановки.

Наприклад, за допомогою git add -i я можу обрати варіант патчу та навіть редагувати окремі номери, щоб сформувати частини нового коду, залишивши коментарі коду налагодження без змін. Я люблю працювати таким чином, тому що це дає зрозуміти, в яких місцях мега-патча, над яким я зараз працюю, ще потрібна робота.

На жаль, я, здається, не зможу зробити те ж саме з файлом, що не відслідковується. Або я виставляю весь файл, або нічого. Завдання, яке я використовував, - це постановка або навіть створення нового файлу, коли він порожній, а потім постановка окремих змін звичайним способом. Але це рішення відчуває себе брудним злом, і коли я забуваю або передумую, це створює більше клопотів, ніж повинно бути.

Отже, питання полягає в тому, як поставити лише частину нового файлу, щоб цей новий файл відслідковувався, але залишав без змін цілий або частину його вмісту?

Відповіді:


415

Ого, все це update-indexі hash-objectбізнес здається надмірно складними. Як щодо цього:

git add -N new_file
git add -i

Від git help add:

-N, --intent-to-add
    Record only the fact that the path will be added later.  An entry
    for the path is placed in the index with no content.  This is useful
    for, among other things, showing the unstaged content of such files
    with git diff and committing them with git commit -a.

9
++ 1! належний кредит. Я занадто багато довіряю, що я знаю ці підручники до цього моменту ....</shame>
1111

1
Добре знайдено. Я повинен був прокрутити сторінку чоловіка трохи далі. Можливо, я повинен повернути значок Git Pro.
dave1010

3
Цікаво, чому git-gui не використовує це внутрішньо, щоб мати змогу створювати рядки з нового файлу.
Дейвін

6
Чудове -Nвідкриття, дякую! Хоча я вважаю за краще комбінувати його з -pцим випадком. gid add -N the_file& git add -p. Варто додати, що -Nтакож працює з-A
Кирилом ЧАПОН

@Deiwin - ви можете додати [guitool] до свого .gitconfig, щоб зробити "git add -N $ FILENAME": [guitool "Додати з наміром"] cmd = "git add -N $ FILENAME" needfile = так noconsole = так
Стів Фолді

7

Найпростіший спосіб зробити це (і взагалі імхо інтерактивні постановки) git gui. Він поставляється в комплекті з git і повинен працювати майже на всіх платформах, які підтримуються git.

Просто запустіть, git guiі відкриється gui, який дозволяє інсценізувати та відміняти перегонки та навіть поодинокі рядки відстежуваних та відслідковуваних файлів.

Скріншот Git Gui


Це творча відповідь і іноді це дуже, дуже корисно.
Пабло Олмос де Агілера C.

3
Лише зауважте, що не всі git-дистрибуції включають git gui. Наприклад, у Debian він знаходиться в окремому пакеті під назвою "git-gui".
cristoper


2
Для мене інсценізація одиночних рядків незатребуваних файлів git guiніколи не працювала. Насправді він вимикає ці параметри меню .
Дейвін

2
@Deiwin Я, мабуть, пропустив це у питанні - на моєму екрані зображено вже відстежений файл. Якщо ви хочете використовувати git guiдля нового файлу, вам потрібно запустити git add -N new_fileперший - дивіться відповідь Річарда Хансена.
Хронічний

6
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
git add --interactive newfile

Проста демонстрація:

mkdir /tmp/demo
cd /tmp/demo
git init .

echo hello > newfile
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
  • Підказка Якщо ви впевнені, що "порожня" крапка вже існує у вашій базі даних об’єктів git, e69de29bb2d1d6434b8b29ae775ad8c2e48c5391замість цього ви можете жорстко кодувати хеш . Я не рекомендую робити це_
  • Підказка Якщо ви працюєте в Windows, ви, ймовірно, можете просто використовувати NUL:замість цього /dev/null. В іншому випадку використовуйте щось подібнеecho -n '' | git hash-object --stdin -w

Тепер індекс буде містити newfileяк порожній blob, а порожній blob був введений в об'єктну базу даних, якщо він ще не існував:

$ find .git/objects/ -type f 
.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   newfile
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   newfile
#

$ git diff
diff --git a/newfile b/newfile
index e69de29..ce01362 100644
--- a/newfile
+++ b/newfile
@@ -0,0 +1 @@
+hello

Це має бути саме те, що ви хочете. Чи можу я також порекомендувати плагін Vim-втікача для дуже інтелектуального управління індексами (див. Краще додавання git -p? )


1
Це, здається, працює добре. Я його псевдоніму на "сценічно-порожній-файл", оскільки це трохи складно запам'ятати.
dave1010

@ dave1010: Рада, що це допомогло! Так, я думав над тим, як додати псевдонім, але я не знав, як ви розраховуєте поводитись, наприклад, з маскими символами або аргументами декількох файлів взагалі. Тому я вирішив не
sehe

2

Редагувати: це, здається, зараз не працює. Я впевнений, що було раніше (на git 1.7.1). У випадку, якщо це не працює, я пропоную /dev/nullвиконати так, як sehe пропонує вище:

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile

Якщо ви перебуваєте в Windows (без /dev/null), ви можете замінити його на шлях до порожнього файлу.

Оригінальна відповідь

Ти хочеш

git add -p # (or --patch)

Це додає для мене неактивні файли. Із чоловічої сторінки:

Інтерактивно вибирайте фрагменти патча між індексом та робочим деревом та додайте їх до індексу. Це дає користувачеві можливість переглянути різницю перед додаванням модифікованого вмісту в індекс.

Це ефективно виконує додавання - інтерактивне, але обходить початкове меню команд і безпосередньо переходить до підкоманди патча. Детальніше див. У "Інтерактивному режимі".


2
Як би цікаво, для мене це не працює (git 1.7.4); git add -p newfileвзагалі не працює (ну ефект), а git add --interactive"[a] dd untrecked" має ефект, який git add newfileмає; Правка також перевірено з git 1.7.5.3; немає кісток
sehe

Хороший натяк для Windows, додав підказки для цього у моїй відповіді. Thx
sehe

-2

Тільки для запису іншої можливості: я використовую

git add -N file
git add -p file

А потім ви можете влаштовувати опини або редагувати їх на місці.


1
Ця відповідь говорить те саме, що і прийнята відповідь, що датується 2011 р. Downvote.
Станіслав Панькевич

Прийнята відповідь поєднується add -Nз add -i. Я просто додав, що add -pзамість add -iробіт теж.
Педро Адама Вергара
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.