Ігнорувати нові коміти для підмодуля git


83

Передумови

Використання Git 1.8.1.1 на Linux. Сховище виглядає наступним чином:

master
  book

Підмодуль був створений таким чином:

$ cd /path/to/master
$ git submodule add https://user@bitbucket.org/user/repo.git book

bookПодмодуль чистий:

$ cd /path/to/master/book/
$ git status
# On branch master
nothing to commit, working directory clean

Проблема

Майстер, з іншого боку, показує, що для підмодуля книги є "нові коміти":

$ cd /path/to/master/
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   book (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")

Git повинен повністю ігнорувати каталог підмодулів, щоб ведучий також був чистим:

$ cd /path/to/master/
$ git status
# On branch master
nothing to commit, working directory clean

Невдала спроба №1 - брудна

Усередині файлу master/.gitmodulesє наступне, згідно з цією відповіддю :

[submodule "book"]
        path = book
        url = https://user@bitbucket.org/user/repo.git
        ignore = dirty

Невдала спроба №2 - без відстеження

Змінено master/.gitmodulesна наступне, відповідно до цієї відповіді :

[submodule "book"]
        path = book
        url = https://user@bitbucket.org/user/repo.git
        ignore = untracked

Невдала спроба №3 - showUntrackedFiles

Відповідно master/.git/configдо цієї відповіді :

[status]
   showUntrackedFiles = no

Невдала спроба №4 - ігнорувати

Додав каталог книг до головного файлу ігнорування:

$ cd /path/to/master/
$ echo book > .gitignore

Невдала спроба №5 - клон

Додано каталог книг до шаблону наступним чином:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://user@bitbucket.org/user/repo.git book

Питання

Як bookпідмодуль може знаходитись у власному каталозі сховища під masterсховищем, але git ігнорує bookпідмодуль? Тобто, не повинно відображатися:

#
#       modified:   book (new commits)
#

Як придушити це повідомлення під час виконання git statusу головному сховищі?

Стаття про підводні камені git підказує, що це невідповідне використання підмодуля?


3
Зазвичай ви використовуєте підмодулі, якщо хочете пов’язати сховище з певною версією іншого сховища, і відстежувати це. Але це не схоже на те, що ви хочете. Ви просто хочете використовувати сховище всередині іншого, не відстежуючи його. Тоді не додайте його як підмодуль.
Фелікс Клінг,

@FelixKling, якщо ви додасте такі репозитарії таким чином і відсунете їх на GitHub, чи створить він просто посилання для нього, не копіюючи вміст цих папок?
Роман Беккієв

@Roland: Підмодулі - це лише файли з посиланням на версію іншого сховища. Після ініціалізації в локальній копії сховища вони замінюються фактичним вмістом сховища.
Фелікс Клінг

2
Я думаю, ви шукаєте "ignore = all"
greuze

1
З Git 2.13 (Q2 2017) ви зможете розглянути git config submodule.<name>.active false. Дивіться мою відповідь нижче
VonC

Відповіді:


60

Щоб включити інше сховище, яке не потрібно відстежувати у своєму супер-репо, спробуйте наступне:

$ cd /path/to/master/
$ rm -rf book
$ git clone https://user@bitbucket.org/user/repo.git book
$ git add book
$ echo "book" >> .gitignore

Потім здійсніть.

Як зазначено в статті про підводні камені підмодуля git :

... єдиним зв'язком між батьківським та підмодулем є [[]] записане значення вивільненого SHA підмодуля, яке зберігається у батьківських комітах.

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

Коли ви перевіряєте інший коміт у підмодулі або робите новий коміт у ньому, супер-репо побачить, що його перевірений SHA змінився. Саме тоді ви отримуєте modified (new commits)лінію від git status.

Щоб усунути це, ви можете:

  • git submodule update, Який скине подмодуль в Ком збережені в супер-репозиторії (подробиці див в git submoduleдовідкової сторінці , або
  • git add book && git commit щоб зберегти новий SHA у супер-репо.

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


3
Ого, тепер я розумію, чому супермодуль повинен знати версію підмодуля. Звичайно, це має сенс робити git add book && git commit. Я не розумів, що git насправді може забезпечити синхронізацію двох репозиторіїв.
Сергій Оршанський

103

Просто запустіть:

$ git submodule update

Це поверне підмодуль до старого коміту (зазначеного в parent-repo), не оновлюючи батьківський repo з останньою версією підмодуля.


6
Ні, це не так, це не змінить статус.
Ед Бішоп,

Чому саме OP хотів би не мати останніх версій зі bookсховища? Я не думаю, що ваша відповідь має сенс у цьому контексті.
Alexis Wilke,

@AlexisWilke, а якщо інтерфейс книги різко змінився, і OP не встигає внести зміни в майстер-репо?
Логман

Це відповідь, яку я шукав!
LLSv2.0

21

Є два типи сповіщень про зміни, які ви можете припинити (з git 1.7.2).

Перший - це відстежений вміст, який трапляється, коли ви вносите зміни до свого підмодуля, але ще не ввели їх. Батьківське сховище зауважує це, і статус git повідомляє про це відповідно:

modified: book (untracked content)

Ви можете придушити це за допомогою:

[submodule "book"]
    path = modules/media
    url = https://user@bitbucket.org/user/repo.git
    ignore = dirty

Однак, як тільки ви внесете ці зміни, батьківський репозитарій знову прийме повідомлення та повідомить про них відповідно:

modified:   book (new commits)

Якщо ви теж хочете їх придушити, вам потрібно ігнорувати всі зміни

[submodule "book"]
    path = book
    url = https://user@bitbucket.org/user/repo.git
    ignore = all

Уявіть, я додав ignore = allопцію до всіх підмодулів. Врешті-решт деякі модулі мають нові коміти, які були висунуті. Якщо хтось потім клонує супер-репо, чи буде він у старому стані підмодулів, або він перевірить найновіші?
FelikZ

За допомогою команди git clone --recursive git@...ви отримаєте старий стан підмодулів. Щоб їх оновити, вам знадобиться щось на кшталт git submodule foreach "git pull"після клонування
марля

1
На жаль, ignore = allпараметр не ігнорує нові коміти підмодуля. Я використовую git версії 1.7.1. Будь-який спосіб ідеї?
Ромул

10

Git 2.13 (Q2 2017) додасть ще один спосіб включити підмодуль, який не потрібно відстежувати за його батьківським репо.

У випадку з ОП:

git config submodule.<name>.active false

Див здійснювати 1b614c0 , здійснювати 1f8d711 , здійснюють bb62e0a , Комміт 3e7eaed , здійснюють a086f92 (17 мар 2017), а також здійснювати ee92ab9 , здійснюють 25b31f1 , здійснюють e7849a9 , здійснюють 6dc9f01 , здійснюють 5c2bd8b (16 Mar 2017) по Брендон Вільямс ( mbrandonw) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті a93dcb0 , 30 березня 2017 р.)

submodule: роз'єднати url та підмодуль відсотка

В даний час submodule.<name>.urlпараметр config використовується, щоб визначити, чи є даний підмодуль цікавим для користувача. Це в кінцевому підсумку є громіздким у світі, де ми хочемо, щоб різні підмодулі перевірялися на різних робочих деревах або більш узагальнений механізм вибору, які підмодулі представляють інтерес.

У майбутньому з підтримкою робочого дерева для підмодулів буде кілька робочих дерев, кожному з яких може знадобитися лише підмножина перевірених підмодулів.
URL-адреса (де можна отримати сховище підмодулів) не повинна відрізнятися між різними робочими деревами.

Користувачам також може бути зручніше легше вказати групи підмодулів, які їх цікавлять, на відміну від запуску кожного " git submodule init <path>" підмодуля, який вони хочуть перевірити у своєму робочому дереві.

З цією метою вводяться два параметри конфігурації submodule.activeта submodule.<name>.active.

  • submodule.activeКонфігурації мають pathspec , що визначає , який повинен існувати подмодуль в робочому дереві.
    • submodule.<name>.activeКонфігурації є булевої прапор , який використовується для вказівки, що конкретний подмодуль повинен існувати в робочому дереві.

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

  1. Підмодулі можна згрупувати з провідним каталогом, таким чином, що специфікація шляху, наприклад, ' lib/' охоплює всі модулі бібліотеки-іш, щоб дозволити тим, хто цікавиться модулями бібліотеки-іш, встановити " submodule.active = lib/" лише один раз, щоб сказати, що всі модулі в ' lib/' є цікаво.
  2. Після винайдення функції pathspec-attribute користувачі можуть мітити підмодулі атрибутами, щоб згрупувати їх, так що широка специфікація pathspec з вимогами до атрибутів, наприклад, ' :(attr:lib)', може бути використана для того, щоб сказати, що будь-які модулі з libатрибутом ' ' цікаві.
    Оскільки .gitattributesфайл, як і .gitmodulesфайл, відслідковується суперпроектом, коли підмодуль рухається в дереві суперпроекту, проект може налаштувати, в який шлях потрапляє атрибут .gitattributes, так само, як він може налаштувати, в якому шляху знаходиться підмодуль .gitmodules.

Як знайти точний <name>для підмодуля в існуючому проекті?
ideasman42

@ Ideasman42 Читання конфігурації в .gitmodules має допомогти: stackoverflow.com/a/12641787/6309
VonC

Ах, це просто значення від .git/config->[submodule "<name>"]
ideaman42

1
Не працює для мене. Ось що я роблю: 1) git clone з --recursive; 2) встановити git config як відповідь; 3) зробити git checkout, git pull, щоб перевірити останній підмодуль; Все одно отримуємо "(нові коміти)".
Ву Байцюань,

2
@VonC Перед тим, як надіслати вам повідомлення, я спробував обидва (як з існуючим, так і новим ініціалізованим репо), в обох випадках це не спрацювало.
Дикобраз

3

Відповідь Невіка Ренеля, безперечно, є правильною для того, що ви запитуєте: я не хотів мати підмодуль, як, чорт вазьми, я виходжу з цієї ситуації ?! .

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

У вашому випадку ви вносите зміни до bookрепозиторію і в якийсь момент фіксуєте ці зміни. Це означає, що у вас є нові коміти в цьому підмодулі, які мають нове посилання SHA1.

Що потрібно зробити в головному каталозі, це зафіксувати ці зміни в головному сховищі.

cd /path/to/master
git commit . -m "Update 'book' in master"

Це оновить посилання на SHA1 masterдо останньої версії, доступної у bookсховищі. Як результат, цей коміт дозволяє іншим перевірити всі репозиторії master& bookна кінчику.

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


-5

Біжи

git submodule update 

на кореневому рівні.


Просто для тих, хто цікавиться. У моєму випадку (і ОП?) Це не змінює git statusсказаного. Він все ще вважає, що зміни відбулись.
скваризм

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