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


1437

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


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

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


Что если вы не хотите хранить изменения, которые уже есть в индексе? Возможно ли сохранить новый файл?
— 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

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


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}

Это не удаляло неотслеживаемые файлы с моего компьютера, хотя они больше не были перечислены как неотслеживаемые. 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или эквивалент, чтобы сделать существование в долгосрочной перспективе.

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


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

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"

По крайней мере, в моей системе ваше предположение неверно. Работает без слеша! Пустые каталоги игнорируются в любом случае. (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), меньше, чем неудобство, вызванное работой и необходимым вниманием, в противном случае стоило бы попытаться добавить файл без отслеживания в ваш тайник


15
Это зависит от проекта. Допустим, неотслеживаемый файл является (наполовину написанным) модульным тестом, а проводка тестирования запускает все модульные тесты в каталоге. И т.д.
— Стив Беннетт

1
Другой пример: если вы работаете на двух компьютерах, и вам разрешено перемещать данные из A в B, но не из B в A. Если вы создаете новый фрагмент кода для решения проблемы, которая сначала возникает на B, но вы и для A, и для B, вы хотите иметь возможность сохранить файл на B, так что когда вы воссоздаете этот файл на A и затем переносите его в связку, вы можете выполнить git diff для сохраненной версии, чтобы убедиться, что вы этого не делали. сделать ошибку.
— Гдаля

7
Тот факт, что файл не отслеживается в одной ветви, не означает, что он не будет конфликтовать с отслеживаемым файлом в другой ветви.
— JWG

3
простой контрпример: файл конфигурации в каталоге .conf.d, или любой другой, который, только находясь там, изменяет поведение программного обеспечения.
— Фотанус

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