Во-первых, --fork-point
предназначено для удаленного отслеживания имен. Он работает так, что использует reflog для поставляемого апстрима. Подробнее об этом см., Например, Git rebase - фиксация выбора в режиме точки ветвления .
Во-вторых, но, возможно, важнее, вы можете запустить git rebase <em>upstream</em>
, git rebase --onto <em>newbase</em> <em>upstream</em>
или даже просто git rebase
. Используя форму с двумя аргументами, вы получаете большую свободу:
Ограничения аргумента upstream
, которые будут скопированы. Мы еще поговорим об этом чуть позже.
Аргумент newbase
выбирает, какой коммит является точкой, после которой должны быть добавлены копии. Фактический хеш-код здесь очень важен.
То есть, когда вы делаете , используете --onto
, вы должны выбрать точную фиксацию для аргумента --onto
newbase
. Это означает, что вы можете быть очень не уверены в том, что вы используете в качестве аргумента upstream
. Но когда вы не используете --onto
, upstream
, вы используете для обеих целей , поэтому параметр upstream
это тот, который требует много тщательности. Одна цель свободна и свободна, а другая нет.
Что это означает, что вы можете использовать два аргумента, чтобы восстановить любую лишнюю слабость, которую вы хотите (но может и не понадобиться), или нет аргументов, чтобы получить удобство.
(Следующая часть построена странно из-за обновления вопроса.)
git show-branch --merge-base X Y
= git merge-base X Y
Команда git show-branch
теперь принимает --merge-base
или --independent
при наличии нескольких аргументов. Имея ровно два аргумента, он делает то же самое, что и git merge-base X Y
, то есть находит базу (и) слияния ревизий X
и Y
. (git merge-base
также теперь занимает --independent
, вместо того, чтобы предполагать стратегию осьминога, но это применимо только при использовании трех или более спецификаторов коммитов.)
Я предпочитаю git merge-base
здесь, так как я думаю, что это более очевидно (и, конечно, немного короче, чтобы набрать).
Без аргументов upstream исходит из настроек вашего филиала
Каждая ветвь может иметь одну (но только одну) восходящую настройку.
Настройка восходящего потока для любой ветви B обычно origin/<em>B</em>
, потому что мы склонны передавать их на GitHub или Bitbucket или какой-либо корпоративный веб-сервер, URL которого мы придерживаемся под именем origin
, чтобы мы не должны печатать это все время. Если вы израсходовали свой апстрим на origin/
и хотите установить секундный параметр, который git rebase
будет использовать автоматически, вам не повезло (но читайте дальше). Но если вы не не использовали один восходящий поток, просто установите для восходящего потока то, что вы хотели бы git rebase
для автоматического использования. Например, если вы сейчас на feature-X
и хотите, чтобы он перебазировал на develop
:
$ git branch --set-upstream-to=develop
и теперь feature
имеет develop
в качестве восходящего. Выполнение git rebase
(с -i
или без него) перезапустится, как если бы вы выполнили ту же команду с develop
, что и ее аргумент upstream
.
Если вы использовали вышестоящий поток, вы можете создать свой собственный псевдоним:
alias.name = !git rebase "$@" $(git config --get branch.$(git symbolic-ref --short HEAD).base) #
(выберите какое-нибудь имя): это позволяет вам настроить, используя git config
, дополнительное имя, branch.feature-X.base
, для develop
. $(git symbolic-ref --short)
извлекает текущее имя ветви, git config --get
получает настройку, а затем rebase использует ее в качестве одного вышестоящего аргумента.
Недостаток одного аргумента ограничитель-и-цель / newbase
Недостаток здесь в том, что, учитывая график вида:
o--o <-- develop
/
...--o--o--o
\
A--B--C <-- feature-X (HEAD)
вы получите копии, которые идут после кончика develop
:
A'-B'-C' <-- feature-X (HEAD)
/
o--o <-- develop
/
...--o--o--o
\
A--B--C [abandoned]
когда вы хотите сохранить копии в одном и том же месте, просто возитесь с текстом их коммита или, может быть, сложите два вместе или что-то в этом роде:
o--o <-- develop
/
...--o--o--o--A'-B'-C' <-- feature-X (HEAD)
\
A--B--C [abandoned]
Использование --onto
В форме с двумя аргументами параметр --onto
выбирает целевой коммит:
o--o <-- develop or whatever
/
...--o--o--* [pick this commit as target]
\
A--B--C <-- feature-X (HEAD)
Копии будут идти после *
. Набор коммитов, подлежащих копированию, определяется с помощью <em>upstream</em>..feature-X
, то есть коммитов, достижимых начиная с feature-X
и работающих в обратном направлении, но исключая коммиты, достижимые начиная с upstream
и работает в обратном направлении.
Теперь вам нужно только найти коммит *
. Если у вас есть два имени, таких как feature-X
и develop
, вы можете использовать синтаксис gitrevisions с тремя точками , develop...feature-X
или feature-X...develop
(синтаксис симметричен, когда существует только одно слияние база, как это), чтобы указать коммит *
. Это работает только в довольно новых версиях Git: в более старых версиях используйте git show-branch
или git merge-base
(с двумя хэш-идентификаторами коммитов они оба ведут себя одинаково).
Указав коммит *
в качестве цели --onto
, вы снова можете разрешить восходящему потоку ветви работать в качестве ограничителя. То есть вы можете опустить явное значение upstream
, поскольку оно по умолчанию соответствует фактическому восходящему потоку. А так как вы можете использовать синтаксис @{upstream}
или @{u}
, вы можете сделать очень короткий и простой псевдоним, как вы сделали в своем собственном ответе.
Если вы хотите сохранить отдельный восходящий поток (origin/feature-X
) и базу, вы можете вернуться к идее настройки дополнительного значения для имени ветви. В этом случае вам нужно будет использовать его дважды, поэтому вместо псевдонима вам может понадобиться полноценный скрипт, где вы можете выполнить проверку ошибок:
#! /bin/sh
# git-base - rebase on the current branch's base setting
. git-sh-setup
branch=$(git symbolic-ref --short HEAD) || exit
base=$(git config --get branch.$branch.base) || die "branch.$branch.base is not set"
mbase=$(git merge-base $base HEAD) || die "there is no merge base"
git rebase --onto $mbase "$@" $base
Назовите это git-base
, поместите его на свой путь, и теперь вы можете запустить git base
.