Как вы храните неотслеживаемый файл?

1437

У меня есть изменения в файле плюс новый файл, и я хотел бы использовать git stash, чтобы убрать их, пока я переключаюсь на другую задачу. Но git stash сам хранит только изменения в существующем файле; новый файл остается в моем рабочем дереве, загромождая мою будущую работу. Как спрятать этот неотслеживаемый файл?

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

Ответы:

1925

Чтобы сохранить ваш рабочий каталог, включая неотслеживаемые файлы (особенно те, которые находятся в .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
Даниэль Флиппанс,
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/*удаляет те, которые не были отслежены. Даже неотслеживаемые файлы, а не просто каталоги.
theUnknown777
22
Можете ли вы объяснить предупреждение? Зачем удалять эти файлы? Это удаляет их и не прячет их? Я использовал Git некоторое время и не сталкивался с этой проблемой.
Александр Дубинский
Это предупреждение относится и к *.extensionзаписям?
ареколек
3
@ Александр-Дубинский, @arekolek - git 1.8.3 -u( --include-untracked) может сохранять и извлекать неотслеживаемые файлы, но git stash showне отображает неотслеживаемые файлы, которые находятся в
хранилище
77

Добавьте файл в индекс:

git add path/to/untracked-file
git stash

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

skiphoppy
источник
Что если вы не хотите хранить изменения, которые уже есть в индексе? Возможно ли сохранить новый файл?
allyourcode
Зафиксируйте индекс, сохраните новый файл, затем отмените фиксацию и / или извлеките файлы из фиксации. Это грязное решение, но оно должно работать.
Гдаля
git add .почему-то не принимал это во внимание
TheBilTheory
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 важны для eclipse - моего редактора java.

Прежде всего, я выборочно добавил остальные файлы и отправил их на постановку. Тем не менее, окончательная отправка не может быть выполнена, если только измененные поля .gitIgnore и неотслеживаемые файлы, а именно. .project и .classpath не спрятаны.

я использовал

 git stash 

для хранения измененного файла .gitIgnore.

Для хранения файлов .classpath и .project я использовал

git stash --include-untracked

и он удалил файлы из моей рабочей области. Отсутствие этих файлов лишает меня возможности работать на рабочем месте в затмении. Я продолжил с завершением процедуры отправки подтвержденных файлов на удаленный компьютер. Как только это было сделано успешно, я использовал

git stash pop

Это вставило те же файлы обратно в мое рабочее пространство. Это вернуло мне мою способность работать над тем же проектом в затмении. Надеюсь, что это отбросит заблуждения.

DolphinJava
источник
2
Почему вы не используете глобальный gitignore для файлов IDE? То есть. использовать ~/.gitignore.
Антти Пихлая
21

На git версии 2.8.1: у меня работает следующее.

Сохранять измененные и неотслеживаемые файлы в stash без имени

git stash save -u

Сохранять измененные и неотслеживаемые файлы в stash с именем

git stash save -u <name_of_stash>

Вы можете использовать или поп или применить позже, как указано ниже.

git stash pop

git stash apply stash@{0}
user1012513
источник
Это не удаляло неотслеживаемые файлы с моего компьютера, хотя они больше не были перечислены как неотслеживаемые. git stash showне показывал им. Когда я попытался git stash apply, я получил «ошибка: не удалось восстановить неотслеживаемые файлы из тайника». Тем не менее, файлы были снова перечислены как неотслеживаемые, но изменения в отслеживаемых файлах не были восстановлены. Я думаю, что эти файлы могут быть восстановлены индивидуально, извлекая их из тайника, но это решение оказалось не тем, на что я надеялся.
hBrent
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или эквивалент, чтобы сделать существование в долгосрочной перспективе.

Надеюсь, этот ответ будет полезен для кого-то, и все будет собрано в одном ответе.

Lindes
источник
1
git ls-files -o показывает намного больше файлов, чем те, которые меня интересуют. Из следующего состояния git, которое я обнаружил, добавив --exclude-standard works. git ls-files -o --exclude-standard. Я полагаю, что он только «включает» неотслеживаемые файлы, которые вы обычно не игнорируете, то есть показывает только неотслеживаемые файлы, которые ваш .gitignore не отфильтровывает
mancocapac
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) Поп отслеживается. Результат: неотслеженный остается спрятанным.
Одед
3

Если вы хотите сохранить неотслеживаемые файлы, но сохранить индексированные файлы (например, те, которые вы собираетесь зафиксировать), просто добавьте -k(сохранить индекс) опцию в-u

git stash -u -k
временное исполнение обязанностей
источник
2

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

git add views.json

Затем:

git stash

И это будет спрятано. Тогда я могу просто изменить ветку с

git checkout other-nice-branch
martline1
источник
1

Здесь есть несколько правильных ответов, но я хотел бы отметить, что для новых целых каталогов НЕ'git add path' будет работать. Так что, если у вас есть куча новых файлов в unraracked-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

и если путь без отслеживания - единственный путь, который вы копируете, тайник «временный тайник» будет пустым тайником. Правильный способ - добавить весь путь, а не только имя каталога (то есть завершить путь символом '/'):

git add untracked-path/
git stash "temp stash"
DrStrangepork
источник
По крайней мере, в моей системе ваше предположение неверно. Работает без слеша! Пустые каталоги игнорируются в любом случае. (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
Насколько я могу судить, первое тоже не работает. Смотрите мой ответ для решения этой проблемы.
Линд
0
git stash --include-untracked

мой любимый, так как он сохраняет также файлы, которые вы добавили и не поставили их.

Ованнес Бабаян
источник
0

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

Когда я впервые выбрал «ставить все», а затем спрятать недавно добавленные компоненты, которые отслеживаются и, следовательно, включаются в заначку.

Иво ван Леувен
источник
На этот вопрос 11 лет и уже есть 14 ответов. Вы читали их перед публикацией?
Микаэль Б.
-7

Я привык размышлять и желать ту же функцию. Но со временем я заметил, что это действительно не нужно. Когда вы прячетесь, все в порядке, чтобы оставить новые файлы. Ничего «плохого» с ними не случится (когда вы проверяете что-то еще, git выдаст ошибку и не перезапишет существующий неотслеживаемый файл)

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

Dieter_be
источник
15
Это зависит от проекта. Допустим, неотслеживаемый файл является (наполовину написанным) модульным тестом, а проводка тестирования запускает все модульные тесты в каталоге. И т.д.
Стив Беннетт
1
Другой пример: если вы работаете на двух компьютерах, и вам разрешено перемещать данные из A в B, но не из B в A. Если вы создаете новый фрагмент кода для решения проблемы, которая сначала возникает на B, но вы и для A, и для B, вы хотите иметь возможность сохранить файл на B, так что когда вы воссоздаете этот файл на A и затем переносите его в связку, вы можете выполнить git diff для сохраненной версии, чтобы убедиться, что вы этого не делали. сделать ошибку.
Гдаля
7
Тот факт, что файл не отслеживается в одной ветви, не означает, что он не будет конфликтовать с отслеживаемым файлом в другой ветви.
JWG
3
простой контрпример: файл конфигурации в каталоге .conf.d, или любой другой, который, только находясь там, изменяет поведение программного обеспечения.
Фотанус
Конечно функциональность нужна. В качестве дополнительного примера невозможно переключиться с одной ветви на другую, если у вас есть локально неотслеживаемые файлы, которые вы хотите сохранить.
Демитриан