Як ви зберігаєте незайманий файл?


1434

У мене є зміни у файлі, а також новий файл, і я хотів би використати git stash, щоб прибрати їх, поки я переключаюся на інше завдання. Але git stash сам по собі приховує лише зміни існуючого файлу; новий файл залишається в моєму робочому дереві, захаращуючи мою подальшу роботу. Як я зберігаю цей незайманий файл?


27
Будьте в курсі, що якщо у вашому сховищі є лише невикрашені файли, це виглядатиме як порожній, оскільки git stash showнічого не повертає, і ви можете спокусити його відкинути (як я це робив, коли він містив корисний сценарій, який я писав кілька місяців тому → як відновити скинуту скриньку )
— Максим Р.

Відповіді:


1920

Щоб сховати свою робочу директорію, включаючи непотрібні файли (особливо ті, які є у .gitignore), ви, ймовірно, хочете використовувати цей cmd:

git stash --include-untracked

Детальніше:

Оновлення 17 травня 2018 року:

Зараз у нових версіях git git stash --allприховуються всі файли, включаючи відстежені та відігноровані файли.
git stash --include-untrackedбільше не торкається ігнорованих файлів (тестовано на git 2.16.2).

Оригінальна відповідь нижче:

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

Починаючи з версії 1.7.7, ви можете використовувати git stash --include-untrackedабо git stash save -uзберігати незавершені файли, не встановлюючи їх.

Додайте git addфайл ( ) і починайте його відстежувати. Потім приховуйте. Оскільки весь вміст файлу є новим, він буде схований, і ви можете ним маніпулювати, якщо потрібно.


4
Чому досі приховується зміна існуючих файлів, навіть якщо ці зміни не були встановлені?
— Алан Крістенсен

6
@ alan-christensen Прочитайте ОПИС kernel.org/pub/software/scm/git/docs/git-stash.html . Сенс у тому, щоб мати чисте робоче дерево після укладання.
— Келвін

3
@Kelvin, що я мав на увазі у своєму коментарі, це те, що він не зберігає нові файли, якщо вони не були інсценовані, однак він зберігає існуючі файли, навіть якщо вони не були поставлені. Здається мені непослідовно.
— Алан Крістенсен

11
@AlanChristensen справа в тому, щоб сховати речі, які можуть бути перезаписані, оформивши іншу гілку.
— jwg

3
Оскільки у вас є головна відповідь тут, я просив би вас перерахувати git stash --include-untrackedраніше git stash --allу своїй відповіді з двох причин. По-перше, він відповідає на питання ОП краще вже в 2019 році, а по-друге, тому що - все робить щось, чого, мабуть, не хоче більшість користувачів, тому що він видаляє всі файли, які .gitignored
— Daniel

411

Станом на git 1.7.7, git stashприймає --include-untrackedопцію (або короткочасну -u). Щоб включити непотрібні файли у свій пристрій, скористайтеся однією з наступних команд:

git stash --include-untracked
git stash -u

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


15
Класно - це, нарешті, працює так, як описано на сторінці керівництва. Не зберігання (та чищення) нових файлів є порушеною поведінкою.
— Стів Беннетт

1
моя версія git 1.9.1, і навіть якщо те, що у мене є, .gitignoreвиглядає так, ignoredDirectoryа не ignoredDirectory/*воно все ще видаляє ті, що не мають треку. Навіть незаймані файли не просто каталоги.
— theNorknown777

22
Чи можете ви поясніть, будь ласка, попередження? Чому б видалити ці файли? Чи видаляє їх, а не приховує їх? Я деякий час користувався Git і не стикався з цією проблемою.
— Олександр Дубінський,

Чи застосовується попередження і до *.extensionзаписів?
— arekolek

3
@ aleksandr-dubinsky, @arekolek - git1.8.3 -u( --include-untracked) варіант може зберігати та видаляти непотрібні файли нормально, але git stash showне перелічує непотрібні файли, які знаходяться в
— скрині

77

Додайте файл до індексу:

git add path/to/untracked-file
git stash

Весь вміст індексу, а також будь-які незмінені зміни до існуючих файлів перетворять їх у сховище.


Що робити, якщо ви не хочете приховувати зміни, які вже є в індексі? Чи зберігання нового файлу все ще можливо?
— allyourcode

Введіть індекс, схойте новий файл, а потім відновіть фіксацію та / або перевірте файли з фіксації. Це химерне рішення, але воно має працювати.
— Гдаля

git add .чомусь не
— враховував це

53

У git bash зберігання відслідковуваних файлів досягається за допомогою команди

git stash --include-untracked

або

git stash -u

http://git-scm.com/docs/git-stash

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

git stash pop

Це поверне файл назад у локальну робочу область.

Мій досвід

Мені довелося змінити свій файл gitIgnore, щоб уникнути переміщення файлів .classpath та .project у віддалений репо. Мені заборонено переміщувати цю змінену .gitIgnore у віддаленому репо-сервері.

Файли .classpath та .project важливі для затемнення - це мій редактор Java.

Я, перш за все, вибірково додав решту файлів і взявся за постановку. Однак остаточне натискання не може бути здійснено, якщо змінені файли .gitIgnore не видаляються та файли, що не відслідковуються, а саме. .project і .classpath не зберігаються.

я використав

 git stash 

для зберігання зміненого файлу .gitIgnore.

Для зберігання .classpath та .project файлу я використовував

git stash --include-untracked

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

git stash pop

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


2
Чому ви не використовуєте глобальний gitignore для файлів IDE? Тобто використання ~/.gitignore.
— Antti Pihlaja

20

Як було сказано в іншому місці, відповідь - на git addфайл. наприклад:

git add path/to/untracked-file
git stash

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

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

це не вдасться:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

Отже, що ти можеш зробити? Ну, вам потрібно по-справжньому додати файл, однак ви можете його ефективно скасувати додавання пізніше, використовуючи git rm --cached:

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

І тоді ви можете продовжувати роботу в тому ж стані, в якому ви були раніше git add(а саме з незвареним файлом, який називається path/to/untracked-file; плюс будь-які інші зміни, які, можливо, мали б відслідковувати файли).

Інша можливість для робочого процесу щодо цього буде щось на зразок:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[Примітка. Як зазначено в коментарі @mancocapac, ви можете додати --exclude-standardдо git ls-filesкоманди (так, git ls-files -o --exclude-standard).]

... що також може бути легко скриптовано - навіть псевдоніми будуть робити (представлені в синтаксисі zsh; коригувати за потребою) [також, я скоротив ім'я файлу, щоб воно все вміщувалося на екрані, не прокручуючи цю відповідь; не соромтеся замінити альтернативне ім’я файлу на ваш вибір]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

Зауважте, що останній може бути кращим як скрипт або функція оболонки, щоб дозволити доставку параметрів git stash, якщо ви не хочете, popале applyта / або хочете мати змогу вказати певний скринь, а не просто брати верх один. Можливо, це (замість другого псевдоніму вгорі) [пробіл позбавлений розміщення без прокрутки; повторно додати для підвищення розбірливості]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

Примітка . У цій формі вам потрібно надати аргумент дії, а також ідентифікатор, якщо ви збираєтесь надати ідентифікатор скриньки, наприклад, unstashall apply stash@{1}абоunstashall pop stash@{1}

Що, звичайно, ви б додали у свій .zshrcеквівалент або еквівалент, щоб існувати довгостроково.

Сподіваємось, ця відповідь комусь корисна, поєднуючи все разом в одну відповідь.


1
git ls-files -o показує набагато більше файлів, ніж ті, що мене цікавлять. З наступного стану git я знайшов додавання --exclude-стандартних робіт. git ls-files -o - exclude-standard. Думаю, це лише те, що "включає" непотрібні файли, які ти зазвичай не ігноруєш, тобто показуєш лише непотрібні файли, які твій .gitignore не фільтрує
— mancocapac

20

У git версії 2.8.1: наступні роботи для мене.

Збереження модифікованих та відслідковуваних файлів у сховці без імені

git stash save -u

Збереження модифікованих та відслідковуваних файлів у сховищі з іменем

git stash save -u <name_of_stash>

Ви можете використовувати або поп, або застосувати пізніше наступним чином.

git stash pop

git stash apply stash@{0}

Це не видалило незавершені файли з мого комп’ютера, хоча вони більше не були вказані як невиправлені. git stash showне показував їх. Коли я спробував git stash apply, я отримав "помилку: не вдалося відновити відслідковувані файли із сховища". Однак файли знову були вказані як не відстежені, але зміни до відстежених файлів не були відновлені. Я думаю, що ці файли можна відновити окремо, перевіривши їх із сховища, але це рішення було не тим, на що я сподівався.
— hBrent

9

Мені вдалося сховати лише незафіксовані файли, зробивши:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

Останній вискакує копію відстежуваних файлів, тим самим залишаючи приховані лише незафіксовані файли.


git stash save -uне просто зберігає untrackedфайли, а зберігає trackedі untracked. і . Я думаю, що перше рятування, яке ви робите, не є необхідним у цьому випадку. Є гарна схема в atlassian.com/git/tutorials/saving-changes/…
— Дренай

2
Питання полягає в тому, як зберігати лише незавершені файли. Якщо ви пропустите першу скриньку, то що ви будете робити? Ідея полягає в тому, щоб: 1) Штату відстежували. 2) Сховайте без уваги. 3) Поп відслідковується. Результат: Невикреслені залишаються прихованими.
— Oded

3

Якщо ви хочете зберігати незараховані файли, але зберігати індексовані файли (ті, які ви збираєтеся зробити, наприклад), просто додайте параметр -k(зберігати індекс) до параметра-u

git stash -u -k


2

припустимо, новий і незатребуваний файл називається: "views.json". якщо ви хочете змінити відділення, переглядаючи стан вашої програми, я зазвичай набираю:

git add views.json

Тоді:

git stash

І це було б приховано. Тоді я можу просто змінити гілку на

git checkout other-nice-branch

1

Тут є кілька правильних відповідей, але я хотів зазначити, що для нових цілих каталогів НЕ'git add path' буде працювати. Тож якщо у вас є купа нових файлів у не відстеженому контурі, виконайте це:

git add untracked-path
git stash "temp stash"

це буде сховано з наступним повідомленням:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

і якщо untracked-path - єдиний шлях, котрий ви перебуваєте, тимчасовий "temp stash" буде порожнім сховищем. Правильний спосіб - це додати весь шлях, а не лише ім'я каталогу (тобто закінчити шлях символом '/'):

git add untracked-path/
git stash "temp stash"

Принаймні, в моїй системі ваше припущення неправильне. Це працює без косої риси! Порожні каталоги все одно ігноруються. (macos git 2.6.2)
— фобій

0

Я подумав, що це можна вирішити, сказавши git про те, що файл існує, а не передавати весь його вміст в область постановки, а потім зателефонувати git stash. Аракнід описує, як це зробити.

git add --intent-to-add path/to/untracked-file

або

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

Однак останній не працює:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

1
Наскільки я можу сказати, колишній теж не працює. Дивіться мою відповідь для вирішення цієї проблеми.
— lindes

0
git stash --include-untracked

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


0

Я зіткнувся з подібною проблемою під час використання Sourcetree з новоствореними файлами (вони теж не будуть включені в сховище).

Коли я вперше вибрав "сценічне все", а потім перезаписував щойно додані компоненти, де відслідковувався і тому включався в сховище.


На це запитання 11 років і вже є 14 відповідей. Чи читали ви їх перед публікацією?
— Мікаель Б.

-7

Я раніше розмірковував і бажав тієї самої риси. Але з часом я помітив, що це справді не потрібно. Коли ви зберігаєте, добре залишити нові файли. Нічого "поганого" з ними не може трапитися (коли ви перевірите щось інше, git помилиться та не замінить існуючий незатребуваний файл)

А оскільки зазвичай часовий проміжок між git stashта та git stash popдосить малий, вам знову знадобиться файл, що не відслідковується, швидко. Тож я б сказав, що незручність файлу, який з’являється під git statusчас роботи над чимось іншим (між git stashі тим git stash pop), є меншим, ніж незручності, спричинені роботою, і потрібна увага, інакше варто коштувати спробувати додати файл, що не відслідковується, до ваш сховище.


15
Це залежить від проекту. Скажімо, файл без відстеження - це тест (напівзаписаний) одиничного тесту, і тестовий джгут виконує всі тести одиниць у каталозі. І т. Д.
— Стів Беннетт

1
Інший приклад - якщо ви працюєте на двох комп’ютерах, і вам дозволяється переміщувати дані з A в B, але не з B на A. Якщо ви створюєте новий фрагмент коду, щоб вирішити проблему, яка спочатку виникає на B, але ви Ви хочете як на A, так і на B, ви хочете мати змогу зберігати файл на B, щоб, коли ви відтворили цей файл на A, а потім перенесли його у пакеті, ви можете отримати git diff зашивану версію, щоб переконатися, що ви цього не зробили помилятися.
— Гдаля

7
Тільки тому, що файл не відслідковується в одній гілці, не означає, що він не буде конфліктувати з відстежуваним файлом в іншій гілці.
— jwg

3
простий зустрічний приклад: файл конфігурації в каталозі .conf.d або будь-який інший, який, лише будучи там, змінює поведінку програмного забезпечення.
— fotanus

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