Добавить все файлы в коммит, кроме одного?
У меня есть набор файлов в наборе изменений, но я хочу специально игнорировать один измененный файл. Выглядит так после git status
:
# modified: main/dontcheckmein.txt
# deleted: main/plzcheckmein.c
# deleted: main/plzcheckmein2.c
...
Есть ли способ, которым я могу сделать git add
но просто игнорировать один текстовый файл, который я не хочу трогать? Что-то вроде:
git add -u -except main/dontcheckmein.txt
20 ответов
Сейчас git
опоры exclude certain paths and files
магией пути :(exclude)
и его краткая форма :!
, Таким образом, вы можете легко добиться этого как следующая команда.
git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt
На самом деле вы можете указать больше:
git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
1) Чтобы начать игнорировать изменения в одном уже версионном файле
git update-index --assume-unchanged "main/dontcheckmein.txt"
и отменить это git update-index --no-assume-unchanged "main/dontcheckmein.txt"
2) Полностью игнорировать определенный отдельный файл, предотвращая его создание в хранилище
Первый взгляд на этот Git Global игнорировать не работает
и в .gitignore
добавить относительный путь к файлу без начального ./
так что если ваш файл в MyProject/MyFolder/myfile.txt
(где .git
также в MyProject
), в .gitignore
ты положил только это MyFolder/myfile.txt
Вы можете подтвердить, какое правило относится к игнорированию с помощью git check-ignore "MyFolder/myfile.txt"
О глобальном игнорировании
Эта ссылка говорит о ~/.gitignore_global
; но файл связан с вашим проектом; так что, если вы поставите шаблон исключения MyFolder/myfile.txt
в ~/.gitignore_global
, это будет работать, но не будет иметь особого смысла...
С другой стороны, если вы настраиваете свой проект с git config core.excludesfile .gitignore
где .gitignore
я сидела MyProject
; эта настройка переопределит ~/.gitignore_global
это может иметь очень полезные правила...
Итак, на данный момент, я думаю, что лучше всего сделать сценарий, чтобы смешать .gitignore
с ~/.gitignore_global
в .gitignore
,
Последнее предупреждение
Если файл, который вы хотите игнорировать, уже находится в хранилище, этот метод не будет работать, если вы не сделаете это: git rm "MyFolder/myfile.txt"
, но сначала сделайте резервную копию, так как она также будет удалена локально! Вы можете скопировать его позже...
Для файла
git add -u
git reset -- main/dontcheckmein.txt
Для папки
git add -u
git reset -- main/*
Git предоставляет
:(exclude)
префикс pathspecs для исключаемых путей.
Его короткая магическая подпись — .
Документация: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-exclude
git add . :^main/dontcheckmein.txt
В некоторых ответах на эту тему упоминается
:!
, что тоже будет работать, но только с кавычками . В целом,
!
считается ужасным персонажем для расширения оболочки.
Если вы похожи на меня — всегда проверяйте, что будет зафиксировано с помощью
-p
флаг в
git add
команда —
:^
магическая подпись тоже работает как шарм:
git add -p . :^main/dontcheckmein.txt
Хотя Бен Джексон прав, я подумал, что добавлю, как я использовал это решение. Ниже приведен очень простой скрипт, который я использую (который я называю gitadd), чтобы добавить все изменения, кроме избранных, которые я держу в списке в файле с именем .gittrackignore
(очень похоже на то, как работает.gitignore).
#!/bin/bash
set -e
git add -A
git reset `cat .gittrackignore`
И это то, что мой нынешний .gittrackignore
похоже.
project.properties
Я работаю над проектом Android, который я компилирую из командной строки при развертывании. Этот проект зависит от SherlockActionBar, поэтому на него нужно ссылаться в project.properties, но это мешает компиляции, поэтому сейчас я просто набираю gitadd
и добавьте все изменения в git без необходимости каждый раз удалять add.properties.
Чтобы сохранить изменения в файле, но не для фиксации, я сделал это
git add .
git reset -- main/dontcheckmein.txt
git commit -m "commit message"
чтобы убедиться, что файл исключен, сделайте
git status
Мы можем добавить все файлы и исключить файл, который необходимо удалить с помощью git reset.
git add .
git reset -- <file_name_to_exclude>
Использование git add -A
добавить все измененные и вновь добавленные файлы одновременно.
пример
git add -A
git reset -- main/dontcheckmein.txt
добавить все файлы
git добавить .
получить путь к файлу для вставки ниже
статус git
удалить из коммита
git reset -- файл/к/путь/файл-к-игнорированию.txt
Для конкретного случая, о котором идет речь, самым простым способом было бы добавить все файлы с расширением .c и пропустить все остальное:
git add *.c
Из git-scm (или / и man git add
):
git add
… Файлы для добавления контента. Fileglobs (например, *.c) могут быть предоставлены для добавления всех соответствующих файлов. <...>
Обратите внимание, что это означает, что вы также можете сделать что-то вроде:
git add **/main/*
добавить все файлы (которые не игнорируются), которые находятся в main
папка. Вы можете даже сходить с ума с более сложными образцами:
git add **/s?c/*Service*
Выше добавит все файлы, которые находятся в s(any char)c
папка и есть Service
где-то в их имени файла.
Очевидно, вы не ограничены одним шаблоном на команду. То есть вы можете попросить git добавить все файлы с расширением .c и .h:
git add *.c *.h
Эта ссылка может дать вам больше идей по шаблону.
Я нахожу это особенно полезным, когда я делаю много изменений, но все же хочу, чтобы мои коммиты оставались атомарными и отражали постепенный процесс, а не мешанину изменений, над которыми я, возможно, работаю в то время. Конечно, в какой-то момент стоимость разработки сложных шаблонов перевешивает стоимость добавления файлов с более простыми методами или даже одного файла за раз. Тем не менее, в большинстве случаев я легко могу указать только нужные мне файлы простым шаблоном и исключить все остальное.
Кстати, вам может понадобиться процитировать ваши шаблоны глобуса, чтобы они работали, но для меня это никогда не было так.
Не напрямую то, что вы просили, поскольку это не достигается одной командой, но результат должен быть таким, как вы хотите.
После добавления всех файлов в промежуточную область через
git add -u
печатание
git status
предложит вам
git restore --staged main/dontcheckmein.txt
вы можете использовать рекомендации git
добавить все изменения файлов и восстановить файл, который не хочет нажимать
git add .
git restore --staged <file_not_push>
Если вы хотите игнорировать определенный файл каждый раз, есть три эффективных решения, не связанных с файлами .
Добавьте файл, который вы хотите игнорировать, в
.git/info/exclude
. Он работает так же, как ваш.gitignore
, за исключением того, что конфигурация специфична для вашей машины .Сбросьте файл, который вы хотите использовать, с помощью git hook перед фиксацией . Например:
$ echo 'git reset -- src/main/resources/log4j.properties' >> .git/hooks/pre-commit $ chmod +x .git/hooks/pre-commit
Хук pre-commit запускается непосредственно перед фиксацией. Таким образом, ваши файлы могут быть автоматически сброшены перед каждым коммитом.
$ git status On branch CHANGE-137-notifications-support ... Changes not staged for commit: modified: Dockerfile modified: src/main/resources/log4j.properties $ git add . $ git status On branch CHANGE-137-notifications-support ... Changes to be committed: modified: Dockerfile modified: src/main/resources/log4j.properties $ git commit -m "Trivial change" Unstaged changes after reset: M src/main/resources/log4j.properties [CHANGE-137-notifications-support 97cfb3f] Trivial change 1 file changed, 3 insertions(+)
Третий способ — обновить индекс для конкретного файла.
$ git update-index --assume-unchanged src/main/resources/log4j.properties
Изменения, которые необходимо зафиксировать: (используйте "git reset HEAD ..." для удаления)
Согласно книге Pro Git .
Скотт Чакон, Бен Штрауб.
Есть 2 подхода к достижению:
git сброс
$ git reset HEAD main/dontcheckmein.txt
В Git версии 2.23.0 появилась новая команда: git restoration . По сути, это альтернатива git reset, о котором мы только что рассказали. Начиная с версии Git 2.23.0, Git будет использовать git Restoration вместо git Reset для многих операций отмены.
git восстановление
$ git restore --staged main/dontcheckmein.txt
:warning: Важно понимать, что git restre <file> — опасная команда. Любые локальные изменения, внесенные вами в этот файл, исчезли — Git просто заменил этот файл последней подготовленной или зафиксированной версией. Никогда не используйте эту команду, если вы не уверены, что вам не нужны эти несохраненные локальные изменения.
:предупреждение: Это правда, что команда git reset может быть опасной, особенно если вы указали флаг --hard . Однако в описанном выше сценарии файл в вашем рабочем каталоге не затрагивается, поэтому это относительно безопасно.
Я использую git add --patch
совсем немного и хотел что-то подобное, чтобы избежать необходимости постоянно нажимать на d через одни и те же файлы. Я набрал пару хакерских псевдонимов, чтобы выполнить работу:
[alias]
HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
ap = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"
В моем случае я просто хотел постоянно игнорировать определенные минимизированные файлы, но вы могли бы заставить его использовать переменную окружения, такую как $GIT_EXCLUDE_PATTERN
для более общего случая использования.
Вы можете попробовать это: git add * && git reset main/dontcheckmein.txt