Показать оригинальную ветку для коммита - PullRequest
36 голосов
/ 26 декабря 2010

Я использовал git-blame, чтобы найти конкретный коммит. Теперь я хочу найти ветку, из которой он изначально появился. (Оттуда я буду использовать название ветви, чтобы найти конкретный билет)

Давайте определим «оригинальную ветвь» как «ветвь, в которую была сделана фиксация до того, как ветвь была объединена с любой другой веткой».

Ответы [ 9 ]

42 голосов
/ 27 декабря 2010

Как говорили другие, если искомая ветка не является локальной для репозитория, в котором вы обвиняете этот коммит (например, ветка только в личном репо удаленного разработчика), вы облажались.

Но если предположить, что искомая ветвь - это то, что вы можете видеть, и, конечно, у вас есть хеш коммита, скажем, d590f2..., то частичный ответ таков:

$ git branch --contains d590f2
  tests
* master

Затем, просто чтобы подтвердить, что у вас есть преступник:

$ git rev-list tests | grep d590f2

Конечно, если d590f2 было объединено в более чем одной ветви, вам придется быть более тонким, чем эта.

9 голосов
/ 26 декабря 2010

Это не совсем применимо в git.Ветви - это локальные понятия для каждого репозитория: ветвь «local-stuff» одного человека может быть совершенно отделена от ветки «local-stuff» другого человека.Если вы делаете что-то вроде просмотра своей основной ветви интеграции, своего коммита запроса и удаления всех баз слияний между ними, вы сможете получить поддерево истории коммитов, которое может пролить некоторое освещение ... или нет,например, если вы проследите ссылку от коммита запроса к «master», вы должны найти коммиты слияния с полезными комментариями, сообщающими, откуда произошло слияние ... но эта информация просто информационная, а не записана каким-либо образом, предназначенным для автоматического извлечения.

например, gitk some-commit...master (что почти означает gitk some-commit master --not $(git merge-base some-commit master))

7 голосов
/ 26 декабря 2010

Ветвь Git - это не что иное, как «именованный указатель на коммит» (это принципиально иное понятие, чем в других известных VCS).

Эта ситуация ясна, фиксация A включена branch-1, фиксация B включена branch-2:

  o A [branch-1]
  |
o | B [branch-2]
| |

После слияния становится неясным, был ли A (или B) первоначально на branch-1 или branch-2:

o [branch-1] [branch-2]
|
o merged 
|\
| o A
| |
o | B
| |

Может быть, вы можете догадаться, какой веткой Git был коммит A, если вы пометили родительские коммиты A, например, release-1 и вы знаете, что этот тег был дан только для коммитов в branch-1.

o [branch-1] [branch-2]
|
o merged 
|\
| o A
| |
o | B
| |
| o <release-1]
| |
6 голосов
/ 14 июля 2011

Я попробую, пожалуйста, прокомментируйте, так как не совсем уверен, но я верю, что он выполняет свою работу.

Следующее будет работать, только если ветви все еще указывают на верхушкубудучи объединенным с мастером, что имеет место, если ветви были в одном репо:

o [master]
|
o merged branch "great-feature" into master
|\
| o A [great-feature]
| |
o | B
| |

Если это не так (например, если вы вытащили из другого репо), вы все равно можете воссоздать их вручную.

Сначала получите ветви, где ваш коммит:

$ git branch -a --contains=<sha-of-B>
*master
great-feature

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

$ git log --pretty=oneline <sha-of-B>..great-feature | wc -l
1
$ git log --pretty=oneline <sha-of-B>..master | wc -l
4

Так что B ближе всего к great-feature, что означает, что он был создан в нем.

Это можно сделать в виде хорошего сценария, не стесняйтесьдобавить его к ответу (я не очень хорош в этом)

5 голосов
/ 11 декабря 2013

Сначала убедитесь, что вы получили изменения с пульта

$ git fetch --all

И

$ git branch -a --contains d590f2

Без опции -a вы не можете найти коммиты, существующие только в удаленных ветвях

2 голосов
/ 29 октября 2016

Когда вы в ветке "оригинальная ветка" была объединена с.Вы можете запустить:

git log <SHA>..HEAD --ancestry-path --merges

Эта команда покажет все merge коммиты между <SHA>..HEAD.Вам нужен последний.

Например, для c0118fa коммит (последний, но один) "оригинальная ветвь" равно 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 a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date:   Sat Oct 1 00:54:18 2016 +0300

    Merge branch 'redesign_interactions' into clean_api
2 голосов
/ 14 июля 2011

Я нашел более простой способ сделать это: в сообщении о последнем коммите git log <sha>..HEAD --merges!

Эта команда показывает слияния, которые произошли между мастером и коммитом;последний вывод коммита этой командой является первым коммитом слияния, который его включил.Обычно оно содержит имя ветви, поэтому даже если ветка была удалена, вы можете найти ее имя.

Чтобы получить только имя ветви, просто наберите git log <sha>..HEAD --merges --oneline |tail -1

1 голос
/ 14 октября 2016

Кажется, что это не тот вопрос, на который можно ответить со 100% точностью с помощью git.

git branch --contains --merge <sha1>

возвращает список всех веток, в которые был добавлен коммит, и исходную ветку. - без слияния возвращает все последующие ветки, которые включают в себя коммит, потому что они разветвились после точки слияния.

Таким образом, вы можете получить список каждого слияния, но не исходную ветку, и любая ветка, удаленная до выполнения команды, будет потеряна (или вы смотрите на reflogs)

Результаты

git branch --contains <sha1 for "added feature/inital 1">
* develop
  feature/inital
  feature/subsequent1

git branch --contains <sha1 for "added feature/inital 1"> --merged
* develop
  feature/inital

git branch --contains <sha1 for "added feature/inital 1"> --no-merged
  feature/inital

Тестовый скрипт

function mkbranch {
  git checkout -b $1
  git push --set-upstream origin $1
}

# Develop
mkbranch develop
for f in 1 2 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "added develop $f"; done
git push

# Initial Feature Branch
mkbranch feature/inital
for f in 1 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "modified feature/inital $f"; done
git push

# Merge
git checkout -b develop
git merge feature/inital
git push


# Next Feature Branch
mkbranch feature/subsequent1
for f in 1 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "modified feature/subsequent1 $f"; done
git push
0 голосов
/ 26 сентября 2015

Это сработало достаточно для того, чтобы я получил название ветви от отсоединенной головки в рабочем пространстве Дженкинса:

git show -s --pretty=%d

...