Як я можу змусити git ігнорувати майбутні редакції файлу?


140

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

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

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

Узагальнити,

  1. Я хотів би створити файл, називати його, default_values.txtякий додається до мого сховища git і включається, коли хтось клонує це сховище.
  2. git add .не слід додавати default_values.txtдо комітів.
  3. Таку поведінку слід передати будь-яким клонам сховища.

1
Чи можете ви скористатись гачками git, щоб мати гачок попереднього фіксації, який би перервав комісію, якщо модифікованим файлом є default_values.txt (скажіть)?
sateesh

1
Пуристи з Git говорять, що не лінуйтеся та правильно використовуйте інсценізаційну зону, саме для цього і потрібно.
Xint0

Пуристи Git, як кажуть, використовують сценарії розмиття / очищення. Це найрентабельніше рішення.
Адам Дімітрук

1
Xint0: вірно. але як запобігти випадковому заїзду до інших людей?
Алан

Відповіді:


115

Як багато інших згадували, хорошим сучасним рішенням є:

git update-index --skip-worktree default_values.txt

Це дозволить ігнорувати зміни цього файлу, як локальні, так і висхідні, поки ви не вирішите знову дозволити їх:

git update-index --no-skip-worktree default_values.txt

Ви можете отримати список файлів, позначених пропущеними:

git ls-files -v . | grep ^S

Зауважте, що на відміну від цього --skip-worktree, --assume-unchangedстатус втрачається, коли буде проведено зміну вище за течією.


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

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

3
Зауважте, що вам, можливо, доведеться скасувати --skip-worktreeстатус файлу, перш ніж ви зможете перемикати гілки, якщо цей самий файл відстежується в іншій гілці.
moodboom

3
хм, це працює ... після того, як я змінив файл, він не відображався git status, але коли я спробував перейти на іншу гілку, я потрапив error: Your local changes to the following files would be overwritten by checkout: , навіть -f не допомагаєerror: Entry 'wix-stores-merchant-app/demo/credentials.js' not uptodate. Cannot merge.
ykravv

1
Мені це дозволено git ignoreі git unignore.
Михайло

48

Що ви шукаєте, так і є git update-index --assume-unchanged default_values.txt.

Докладніше див. У документах: http://www.kernel.org/pub/software/scm/git/docs/git-update-index.html


11
це не працює. хоча це змушує додавати git. ігноруйте файл у локальній гілці, клон архіву не має такої поведінки (якщо ви зміните default_values.txt у клонованому архіві, він буде доданий до комітету з "git add.")
Марк

6
Так, тому що ви встановлюєте це лише для місцевого репо. Ви не можете надсилати таку інформацію.
tamasd

8
@Indradhanush - це рішення не задовольняє критерію 3 - "поведінку слід передати будь-яким клонам сховища" - саме тому я її не прийняв. Це не означає, що це не є вдалою відповіддю.
Марк

Я ніколи не помічав 3-го критерію. Тому що я не шукав цього. :)
Індрадхануш Гупта

3
Для локальних файлів конфігурації з налаштуваннями приватних додатків ви, ймовірно, хочете використовувати skip-worktreeзамість assume-unchangedдодаткової інформації stackoverflow.com/questions/13630849/…
Аарон Хоффман

22

Я зазвичай бачив підхід - створити файл з іншим іменем, наприклад: default_values_template.txt і помістити default_values.txt у свій .gitignore. Доручіть людям копіювати default_values_template.txt до default_values.txt у свої локальні робочі простори та вносити необхідні зміни.


hmmm ... можливо, я можу написати гачок, щоб автоматично скопіювати default_values_template в default_values, якщо default_values ​​не існує?
Марк

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

Я думаю, що рішення дійсно полягає в тому, щоб зробити щось подібне, бажано зі сценарієм, який виконується щоразу, коли ви тягнете або клонуєте. Ідеєю було б те, що все, що має певне розширення (скажімо, .basefile), буде скопійовано у файл із розширенням, а потім ім'я файлу додається до .gitignore в цьому каталозі. Тому я створив би файл default_values.txt.basefile і вчинив би це. У мене немає грі чи перл-коттів, щоб це зробити, але я попрошу свого друга, який це робить, і повідомляю, як це відбувається.
Марк

1
@AdamDymitruk: Так, в цьому випадку можна використовувати очищення / розмазання, але далеко не ясно, що це найкращий варіант. Наприклад, це зробить досить важким, якщо люди дійсно хочуть змінити файл, оскільки очищення / розмазання буде заважати. Я б фактично віддав перевагу описаному тут підходу.
sleske

1
Я беру підказку від самого git (конкретно git hooks) і використовую .sampleсуфікс. Тож у вашому випадкуdefault_values.txt.sample
tir38

5

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

Коли ви зробите це, ви "очистите" його, замінивши певну інформацію про машину загальною інформацією або інформацією про місця.

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

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


Чи сценарії «Очищення і розмазання» є локальними або частиною репо?
Алан

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

Мені потрібно прочитати трохи більше про це. В основному я хочу налаштувати проект, який має за замовчуванням, user.jsonякий потрібно перезаписати з кожним кредитом розробників, але я не хочу, щоб розробник випадково перевірив їхні записи.
Алан

Я б погукав навколо для чистих сценаріїв розмазання. Подивіться, що виходить. Крім того, стрибайте по кімнаті git irc на freenode. Ви отримаєте допомогу негайно.
Адам Дімітрук

3

Я вирішив це, визначивши фільтр "чистий", щоб просто передати вміст файлу в індексі.

git show :path/to/myfile слід просто надрукувати вміст індексу для вказаного файлу, щоб ми могли використовувати його в скрипті для заміни робочої копії недоторканою копією в індексі:

#! /bin/sh

git show :$1

Встановіть це як "чистий" фільтр для відповідного файлу (припустимо, що ви його помістили в "discard_changes"):

$ git config filter.ignore_myfile.clean "discard_changes path/to/myfile"
$ echo "path/to/myfile filter=ignore_myfile" >> .gitattributes

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


1

Я знайшов рішення, яке працює для моєї команди. Ми ділимося нашими githooks за допомогою символьних посилань, і після додавання файлу шаблону до git я додав гачок, який попередньо здійснює, який перевіряє, чи файл шаблону був змінений, і якщо так, то я git reset -- templatefile.txt. Якщо це єдиний змінений файл, я також скасовую комісію.


-1

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


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

@Marc ознайомтеся з командами Visual Studio Team Services, необмеженими безкоштовними приватними проектами та сховищами git. Kanban дошки, відстеження робочих предметів та помилок, асоціюйте чеки з робочими предметами, керуйте спринтами, якщо ви входите в scrum чи інші типи проектів. Окрім того, що у нього є чудові інструменти побудови для побудови на кількох платформах, занадто багато речей, про які можна згадати, всі вони безкоштовні. Деякі люди шлакують це через те, що його Microsoft, але він передає б'є, що може запропонувати github щодо інструментів, крім простого хостингу репозиторію. Є обмеження того, що можна зробити безкоштовно, але я їх рідко перевищую.
Аран Малхолланд

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