Исключить подпроект коммит Git - PullRequest
1 голос
/ 30 сентября 2019

Как исключить Subproject commit .... Я ничего не изменил в подмодуле, только извлекал изменения из удаленного репозитория! Я думаю, что я сделал что-то ненужное в основном хранилище, когда создал субмодуль. Любые идеи?

1) Когда я создал подмодуль git diff в основном хранилище, также показал

submodule-path:
    Subproject commit 5a8162ff9a602deb96956854346988e1ee45672e

, и я зафиксировал это

2) затемкто-то зафиксировал субмодуль, поэтому он имеет следующий журнал

2ff89a2bfcaa0 last commit
5a8162ff9a602d  first commit

3) Я обновил субмодуль с помощью

git submodule update --remote --merge

4) теперь git status показывает

modified:   submodule-path (new commits)

Но я ничего не изменил в подмодуле, только вытащил последние удаленные изменения! И мне нужны эти последние изменения

git diff показывает

diff --git a/submodule-path b/submodule-path
index 5a8162f..2ff89a2 160000
--- a/submodule-path
+++ b/submodule-path
@@ -1 +1 @@
-Subproject commit 5a8162ff9a602deb96956854346988e1ee45672e
+Subproject commit 2ff89a2bfcaa014885a70b0da86e997ecd8d0688

Ответы [ 3 ]

1 голос
/ 30 сентября 2019

Обновление:

Это НЕ ошибка. Подмодули просто работают таким образом.

Главный репо не отслеживает файлы субмодуля. Он отслеживает только URL подмодуля и идентификатор фиксации ( состояние подмодуля в определенной точке ).

Цитата из раздела «Начало работы с подмодулями» в книге Pro Git

Хотя sbmodule DbConnector является подкаталогом в вашем рабочем каталоге, Gitвидит его как подмодуль и не отслеживает его содержимое, когда вы не в этом каталоге. Вместо этого Git видит его как особый коммит из этого репозитория .

Поскольку вы обновили модуль с помощью git submodule update, вы должны выполнить изменение (фактически, обновленноесовершить идентификатор). Если вы не хотите обновлять отслеживание подмодулей, просто не используйте git submodule update в начале или просто отмените изменение.


Весьма вероятно, что подмодуль отключен от HEAD. Зайдите в подмодуль, перезагрузите подмодуль, чтобы зафиксировать отключенное состояние HEAD.

# Do this in the submodule
git reset --hard origin/master

Затем обновите подмодуль до последней фиксации.

# run in the project's root, not the submodule's
git submodule update --remote --merge
1 голос
/ 30 сентября 2019

Во-первых, давайте попробуем прояснить некоторые вещи здесь. Это сложно, потому что когда вы работаете с Git самостоятельно, это сложно. Когда вы добавляете второй репозиторий Git, в который вы git push делаете свои собственные коммиты, и из которого вы git fetch делаете новые коммиты других людей, , то также усложняется. Подмодуль - это не что иное, как третий Git-репозиторий, и этот третий Git-репозиторий имеет четвертый Git-репозиторий, в который вы, возможно, можете git push свои собственные коммиты, и из которого вы можетеgit fetch новые коммиты других людей. Таким образом, мы прыгаем прямо в ситуацию, в которой есть по крайней мере четыре репозитория Git, все они несколько независимы друг от друга.

Мы могли бы попытаться рисовать картинки, но даже картинкибудет немного грязноКак мы можем поддерживать четыре хранилища прямо? У Git есть имена для двух из них: два, с которыми вы работаете напрямую, сами. Одним из них является суперпроект , в котором вы работаете git diff и видите:

diff --git a/submodule-path b/submodule-path
index 5a8162f..2ff89a2 160000
--- a/submodule-path
+++ b/submodule-path
@@ -1 +1 @@
-Subproject commit 5a8162ff9a602deb96956854346988e1ee45672e
+Subproject commit 2ff89a2bfcaa014885a70b0da86e997ecd8d0688

Другой - это сам подмодуль: если вы cd submodule-pathи запустив различные команды Git, вы увидите, что это обычный Git-репозиторий. Единственное, что необычно в этом, это то, что он почти всегда находится в режиме «отсоединенного HEAD».

Ваш суперпроект Git, вероятно, имеет origin. Это репозиторий, ну, технически, короткое имя, которое вы можете использовать в этом Git для , ссылается на другой репозиторий, который вы можете git push зафиксировать, сделанный в суперпроекте. Вам потребуется сделать коммит в суперпроекте, а затем git push этот новый коммит в origin. Что именно входит в этот суперпроект коммит? Мы скоро увидим.

Ваш подмодуль Git также имеет origin. Это другой другой репозиторий Git: четвертый Git на этой не очень хорошо прорисованной картине. Мне не ясно, хотите ли вы отправить коммиты в этот четвертый репозиторий. Возможно, вы do хотите получить коммит из этого хранилища. Есть несколько способов сделать это, включая использование git submodule update --remote, возможно, с дополнительными опциями. Я предпочитаю просто cd submodule-path и начать работать непосредственно в подмодуле Git , поскольку это сводит проблему к вещам, которые вы уже знаете, как делать: манипулировать одним локальным репозиторием Git на основе новых коммитов, которые появились в его origin.

Предположим, вы просто хотите получить новые коммиты в подмодуле

Если это так, вы можете:

cd submodule-path           # begin working in your submodule
git fetch                   # update origin/*
git checkout origin/master  # get a detached HEAD on the desired commit
                            # (this assumes `origin/master` is the
                            # desired commit; it's impossible for me
                            # to know which commit you desire)

итеперь подмодуль имеет желаемый коммит в качестве отдельного заголовка. Отсюда git push нечего: все коммиты, которые находятся в этом репозитории, являются коммитами, полученными из Git этого подмодуля origin.

(Использование git submodule update --remote может сделать cd submodue-path и git fetch и git checkout origin/master для вас, все без изменения собственного рабочего каталога. Вся операция выполняется в своей собственной под-оболочке, так что ни одна из этих операций cd не влияет на то, где вы находитесь. Это похоже на то, что ваш git submodule update --remote --mergeсделал: не было необходимости делать новый коммит слияния, поэтому он просто переключился на коммит, определенный по некоторому имени ветки в origin.)

Но если вам нужно сделать новые коммиты в подмодуле .. .

В этом случае вы можете захотеть заставить субмодуль работать в ветке, чтобы вы работали в более нормальном рабочем процессе. Тогда вы, вероятно, захотите, например, git checkout master, а затем выполнять различные команды. В конечном итоге вы можете получить новый коммит, сделанный в вашем хранилище субмодулей, который вам потребуется git push в origin репозиторий из субмодуля, чтобы другие люди могли получить этот коммиттоже.

Вы можете оставить подмодуль в его ветке. Ветвь подмодуля не имеет отношения к суперпроекту Git: суперпроект Git заботится только о том, какой commit извлечен в подмодуле. (Вот почему в более раннем случае, приведенном выше, мы можем просто переключить отсоединенную головку.)

НетЕсли субмодуль Git находится на правильном коммите, вы должны сделать новый коммит суперпроекта

. На этом этапе вы можете cd вернуться из субмодуля в суперпроект. В git diff вы увидите что-то в точности как вы цитировали выше, и git status скажет:

modified:   submodule-path (new commits)

Это не обязательно означает, что есть какие-то new фиксирует в хранилище подмодулей, которых нет в хранилище подмодулей origin. Это просто означает, что репозиторий подмодулей включен (как его HEAD, отсоединен или нет) коммит, который не является коммитом, который текущий статус суперпроекта говорит, что должен быть включен.

Проблемаздесь то, что текущий коммит суперпроекта, в некотором смысле, неисправен. Это было правильно, но это больше не так, поскольку текущий коммит суперпроекта был бы дефектным, если бы вы, скажем, редактировали файл README.md локально. Это означает, что вам нужно сделать в суперпроекте новый исправленный коммит. Суперпроект Git сделает новый коммит из того, что находится в индексе репозитория суперпроекта, так что теперь вам нужно обновить индекс.

Если вы изменили файл README.md, то какобновить индекс:

git add README.md

Но то, что вы изменили, не было README.md файлом. Вместо этого это был хеш-идентификатор субмодуля. Таким образом, вам нужно записать новый идентификатор хеша в индексе. Вот как вы это делаете:

git add submodule-path

Это берет хеш-идентификатор из подмодуля, выполнив cd submodule-path; git rev-parse HEAD, чтобы получить необработанный хеш-идентификатор - тот, который появился в git diff - и прочее, чтоID хеша в индекс. Теперь git diff - который сравнивает индекс с вашим рабочим деревом - не будет отображать эти Subproject commit строки больше, но git diff --cached - который сравнивает текущую (суперпроектную) фиксацию с индексом - покажет . Теперь git status скажет, что эти «новые коммиты» готовы к фиксации, а не «еще не подготовлены для фиксации».

Вы можете git add любые другие файлы суперпроекта (если они есть)которые должны быть обновлены в индексе) в это время. Затем:

git commit

в суперпроекте создаст новый коммит, в котором будет записан хэш-идентификатор, который вы указали в индексе суперпроекта, когда вы запустили git add в пути подмодуля.

You '(локально) мы выполнили обновление, но вот некоторые вещи, о которых стоит подумать

Обратите внимание, что каждый коммит в суперпроекте записывает хэш-идентификатор в подмодуле. Каждый раз, когда вы git checkout делаете другой коммит суперпроекта, который не только извлекает правильные файлы суперпроекта в индекс (суперпроекта) и ваше (суперпроект) рабочее дерево, он также извлекает записанный хеш-идентификатор субмодуля в индекс (суперпроекта). не , по умолчанию, cd в подмодуле и git checkout этой конкретной фиксации по его хэш-идентификатору. Вы можете изменить это с помощью параметра или добавить --recursive к git checkout;или вы можете просто запустить git submodule update, который сообщает вашему Git cd в каждый подмодуль, по одному, и git checkout идентификатор хеша, который в настоящее время записан в индексе (суперпроекта).

Вы будетев какой-то момент необходимо git push новый коммит, который вы сделали в своем суперпроекте, до origin (суперпроекта), чтобы новый коммит с его новым записанным идентификатором хеша появился в Git над origin вашего суперпроекта. Вы можете делать это в любое время - но предположим, что вы сделали сделали новые коммиты в вашего подмодуля, и вы еще не использовали git push в самом подмодуле для отправки этих новых коммитовorigin субмодуля. В этом случае новый коммит, который вы сделали в суперпроекте, записывает хэш-идентификатор коммита, который существует только в вашем локальном хранилище субмодулей . Если кто-то запустит git fetch для суперпроекта Git origin, он получит этот новый хэш-идентификатор из нового отправленного вами коммита, но не сможет найти , который коммитит в их клон подмодуля. Так что, если вы сделали новые коммиты подмодулей, обычно лучше сначала git push их, , а затем git push новый суперпроект коммитов.

(Если выне делал никаких новых подмодульных коммитов, здесь нет проблем.)

0 голосов
/ 30 сентября 2019

Выполнение команды git submodule update -f --init должно решить вашу проблему, это сбросит ваш подмодуль на удаленный HEAD

...