Вопрос не сформирован, но как только форма исправлена, ответ , вероятно, да. Но , который да, и какой ответ вы хотите, зависит от того, что вы действительно имеете в виду.
Каждый коммит содержит снимок. Ни один коммит не содержит изменений , так же, как если у вас есть несколько фотографий (возможно, вас самого разного возраста), ни одна фотография не содержит никаких изменений. Но, возможно, у вас было больше (или больше) волос на одной фотографии, чем на другой, так что при сравнении двух фотографий вы можете наблюдать изменения.
Проблема, как вы, вероятно, теперь можете видеть, заключается в том, что вам нужно выбрать два снимка . Какие две вас волнуют? Вы можете выбрать любые два, но только два - или, ну, два одновременно.
Что волнует Git , так это различные коммиты. Каждый из них, как мы только что сказали, содержит снимок - но он также содержит немного больше. Он содержит имя и адрес электронной почты человека, который сделал снимок, например. Он содержит дату и время. (На самом деле у него есть и автор и коммиттер , дающий два имени, адреса электронной почты и метки времени.) В нем есть сообщение журнала, написанное тем, кто сделал коммит, чтобы сообщить вам почему они совершили этот коммит. И каждый коммит хранит хеш-идентификатор своего родительского коммита (или коммитов в случае коммита слияния). Этот дополнительный материал представляет собой метаданные для фиксации, основные данные которого являются исходным снимком.
Каждый коммит имеет свой уникальный хэш-идентификатор. Этот хэш-идентификатор, который выглядит случайным, на самом деле является просто криптографической контрольной суммой содержимого этого коммита (данные + метаданные). Этот хэш-идентификатор - это то, как Git на самом деле находит фиксацию - как он получает содержимое фиксации (данные + метаданные) из основной базы данных, которую хранит Git. Вы видели эти хеш-идентификаторы в выводе git log
и сокращенные версии повсюду - Git остро нуждается в них, так как они являются реальными именами внутренних объектов Git, поэтому неизбежно, что Git покажет вам некоторые из них. Например, они выглядят как b5101f929789889c2e536d915698f58d5c5c6b7a
. Хотя они довольно бесполезны для людей: их слишком сложно запомнить; Я должен вырезать и вставить их, чтобы получить их правильно.
При наличии любого конкретного хеш-идентификатора коммита Git может получить коммит и его метаданные. Эти метаданные включают в себя идентификатор хэша родительского коммита коммита, поэтому Git теперь может также выявлять родителя. Затем Git может сравнить два коммита , и это то, что вы видите, например, git log -p
output: результат этого сравнения. И git log
, и git show
уменьшают полный снимок до набора изменений, по сравнению с родительским коммитом этого коммита . Отсюда и два снимка.
Теперь, поскольку коммит имеет хеш-идентификатор своего родителя, который имеет другой хеш-идентификатор своего родителя и т. Д., Мы можем нарисовать коммиты как длинный ряд узлов, указывающих назад, с каждым узлом, представляющим коммит и стрелку, выходящую из этого узла в качестве хеш-идентификатора родителя:
... <-o <-o <-o ...
Но чтобы начать этот процесс, мы должны знать некоторый начальный (конечный?) Хэш-идентификатор. Мы могли бы записать эти большие уродливые хэш-идентификаторы или вырезать и вставить их много, но у нас есть компьютер. Почему бы компьютеру не сохранить хэш-идентификатор для нас? Это где имена филиалов входят.
На самом деле, имя ветки - это место для хранения одного (1) хеш-идентификатора. Мы храним идентификатор хэша последнего коммита в ветке:
...--F--G--H <-- master (HEAD)
(НПрежде чем я использовал прописные буквы, такие как H
вместо реального хэша, просто чтобы о них было проще говорить.) Чтобы сделать new commit, мы возьмемся за исходный код в нашей работе. tree, используйте git add
, чтобы Git обновил готовые к снимку копии файлов, а затем используйте git commit
, чтобы собрать метаданные и сделать новый снимок. Это получает новый, непредсказуемый хэш-идентификатор. Помните, что одним из входных данных является время , поэтому даже если мы прогнозируем источник и наше имя, сообщение журнала и т. Д., Мы не будем знать, каким будет хеш-идентификатор, пока мы не нажмем Enter или не нажмем кнопка "make commit" или что-то еще.
В любом случае мы получаем новый коммит с новым хеш-идентификатором, который мы можем просто вызвать I
:
...--F--G--H <-- master (HEAD)
\
I
Родитель
I
H
. Теперь перейдем к хитрому, но в то же время мастерскому трюку: Git записывает фактический хэш-идентификатор commit I
в текущее имя ветви , master
. Мы можем выправить наш рисунок, как мы теперь имеем:
...--F--G--H--I <-- master (HEAD)
У нас есть новый снимок, чьим родителем является старый снимок.
Если мы создадим новую ветку сейчас, мы получим два имени, указывающих на коммит I
:
...--F--G--H--I <-- feature, master (HEAD)
Обратите внимание, что все коммиты находятся в обеих ветвях. Мы можем переключить , к которой ветвь имеет HEAD
, присоединенную к ней, используя git checkout feature
:
...--F--G--H--I <-- feature (HEAD), master
и теперь, если мы сделаем новый коммит J
, это будет только на feature
:
...--F--G--H--I <-- master
\
J <-- feature
Теперь у вас есть большинство частей, которые вам нужны, чтобы ответить на свой вопрос
Я собираюсь перенести codeToExtract в новый репозиторий.
Предположительно, вы имеете в виду, что намереваетесь взять файлы, имена которых находятся в этом каталоге / папке, из каких-либо коммитов и поместить их в новый репозиторий. Пока все хорошо.
Есть ли способ найти ветки, которые имеют изменения в этой папке?
Как вы теперь знаете, ни ветки, ни коммиты не имеют изменений , но ветки позволяют найти коммиты, и если вы выберете любые два конкретных снимка (коммита), вы можете сравнить им.
Помните, что некоторые коммиты могут быть во многих ветвях. Это зависит от вас, что вы хотите сделать с этим, если что-нибудь. Кроме того, вы сами решаете, сравнивать ли каждый проверяемый вами коммит с его родителем (-ями) или с фиксированным снимком фиксированной начальной или конечной точки. Вы можете, например, иметь график, который включает, в частности:
o--o--*--K
/ \
...--o--*--o--*--L---M--o <-- br1
\
o--*--o--o <-- br2
, где каждый *
коммит имеет, по сравнению со своим родителем, некоторые различия в файлах в одной рассматриваемой папке.
Вам также необходимо решить, что делать с коммит слияния . Это коммиты с более чем одним родителем. Я дал один интересный коммит слияния над буквой M
, а каждому из двух родителей прислали буквы K
и L
(хотя на самом деле все они будут просто ужасными хэш-идентификаторы). Коммит слияния M
имеет снимок, как и любой другой коммит. Но его трудно сравнить с его родителем, потому что у него нет одного родителя, у него есть двух родителей.
Вам решать, что с этим делать. Если вы решите принять (файлы из) оба *
коммитов, которые являются родителями K
и L
соответственно, вы, вероятно, захотите также взять (файлы из) коммит M
, , даже если эти файлы совпадают с K
и / или L
.
Вполне возможно, что вас это не волнует: может быть, вы просто захотите посмотреть коммит tip из каждой ветви и сравнить каждый из них со всеми Другой такой совет обязывает выяснить, какую версию (и) файла (ов) из одной папки вы хотите. Если это то, что вам нужно, вы можете использовать git diff
для этих сравнений: дайте git diff
два хеш-идентификатора коммита, и он будет сравнивать снимки в этих двух коммитах. Присвойте ему два имени ветви, например master
и feature
, или br1
и br2
, и он будет сравнивать снимки двух коммитов, идентифицированных этими именами, без выполнения родительских ссылок.
Как только вы выясните, какой ответ вы хотите - или на какой вопрос вы хотите ответить - вы можете использовать его, чтобы получить то, что вы хотите.