Как определить ветвь источника для конкретной ветки?
У меня есть ветвь в git и вы хотите выяснить, из какой ветки она изначально была разветвленной и при какой фиксации.
Github, похоже, знает, поскольку, когда вы делаете запрос на pull, он обычно автоматически настраивает, в какую ветвь он должен войти, но я не могу понять, как это сделать вручную из командной строки.
Позвольте мне добавить конкретный пример:
master -- ongoing development
2.2 -- stable maintenance
Была создана ветвь функциональности feature
(при фиксации B
ниже) и работала (B'
, C'
и E'
) и сливалась с ветвью источника, чтобы выбрать C
и D
feature branch: B'-C'-C--D--E'
/ /
source branch: A--B--C--D--E-- ...
Теперь я хочу объединить feature
обратно в исходный код, но я не уверен, был ли он изначально отключен от master
или 2.2
. Чтобы объединить функцию в правильный источник, существует ли программный способ узнать, есть ли ветвь источника master
или 2.2
?
Ответы
Ответ 1
Git только отслеживает информацию "вверх по течению" в отдельных репозиториях, и эта информация не является статической и не разделяется между отдельными клонами одного и того же репозитория.
Команда для установки этого отношения из командной строки:
git branch --set-upstream <branch> [<start-point>]
Просмотр вывода git -diff может дать вам ключ:
git diff <mybranch>..master # commits in master that are not in mybranch
git diff <mybranch>..2.2 # commits in 2.2 that are not in mybranch
Вероятно, тот, у кого меньше коммитов, является точкой ветвления (но это не гарантировано, очевидно.
Вы также можете использовать gitk или журнал git, чтобы посмотреть вокруг:
gitk --all
git log --graph --color --decorate --oneline --all
Ответ 2
git show-branch [--all]
git merge-base
Первый показывает вам ветки и даст вам информацию о слиянии. Второй поможет вам понять взаимосвязь между двумя конкретными ветвями (где они в последний раз расходились).
Ответ 3
git branch -r
С помощью --contains отображаются только ветки, которые содержат именованное commit (другими словами, ветки, концы которых совершаются, являются потомками named commit). С -merged только ветки, объединенные в названные фиксации (т.е. ветки, вершина которых заканчивается доступный от именованного коммита). С --no-merged будут перечислены только те ветки, которые не объединены в именованный коммит. Если аргумент отсутствует, по умолчанию используется HEAD (т. кончик текущей ветки).
Учитывая, что предыдущая фиксация уже была перенесена в удаленную ветвь, вы можете отфильтровать доступные удаленные ветки, используя ключ --contains.
# git branch -r --contains HEAD~1
origin/HEAD -> origin/master
origin/master
или
git branch -r --contains refs/heads/<local_branch_name>~1
Если у вас есть 2 нетолкнутых фиксации, но не измените число соответственно, чтобы достичь уже нажатой фиксации:
# git branch -r --contains HEAD~2
origin/<parent_remote_branch>
Если количество локальных нетолкнутых коммитов неизвестно, вы можете пройти до тех пор, пока не получите результат, например:
#!bin/bash
i=0;
res=;
while [ -z "$res" ]; do
res=$(git branch -r --contains HEAD~$i);
echo "$i";
i=$(($i+1));
done
echo "$res"
Конечно, вы можете ограничить количество итераций на безопасной стороне.