Найдите родительскую ветвь ветки Git - PullRequest
346 голосов
/ 01 июля 2010

Допустим, у меня есть следующий локальный репозиторий с деревом коммитов, подобным этому:

master --> a
            \
             \
      develop c --> d
               \
                \
         feature f --> g --> h

master - это мой , это код последней стабильной версии , develop - это мой , это код следующей версии , а feature - готовится новая функция для develop.

То, что я хочу иметь в своем удаленном репо с использованием хуков, - это отклонение запросов к feature, если только коммит f не является прямым потомком develop HEAD. то есть дерево коммитов выглядит так, потому что функция была git rebase на d.

master --> a
            \
             \
      develop c --> d
                     \
                      \
               feature f --> g --> h

Так можно ли:

  • Укажите родительскую ветвь feature?
  • Укажите коммит в родительской ветви, потомком которого является f?

Оттуда я бы проверил, что такое HEAD родительской ветви, и посмотрел, соответствует ли f предшественник родительской ветви HEAD, чтобы определить, нужно ли перебазировать эту функцию.

Ответы [ 19 ]

3 голосов
/ 31 августа 2018

Я не говорю, что это хороший способ решить эту проблему, однако, похоже, это работает для меня.

git branch --contains $(cat .git/ORIG_HEAD) Проблема в том, что cat'ing файл заглядывает во внутреннюю работу git, так что это не обязательно совместимо вперед (или обратно).

3 голосов
/ 30 декабря 2015

Кроссплатформенная реализация с Ant

    <exec executable="git" outputproperty="currentBranch">
        <arg value="rev-parse" />  
        <arg value="--abbrev-ref" />  
        <arg value="HEAD" />  
    </exec>

    <exec executable="git" outputproperty="showBranchOutput">
        <arg value="show-branch" />  
        <arg value="-a" />  
    </exec>

    <loadresource property="baseBranch">
      <propertyresource name="showBranchOutput"/>
          <filterchain>
            <linecontains>
              <contains value="*"/>
            </linecontains>
            <linecontains negate="true">
              <contains value="${currentBranch}"/>
            </linecontains>
            <headfilter lines="1"/>
            <tokenfilter>
                <replaceregex pattern=".*\[(.*)\].*" replace="\1"/>
                <replaceregex pattern="[\^~].*" replace=""/>
            </tokenfilter>
          </filterchain>
    </loadresource>

    <echo message="${currentBranch} ${baseBranch}" />
3 голосов
/ 19 августа 2015

Вот реализация Power Mark для решения Марка Рида:

git show-branch -a | where-object { $_.Contains('*') -eq $true} | Where-object {$_.Contains($branchName) -ne $true } | select -first 1 | % {$_ -replace('.*\[(.*)\].*','$1')} | % { $_ -replace('[\^~].*','') }
2 голосов
/ 19 февраля 2015

@ Марк Рид: Вы должны добавить, что строка коммита должна содержать не только звездочку, но и начинаться со звездочки!В противном случае сообщения о фиксации, содержащие звездочку, также включаются в соответствующие строки.Так должно быть:

git show-branch -a | awk -F'[]^~[]' '/^\*/ && !/'"$current_branch"'/ {print $2;exit}'

или длинная версия:

git show-branch -a           |
  awk '^\*'                  | # we want only lines that contain an asterisk
  awk -v "$current_branch"   | # but also don't contain the current branch
  head -n1                   | # and only the first such line
  sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
  sed 's/[\^~].*//'            # and with any relative refs (^, ~n) removed`
2 голосов
/ 11 мая 2016
vbc=$(git rev-parse --abbrev-ref HEAD)
vbc_col=$(( $(git show-branch | grep '^[^\[]*\*' | head -1 | cut -d* -f1 | wc -c) - 1 )) 
swimming_lane_start_row=$(( $(git show-branch | grep -n "^[\-]*$" | cut -d: -f1) + 1 )) 
git show-branch | tail -n +$swimming_lane_start_row | grep -v "^[^\[]*\[$vbc" | grep "^.\{$vbc_col\}[^ ]" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

Достигает тех же целей, что и ответ Марка Рида, но использует гораздо более безопасный подход, который не ведет себя неправильно в ряде сценариев:

  1. Последний коммит родительской ветви - это слияние, в котором столбец показывает - не *
  2. Сообщение коммита содержит имя ветви
  3. Сообщение коммита содержит *
0 голосов
/ 19 июня 2019

Это не сработало для меня, когда я сделал что-то вроде develop > release-v1.0.0 > feature-foo, все вернулось бы к разработке, заметьте, что произошел ребазинг, не уверен, что это усугубляет мою проблему ...

Следующий код дал мне правильный хеш коммита

git log --decorate \
  | grep 'commit' \
  | grep 'origin/' \
  | head -n 2 \
  | tail -n 1 \
  | awk '{ print $2 }' \
  | tr -d "\n"
0 голосов
/ 15 февраля 2019

Альтернатива: git rev-list master | grep "$(git rev-list HEAD)" | head -1

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

0 голосов
/ 05 апреля 2017

Любой, кто хочет сделать это в наши дни - приложение Atlassian SourceTree показывает вам отличное наглядное представление о том, как ваши ветви связаны друг с другом, то есть, где они начались и где они в настоящее время находятся в порядке фиксации (например, HEAD или 4 коммитов позади,и др.).

0 голосов
/ 03 октября 2017

Если вы используете Source Tree, посмотрите информацию о коммите> Parents>, тогда вы увидите подчеркнутые номера коммитов (ссылки)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...