10 ответов:
хотя Dav прав, что информация не хранится непосредственно, это не значит, что вы никогда не сможете узнать. Вот несколько вещей, которые вы можете сделать.
найти ветви фиксация включена
git branch --contains <commit>это расскажет вам все ветви, которые имеют данную фиксацию в своей истории. Очевидно, что это менее полезно, если фиксация уже была объединена.
Поиск reflogs
если вы работаете в репозитории, в котором была сделана фиксация, вы можете искать reflogs для строки для этой фиксации. Reflogs старше 90 дней обрезаются git-gc, поэтому, если фиксация слишком стара, вы ее не найдете. Тем не менее, вы можете сделать это:
git reflog show --all | grep a871742чтобы найти фиксацию a871742. Вывод должен быть примерно таким:
a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewriteуказывает, что фиксация была сделана на ветке "завершение". Выходные данные по умолчанию показывают сокращенные хэши фиксации, поэтому не ищите полный хэш, иначе вы не найдете что угодно.
git reflog showна самом деле это просто псевдоним дляgit log -g --abbrev-commit --pretty=oneline, так что если вы хотите возиться с выходным форматом, чтобы сделать различные вещи доступными для grep, это ваша отправная точка!если вы не работаете в репозитории, где была сделана фиксация, лучшее, что вы можете сделать в этом случае, это изучить рефлоги и найти, когда фиксация была впервые введена в ваше РЕПО; если Вам повезет, вы выбрали ветку, в которую она была зафиксирована. Это немного сложнее, потому что вы не может ходить как дерево фиксации, так и reflogs одновременно. Вы хотите парсить вывод reflog, осматривая каждый хэш, чтобы увидеть, если она содержит нужный коммит или нет.
найти последующую фиксацию
это зависит от рабочего процесса, но с хорошими рабочими процессами фиксации выполняются в ветвях разработки, которые затем объединяются. Вы могли бы сделать это:
git log --merges <commit>..чтобы увидеть коммиты слияния, которые имеют данный коммит в качестве предка. (Если фиксация была только объединена один раз первым должно быть слияние, которое вы ищете; в противном случае вам придется изучить несколько, я полагаю.) Сообщение фиксации слияния должно содержать имя ветви, которая была объединена.
если вы хотите иметь возможность рассчитывать на это, вы можете использовать до
git mergeдля принудительного создания фиксации слияния даже в случае быстрой перемотки вперед. (Не слишком стремитесь, хотя, это может стать запутанным, если злоупотреблять.) VonC это ответ на вопрос услужливо подробно останавливается на этой теме.
Обновление Декабрь 2013 Года:
git-what-branch(сценарий Perl, см. ниже), похоже, больше не поддерживается.git-when-mergedэто альтернатива, написанная на Python, которая работает очень хорошо для меня.он основан на "найти слияние фиксации, которые включают в себя определенную фиксацию".
git when-merged [OPTIONS] COMMIT [BRANCH...]найти когда фиксация была объединена в одну или несколько ветвей.
Найдите фиксацию слияния, которая принеслаCOMMITв указанную ветвь (Ы).в частности, найдите самую старую фиксацию в истории первого родителя
BRANCHСCOMMITкак предок.
оригинальный ответ сентябрь 2010 года:
Себастьен Шарко просто twitted (за 16 минут до этого так ответ):
git-what-branch: узнайте, в какой ветви находится фиксация, или как она попала в именованную ветвь
это Perl script С Сет Робертсон это кажется очень интересным:
справка
git-what-branch [--allref] [--all] [--topo-order | --date-order ] [--quiet] [--reference-branch=branchname] [--reference=reference] <commit-hash/tag>...обзор
расскажите нам (по умолчанию) о самой ранней причинной связи путь коммитов и слияний, чтобы вызвать запрошенную фиксацию, попал в именованную ветвь.
Если фиксация была сделана непосредственно на именованной ветви, это, очевидно, самый ранний путь.под самым ранним каузальным путем мы подразумеваем путь, который слился в именованную ветвь раньше всего, по времени фиксации (если только
--topo-orderуказан).производительность
если многие ветви (например, сотни) содержат фиксацию, система может занять много времени (для конкретной фиксации в дереве linux потребовалось 8 секунд, чтобы изучить ветвь, но было более 200 возможных ветвей), чтобы отследить путь к каждой фиксации.
Выбор конкретного--reference-branch --reference tagпроверять будет в сотни раз быстрее (если у вас есть сотни ветвей-кандидатов).примеры
# git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path: v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May 5 08:59:37 2005) v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May 3 18:27:24 2005) v2.6.12-rc3-461-g84e48b6 is on master v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n [...]эта программа не учитывает эффекты вишневого выбора фиксации интереса, только операции слияния.
например, чтобы найти, что
c0118facommit пришел отredesign_interactions* ccfd449 (HEAD -> develop) Require to return undef if no digits found * 93dd5ff Merge pull request #4 from KES777/clean_api |\ | * 39d82d1 Fix tc0118faests for debugging debugger internals | * ed67179 Move &push_frame out of core | * 2fd84b5 Do not lose info about call point | * 3ab09a2 Improve debugger output: Show info about emitted events | * a435005 Merge branch 'redesign_interactions' into clean_api | |\ | | * a06cc29 Code comments | | * d5d6266 Remove copy/paste code | | * c0118fa Allow command to choose how continue interaction | | * 19cb534 Emit &interact eventвы должны выполнить:
git log c0118fa..HEAD --ancestry-path --mergesи прокрутите вниз, чтобы найти последнего слияние commit. А именно:
commit a435005445a6752dfe788b8d994e155b3cd9778f Merge: 0953cac a06cc29 Author: Eugen Konkov Date: Sat Oct 1 00:54:18 2016 +0300 Merge branch 'redesign_interactions' into clean_apiUPD
Или только одна команда:git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1
эта простая команда работает как шарм:
git name-rev <SHA>например(где test-branch название филиала):
git name-rev 651ad3a 251ad3a remotes/origin/test-branchдаже для сложных сценариев, как:
origin/branchA/ /branchB /commit<SHA1> /commit<SHA2>здесь
git name-rev commit<SHA2>возвращает branchB
git branch --contains <ref>Это самая очевидная команда "фарфор", чтобы сделать это. Если вы хотите сделать что-то подобное только с командами "сантехника":COMMIT=$(git rev-parse <ref>) # expands hash if needed for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do if $(git rev-list $BRANCH | fgrep -q $COMMIT); then echo $BRANCH fi done(от пересечения сообщений это так ответ)
вариант бедного человека-использовать инструмент
tig1 onHEAD, найдите фиксацию, а затем визуально следуйте за строкой из этой фиксации до тех пор, пока не будет замечена фиксация слияния. В сообщении слияния по умолчанию должно быть указано, какая ветвь будет объединена в where:)1 Tig-это текстовый интерфейс на основе ncurses для git. Он функционирует в основном как браузер репозитория Git, но также может помочь в постановке изменения для фиксации на уровне куска и действовать как пейджер для вывода из различные команды Git.
в качестве эксперимента я сделал крюк после фиксации, который хранит информацию о текущей извлеченной ветви в метаданных фиксации. Я также немного изменил gitk, чтобы показать эту информацию.
вы можете проверить это здесь: https://github.com/pajp/branch-info-commits
Если ОП пытается определить история это было пройдено ветвью, когда был создан конкретный коммит ("узнайте, из какой ветви происходит коммит с учетом его sha1"), то без рефлога есть нет записей в базе данных объектов git это показывает, какая именованная ветвь была привязана к какой истории фиксации.
(Я написал это в качестве ответа в ответ на комментарий)
надеюсь, этот скрипт иллюстрирует мой точка:
rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1 git init; git config user.name n; git config user.email [email protected] git commit -m"empty" --allow-empty; git branch -m b1; git branch b2 git checkout b1; touch f1; git add f1; git commit -m"Add f1" git checkout b2; touch f2; git add f2; git commit -m"Add f2" git merge -m"merge branches" b1; git checkout b1; git merge b2 git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2 set -x; cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2; cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;вывод показывает отсутствие какого-либо способа узнать, пришла ли фиксация с 'Add f1' из ветви b1 или b2 из удаленного клона /tmp/r2
(последние строки вывода здесь)
+ cd /tmp/r1 + git log --oneline --graph --decorate * f0c707d (HEAD, b2, b1) merge branches |\ | * 086c9ce Add f1 * | 80c10e5 Add f2 |/ * 18feb84 empty + git reflog b1 f0c707d b1@{0}: merge b2: Fast-forward 086c9ce b1@{1}: commit: Add f1 18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1 18feb84 b1@{3}: commit (initial): empty + git reflog b2 f0c707d b2@{0}: merge b1: Merge made by the 'recursive' strategy. 80c10e5 b2@{1}: commit: Add f2 18feb84 b2@{2}: branch: Created from b1 + cd /tmp/r2 + git log --oneline --graph --decorate * f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches |\ | * 086c9ce Add f1 * | 80c10e5 Add f2 |/ * 18feb84 empty + git reflog b1 f0c707d b1@{0}: clone: from /tmp/r1 + git reflog b2 f0c707d b2@{0}: fetch origin b2:b2: storing head
найти местное отделение
grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'найти удаленную ветку
grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'
Comments