Найти в какой ветке это коммит в git'е, пришли из



есть ли способ узнать, из какой ветви происходит фиксация с учетом ее sha1?



бонусные очки, если вы можете сказать мне, как это сделать с помощью Ruby Grit.

1119   10  
git

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 Года:

sschuberthкомментарии

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
   [...]

эта программа не учитывает эффекты вишневого выбора фиксации интереса, только операции слияния.

например, чтобы найти, чтоc0118fa commit пришел от 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_api

UPD
Или только одна команда:

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 on HEAD, найдите фиксацию, а затем визуально следуйте за строкой из этой фиксации до тех пор, пока не будет замечена фиксация слияния. В сообщении слияния по умолчанию должно быть указано, какая ветвь будет объединена в 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

    Ничего не найдено.