Git - ігноруйте файли під час об’єднання


114

У мене є репо зателефонований myrepoна пультbeanstalk сервері .

Я клонував це до своєї місцевої машини. Створено дві додаткові галузі: stagingі dev. Ці гілки натискали і на віддалений.

Зараз:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

У мене є файл, config.xmlякий називається, різний у кожній гілці.

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

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

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

Дякую!


У режимі за замовчуванням git pull є скороченням для git fetch з подальшим об'єднанням git FETCH_HEAD. Таким чином, ви заявляєте свого роду конфлікт один з одним.
zzk

Ну, я б сказав, його замовлення. Не тягнути. Я оновлю питання, щоб було зрозуміло.
Кевін Рейв


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

ви розглядали символічні (не супроводжувані git) чи навіть тверді посилання на допомогу?
Френк Нокк

Відповіді:


94

Я вирішив цю проблему, використовуючи команду git merge з --no-commitопцією, а потім явно видалив поетапний файл і проігнорував зміни у файлі. Наприклад: скажіть, що я хочу ігнорувати будь-які зміни, myfile.txtя дію так:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

Ви можете помістити оператори 2 і 3 у цикл for for, якщо у вас є список файлів, які потрібно пропустити.


2
Я б додав "--no-ff", якщо ви хочете, щоб файл не був перезаписаний, коли злиття відбувається в стратегії швидкого перемотування.
Ілля Шакітко

1
так що git reset HEAD myfile.txtробити саме? Як це допомагає нашій меті тут?
Kid_Learning_C

Як ви ставите рядки 2 і 3 в циклі?
AndroidDev

52

Я закінчила пошук git attributes. Пробуючи це. Працюючи поки що. Ще не перевірили всі сценарії. Але це повинно бути рішенням.

Стратегії злиття - атрибути Git


4
але я знайшов це git-scm.com/book/ch7-2.html#Merge-Strategies
Nate-

1
Ось правильне посилання для розділу стратегій злиття атрибутів git docs: git-scm.com/book/en/v2/…
Адріан Лауренці

3
Це було добре пояснено у статті medium.com/@porteneuve/…
ShawnFeatherly

10
Це здається проблемою, якщо немає конфліктів? Файли все ще об’єднаються?
Бретт

18

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

Ви можете вказати атрибут, щоб сказати Git використовувати різні стратегії злиття для конкретного файлу. Тут ми хочемо зберегти існуюче config.xmlдля нашої галузі. Нам потрібно встановити , merge=oursщоб config.xmlв .gitattributesфайлі.

merge=ours скажіть git використовувати наш (поточний відділення) файл, якщо виникає конфлікт злиття.

  1. Додайте .gitattributesфайл на кореневому рівні сховища

  2. Ви можете встановити атрибут для .gitattributesфайлу confix.xml

    config.xml merge=ours
    
  3. А потім визначте манекен нашої стратегії злиття з:

    $ git config --global merge.ours.driver true
    

Якщо ви об'єднаєте відділення stagформи dev, замість того, щоб злиття конфліктувало з файлом config.xml, файл config.xml контуру зберігайте в будь-якій версії, в якій ви були спочатку.


16
Але що робити, якщо конфлікту немає? Як завжди зберігати певний файл під час злиття?
Ігор Яловий

2
@IgorYalovoy: Якщо конфлікту немає ... ну, це трохи хитро, оскільки це насправді працює з хеш-ідентифікаторів, але: якщо config.xmlвін повністю не змінився від бази злиття до будь-якої версії наконечника гілки, Git просто приймає змінену версію, без дивлячись на merge.ours.driverналаштування. Значить, ви правильно заклопотані.
торек

1
Скопіюйте-вставте з Git Docs: стратегії об’єднання - атрибути Git. Посилання
kyb

Цей метод призводить до "злиття здійснює" кожен раз, коли FYI.
рсмет

2
"наша", як видається, є довільною назвою для нової стратегії, яка впроваджується. Я вважав це заплутаним, оскільки theirsце вбудована стратегія злиття. Але здається, що можна писати <pattern> merge=foo, значить git config --global merge.foo.driver true, і це буде працювати так само.
Кайл Странд

8

Ви можете почати з використання git merge --no-commit, а потім відредагувати злиття, як вам подобається, тобто, відмінивши config.xmlбудь-який файл або будь-який інший файл, після чого скористайтеся. Я підозрюю, що ви хочете додатково автоматизувати його за допомогою гачків, але, думаю, варто було б пройти вручну хоча б раз.


2
Чи git attributesпропонується якесь пряме рішення? Я не в змозі цього зрозуміти. git-scm.com/book/en/…
Кевін Рейв

4

Ви можете використовувати, .gitignoreщоб не зберігати config.xmlсховище, а потім використовувати гак для фіксації публікації, щоб завантажити відповідний config.xmlфайл на сервер.


1
Я знаю, це такий злом. Я намагаюся знайти чисте рішення. Як щодо мерзотника attributes. Будь-яка ідея, як це працює? Я не в змозі цього зрозуміти. git-scm.com/book/en/…
Кевін Рейв

1
Я не чув про них, я намагаюся застосувати атрибут merge = ours, виглядає перспективно.
thlehman

1
Атрибути Git - приголомшливі! Ви навіть можете сказати git, як відрізняти нетекстові файли, щоб ви могли використовувати pdf2text для розрізнення PDF-файлів!
tlehman

2

Приклад:

  1. У вас є дві гілки: master,develop
  2. Ви створили файл у developвідділенні і хочете його ігнорувати під час об’єднання

Код:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

Ви також можете ігнорувати файли з тим же розширенням

наприклад, усі файли з .txtрозширенням:

echo "*.txt merge=ours" >> .gitattributes

1

Тут git-update-index - Зареєструйте вміст файлів у робочому дереві до індексу.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Приклад: -

git update-index --assume-unchanged somelocation/pom.xml


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

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