Як зупинити відстеження та ігнорувати зміни до файлу в Git?


1731

Я клонував проект, який включає деякі .csprojфайли. Мені не потрібно / подобається, що мої локальні csprojфайли відслідковуються Git (або виховуються під час створення патчу), але явно вони потрібні в проекті.

Я додав *.csprojдо мого LOCAL .gitignore, але файли вже є у репо.

Коли я набираю статус git, він показує мої зміни, csprojякі мені не цікаво відстежувати та надсилати патчі.

Як я можу видалити "відстеження" цих файлів із особистого репортажу (але зберігати їх у джерелі, щоб я міг їх використовувати), щоб я не бачив змін, коли я створюю статус (або створюю патч)?

Чи є правильний / канонічний спосіб вирішення цієї ситуації?


18
Дуже корисне питання, але мені цікаво, чому ви не хочете відслідковувати зміни у .csprojфайлі, що дуже важлива частина будь-якого проекту. Зміни у .csproj.userфайлі чи будь-яких .Publish.XMLфайлах я можу повністю зрозуміти, не відстежуючи, але мене заінтригувало, чому ви не хочете відслідковувати .csproj
Owen Blacker

7
Можливо, вони використовують інший IDE?
Джаретт

3
Як не дивно, я прийшов до цієї теми, тому що я хочу видалити .suo файли з репо, але зберігати їх локально. Що стосується нащадків, розробка .Net вимагає від вас зберігати .csproj файли в репо, і ці зміни слід завжди відслідковувати, якщо ви не хочете відчувати гнів будь-яких інших розробників вашого проекту. Якщо ви колись не впевнені, подивіться репортаж файлів gitignore на GitHub: github.com/github/gitignore/blob/master/VisualStudio.gitignore
longda

1
@Cupcake, питання, з яким ви пов’язали, було написане через 15 днів після цього? Можливо, ви маєте на увазі іншого?
stephenmurdoch

Канонічні питання @marflar не обов'язково повинні бути найстарішими , а лише найкращими . На одну, з якою я пов’язаний, є 20 відповідей, а на цю лише 5.

Відповіді:


2129

Просто зателефонувавши git rm --cachedдо кожного з файлів, які ви хочете видалити з контролю редагування, має бути добре. Поки ваші локальні схеми ігнорування правильні, ви не побачите цих файлів, що містяться у виведенні статусу git.

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

Щоб git не виявляла змін у цих файлах, слід також скористатися цією командою:

git update-index --assume-unchanged [path]

Що ви, мабуть, хочете зробити: (знизу відповідь @Ryan Taylor )

  1. Це означає, щоб git хотів отримати власну незалежну версію файлу чи папки. Наприклад, ви не хочете перезаписувати (або видаляти) конфігураційні файли виробництва / постановки.

git update-index --skip-worktree <path-name>

Повна відповідь тут у цій URL-адресі: http://source.kohlerville.com/2009/02/untrack-files-in-git/


187
"git rm --cached <file>" видалить <file> з контролю версій, зберігаючи його у робочому сховищі. Будь то, що ти хочеш ...
Якуб Нарбскі

51
Але коли інші витягнуть сховище, чи буде видалений власний файл * .csproj? Тому що, якщо ми хочемо, щоб файл не відслідковувався, а не був видалений.
FMaz008

23
Якщо ви намагаєтесь видалити ВСІ файли в каталозі, комбінуйте їх з git ls-файлами: git ls-files | xargs git rm --cached- це видалить усе з індексу git у заданому каталозі, не видаляючи фактичні файли.
Марко

129
git rm --cached -r <dir>працює рекурсивно для папки та всіх файлів у ній.
Кріс К

41
Це зупинить відстеження файлу, збереже його на локальному рівні, але призведе до видалення для всіх, хто тягне
Едвард Ньюелл

249

Якщо ви зробите це git update-index --assume-unchanged file.csproj, git не перевірятиме файл file.csproj на зміни автоматично: це зупинятиме їх появу у статусі git кожного разу, коли ви їх зміните. Таким чином, ви можете позначати всі ваші .csproj файли таким чином - хоча вам доведеться вручну позначити всі нові, які вам надсилає репортаж вище. (Якщо вони є у вашому .gitignoreабо .git/info/exclude, то створені вами ігноруються)

Я не зовсім впевнений, що таке .csproj-файли ... якщо вони щось в порядку конфігурацій IDE (подібне до файлів Eclipse. всі. З іншого боку, якщо вони є частиною системи збирання (як Makefiles), то, очевидно, вони повинні --- і спосіб отримати необов'язкові локальні зміни (наприклад, з local.csproj a la config.mk) був би корисним : розділити накопичення на глобальні частини та локальні зміни.


8
csproj - файл проекту C #, який відслідковує, які файли включені у ваш проект та інші кілька конфігурацій, ОБОВ'ЯЗКОВО слід контролювати джерело, щоб проект працював
SparK

4
Тут єдина правильна відповідь! Я використовую @araqnids відповідь протягом багатьох років, і вона працює саме так, як вимагається для вирішення цієї проблеми.
NHDaly

Яке значення префіксу 'файл' у аргументі команди? Чому це не просто .csproj?
GreenAsJade

1
Чи можна виявити, що це було зроблено для файлу, або для яких файлів це було зроблено в репо? Я трохи нервую, коли забуваю, що я це зробив, а потім цікаво, чому чорт цей файл не оновлюється, згодом!
GreenAsJade

4
@GreenAsJade: git ls-files -vвідображатимуться файли, які вважаються незмінними з малим показником (наприклад, hзамість звичайного Hдля кешованих файлів).
Амадан

238

Є 3 варіанти, ви, мабуть, хочете №3

1. Це збереже локальний файл для вас, але видалить його для всіх інших, коли вони потягнуть.

git rm --cached <file-name> або git rm -r --cached <folder-name>

2. Це для оптимізації, як папка з великою кількістю файлів, наприклад, SDK, які, ймовірно, ніколи не зміняться. Він говорить git кожен раз переставати перевіряти цю величезну папку для змін, оскільки її не буде. assume-unchangedІндекс буде обнулений і файл (и) перезаписані , якщо є вгору по течії зміни в файлі / папці (при витягуванні).

git update-index --assume-unchanged <path-name>

3. Це означає, щоб git хотів отримати власну незалежну версію файлу чи папки. Наприклад, ви не хочете перезаписувати (або видаляти) конфігураційні файли виробництва / постановки.

git update-index --skip-worktree <path-name>

Це важливо знати git update-index не поширюватиметься з git, і кожному користувачеві доведеться запускати його самостійно.


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

1
Як я можу перевірити в моїй локальній програмі, які файли застосовуються для "припустити-не змінюється" або "пропустити робоче дерево"?
Supawat Pusavanno

3
@SupawatPusavanno, щоб побачити, які файли, які ви раніше вибрали для припущення без змін або пропустити робоче дерево, подивіться на цю відповідь stackoverflow.com/questions/42363881/… - вона використовує grepтаgit ls-files
Ryan Taylor

1
Дуже гарна відповідь. Але git видає помилку, коли я намагаюся переключитися на іншу гілку: помилка: "Ваші локальні зміни до наступних файлів будуть перезаписані під замовлення .....", і рішення полягає в тому, щоб приховати зміни перед переключенням і зняти приховування, коли ти повертаєшся до гілки.
PhantomReference

@RyanTaylor: Я спробував спочатку припустити незмінний (не працював) і пропустити команду worktree (не працював), коли я перевіряю зі статусом git, чи не відображаються файли, значить, команда працювала. Але коли я знову it gives me error that your local changes would be overwrittenвитягую код з репоту git origin у цих двох файлах, так що це означає, що це не розв’язує так?
NeverGiveUp161

152

Це два етапи:

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

    git rm --cached 
    

    Зараз вони не відображаються як "змінені", але все ще показують як

        untracked files in  git status -u  
    
  2. Додайте їх до .gitignore


56
Ні, це видалить файл із відстеження, збереже його локально, але призведе до видалення для всіх, хто тягне .
Едвард Ньюелл

1
У моєму випадку я випадково додав папку, яку я не хотів відслідковувати, тому це мені було потрібно.
Сонні

4
Так, це дійсно неправильна відповідь на поставлене запитання - але це, мабуть, правильна відповідь для більшості людей, які знаходять це питання в результатах пошуку (як я).
Ендрю Спенсер

95

Прийнята відповідь все ще не працювала для мене

я використав

git rm -r - кешований.

git add.

git commit -m "виправлення. gitignore"

Знайшов відповідь звідси


Це посилання дуже корисно, особливо для рекурсивного видалення всіх файлів у .gitignore
rmcsharry

9
Я повернувся сюди 3 рази, сподіваюся, я можу взяти на себе пам’ять до наступного разу!
Гаррі Бош

Коментар @Edward Newell, як і у наведеній вище відповіді, застосовується і тут: "це видалить файл відстеження, збереже його локально, але призведе до видалення для всіх, хто тягне ".
ToJo

46

Забули свій .gitignore?

Якщо у вас весь проект локально, але ви забули додати вам git ignore і тепер відстежуєте непотрібні файли, використовуйте цю команду, щоб видалити все

git rm --cached -r .

переконайтеся, що ви в корені проекту.

Тоді можна обійтися звичайним

Додайте

git add .

Здійснити

git commit -m 'removed all and added with git ignore'

Штовхати

git push origin master

Висновок

Сподіваюсь, це допоможе людям, які мають внести зміни до своїх .gitignoreабо забули це разом.

  • Він видаляє весь кеш
  • Дивиться на ваш .gitignore
  • Додає файли, які потрібно відстежувати
  • Натискає на ваше репо

4
Коли ви говорите про видалення або додавання, ви забуваєте сказати, коли і де. Видалення зі списку треків? З сховища? З місцевого простору проекту? Зняття при витягуванні? На фіксацію? На натиску? На жаль, у всіх авторів тут одна і та ж проблема.
Gangnus

3
@Gangnus Я не думаю, що хтось «уточнив» точку, яку ви намагаєтеся зробити, тому що цілком очевидно, що файл насправді не видаляється з диска чи сховища. У цій відповіді вказується хронологічний порядок команд. Це не таємниче чи не пояснене, як підказав ваш коментар.
Ентоні

Коментар @Edward Newell, як і у наведеній вище відповіді, застосовується і тут: "це видалить файл відстеження, збереже його локально, але призведе до видалення для всіх, хто тягне ".
ToJo

26

Як вказувалося в інших відповідях, обрана відповідь неправильна.

Відповідь на інше питання передбачає , що це може бути пропуск worktree , які будуть потрібні.

git update-index --skip-worktree <file>

2
Ні, не дуже: --skip-worktreeвикористовується для збереження файлу у сховищі, але припиняє відслідковувати його зміни . Як говориться у вашій відповіді: --skip-worktree корисний, коли ви доручаєте git не торкатися певного файлу ніколи, оскільки розробники повинні його змінити
Ердал Г.

4
@ErdalG. Саме так. Відповідно до запитання, вони хочуть ігнорувати будь-які зміни у файлі, але зберігають файл у
репортажі

Погодьтеся з @the_new_mr, --assume-unchangedі --skip-worktreeмають подібний ефект, але їх цілі зовсім інші. Перший - для прискорення продуктивності git, обманувши git не перевіряти конкретні файли , а другий - для ігнорування майбутніх змін окремих файлів , які підходять для виконання, але необхідні файли.
Віктор Вонг

22

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

git rm --cached app/**/*.xml

або

git rm --cached -r app/widgets/yourfolder/

тощо


Це дуже хороша причина рішення, у будь-якому випадку ви хочете виправити gitignore крок за кроком
cutiko

15

Щоб запобігти моніторингу файлу git

git update-index --assume-unchanged [file-path]

І повернути його назад

git update-index --no-assume-unchanged [file-path]

Репо для посилання на подібні випадки використання https://github.com/awslabs/git-secrets


1
Спасибі поради були рятівниками життя, дякую!
Хамман Самуель

9

Багато людей радять використовувати git update-index --assume-unchanged. Дійсно, це може бути вдалим рішенням, але лише в короткостроковій перспективі.

Те , що ви , ймовірно , хочете зробити це: git update-index --skip-worktree.

(Третій варіант, який ви, мабуть, не бажаєте:) git rm --cached. Він збереже ваш локальний файл, але буде позначений як видалений з віддаленого сховища.)

Різниця між першими двома варіантами?

  • assume-unchangedполягає в тимчасовому дозволі приховати модифікації з файлу. Якщо ви хочете приховати зміни, внесені до файлу, змінити файл, а потім оформити іншу гілку, вам доведеться використовувати no-assume-unchangedтоді, ймовірно, зроблені сховані зміни.
  • skip-worktree буде стежити за вами будь-якою філією, яку ви оформили, з вашими змінами!

Використовуйте корпус assume-unchanged

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

Мені подобається використовувати його, коли я хочу лише на деякий час зупинити відстеження змін + здійснити купу файлів ( git commit -a), пов’язаних з тією ж модифікацією.

Використовуйте корпус skip-worktree

У вас є клас налаштування, що містить параметри (наприклад, включаючи паролі), які ваші друзі повинні змінити відповідно до їх налаштування.

  • 1: Створіть першу версію цього класу, заповніть поля, які ви можете заповнити, а інші залиште порожніми / null.
  • 2: Введіть і натисніть на віддалений сервер.
  • 3: git update-index --skip-worktree MySetupClass.java
  • 4: Оновіть свій клас конфігурації за допомогою власних параметрів.
  • 5: Поверніться до роботи над іншою функціональністю.

Зміни, які ви робите, підуть за вами, незалежно від галузі. Попередження: якщо ваші друзі також хочуть змінити цей клас, вони повинні мати однакові настройки, інакше їх модифікації будуть перенесені у віддалений сховище. Під час витягування віддалена версія файлу повинна перезаписати вашу.

PS: робіть те чи інше, але не обидва, оскільки у вас виникнуть небажані побічні ефекти. Якщо ви хочете спробувати інший прапор, попередньо слід вимкнути останній.


7

Щоб сказати Git не відстежувати зміни у вашому локальному файлі / папці (значить, статус git не виявить зміни в ньому), зробіть:

git update-index --skip-worktree path/to/file

І щоб сказати Git знову відстежувати зміни у вашій локальній версії (щоб ви могли здійснити зміни), виконайте:

git update-index --no-skip-worktree path/to/file

1

відповідь однієї лінії git update-index --assume-unchanged [path]

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

Найкращий приклад: конфігураційний файл для з'єднань з БД . У центральному репо-сервері ви матимете все ім’я користувача, пароль, хост, порт зі значеннями виробничого сервера БД. Але в локальному розробнику ви повинні використовувати лише локальний або будь-який інший сервер БД розробки (який налаштовує ваша команда). У цьому випадку ви хочете внести зміни в конфігураційний файл, але не повинні привласнюватися до центрального репо.

Найкраще


0

Я припускаю, що ви запитуєте, як видалити ВСІ файли в певній папці або папці bin, а не вибирати кожен файл окремо.

Ви можете використовувати цю команду:

git rm -r -f /<floder-name>\*

Переконайтеся, що ви перебуваєте у батьківському каталозі цього каталогу.
Ця команда буде рекурсивно "видаляти" всі файли, які знаходяться в bin / або build / папках. Під словом delete я маю на увазі, що git зробить вигляд, що ці файли "видалено" і ці файли не будуть відслідковуватися. Git дійсно позначає ці файли у режимі видалення.

Переконайтеся, що ви готові .gitignore готові до майбутніх подій.
Документація: git rm


0

Проблема може бути викликана порядком роботи. Якщо ви змінили спочатку .gitignore, а потім git rm --cached xxx, можливо, вам доведеться продовжувати стикатися з цією проблемою.

Правильне рішення:

  1. git rm - кешований ххх
  2. змінив .gitignore

Замовляйте інваріант!

Перезавантаження .gitignore після модифікації!


0

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

git update-index - замінити -змінним

Ex - git update-index --assume-unchanged .gitignore .idea / compiler.xml


0

Щоб ігнорувати будь-які зміни всіх файлів (певного типу) у каталозі, мені довелося поєднувати деякі з цих підходів, інакше файли були створені, якщо вони раніше не існували.

Нижче, "ludirir "- це назва каталогу, в якому я не хочу дивитися зміни.

Спочатку видаліть усі наявні нові файли з кешу відстеження змін (не видаляючи з вашої файлової системи).

git status | grep "new file:" | cut  --complement -d " " -f1-4 | grep "^excludedir" | xargs git rm --cache

Ви можете зробити те ж саме і з modified:. renamed:трохи складніше, тому що вам доведеться переглянути ->біт публікації для нового імені файлу і зробити попередній ->біт, як описано deleted:нижче.

deleted: Файли виявляються трохи складнішими, тому що ви не можете здати оновлення-індекс для файлу, який не існує в локальній системі

echo .deletedfiles >> .gitignore
git status | grep "deleted:" | cut  --complement -d " " -f1-4 | grep "^excludedir" > .deletedfiles
cat .deletedfiles | xargs -d '\n' touch
cat .deletedfiles | xargs -d '\n' git add -f
cat .deletedfiles | xargs -d '\n' git update-index --assume-unchanged
cat .deletedfiles | xargs -d '\n' rm

Остання команда у наведеному вище списку знову видалить файли з вашої файлової системи, тому сміливо пропустіть це.

Потім заблокуйте відстеження змін із цього каталогу

git ls-files excludedir/ | xargs git update-index --skip-worktree
git update index --skip-worktree excludedir/

0

У цій відповіді був запропонований майже git без команд :

Щоб ігнорувати певні файли для кожного локального репо :

  1. Створіть файл ~/.gitignore_global, наприклад, touch ~/.gitignore_globalу своєму терміналі.
  2. Бігайте git config --global core.excludesfile ~/.gitignore_globalраз.
  3. Напишіть шлях до файлу / dir, який ви хочете ігнорувати ~/.gitignore_global. наприклад modules/*.H, який буде вважатись у вашому робочому каталозі, тобто $WORK_DIR/modules/*.H.

Щоб ігнорувати певні файли для одного локального репо :

  1. Виконайте вищенаведений третій крок для файлу .git/info/excludeв рамках репо, тобто запишіть файли / редактори, які ви хочете ігнорувати .git/info/exclude. наприклад modules/*.C, який буде вважатись у вашому робочому каталозі, тобто $WORK_DIR/modules/*.C.

0

Застосувати .gitignore до теперішнього / майбутнього

Цей метод застосовує стандартну поведінку .gitignore і не вимагає вручну вказувати файли, які потрібно ігнорувати .

Більше не можна використовувати --exclude-from=.gitignore: / - Ось оновлений метод:

Загальна порада: почніть з чистого репо-репортажу - все, що зроблено, нічого не очікує на робочий каталог чи індекс, і зробіть резервну копію !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

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


-1

після тривалого пошуку, знайдіть спосіб зробити це. псевдонім команда git в .gitconfig.like в проекті андроїд-студії check перед тим, як оформити замовлення, відновити конфігураційний файл, а потім пропустити його , після відділення оформлення замовлення використовувати sedзмінити конфігураційний файл у мій локальний конфігуратор. checkoutandmodifylocalproperties = !git update-index --no-skip-worktree local.properties && git checkout local.properties && git checkout $1 && git update-index --skip-worktree local.properties && sed -i '' 's/.*sdk.dir.*/sdk.dir=\\/Users\\/run\\/Library\\/Android\\/sdk/g' local.properties && :

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