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


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.