Как узнать, происходит ли git rebase?
Когда я начинаю git rebase -i
Я могу выдавать команды, такие как git rebase --continue
, или же git rebase --abort
, Эти команды работают, только если выполняется перебазирование.
Как я могу узнать, происходит ли ребазинг?
(Я был бы очень признателен за некоторые подробности о том, как rebase работает внутри; что делает git с репо, который придает ему статус "rebase in progress"?)
8 ответов
С одной стороны, есть ORIG_HEAD
на месте во время перебазировки (но это не ограничивается командой rebase)
Но вы также можете посмотреть на 2010 Git 1.7.0 git-rebase.sh
сам скрипт (который настолько "внутренний", насколько вы можете;)).
Линии, подобные этим, могут дать вам другую подсказку:
dotest="$GIT_DIR"/rebase-merge
test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || die "No rebase in progress?"
- Папка
rebase-apply
кажется, появляется сrebase
, - но папка
rebase-merge
появляется только сrebase -i
,
И hIpPy также комментирует, в 2017 году, что:
Руководящие принципы кодирования препятствуют использованию
-o
(увидетьDocumentation/CodingGuidelines
), поэтому правильный путь сейчас (2017, а также с 2011 года, Git 1.7.6):
(test -d ".git/rebase-merge" || test -d ".git/rebase-apply") || die "No rebase in progress?"
Jelaby предлагает в комментариях:
(test -d "$(git rev-parse --git-path rebase-merge)" || \
test -d "$(git rev-parse --git-path rebase-apply)" )
Это правильно обрабатывает рабочие деревья и необычные или нестандартные макеты, которые не имеют
.git
каталог, а также позволяет запустить этот тест из подкаталога рабочего каталога.
Это потому что git rev-parse --git-path <path>
: решает " $GIT_DIR/<path>
".
Git 2.6+ (3 квартал 2015 года) напечатает больше информации во время ребазинга:
См. Коммит 592e412, коммит 84e6fb9 (06 июля 2015 г.), коммит 84e6fb9 (06 июля 2015 г.) и коммит df25e94, коммит 05eb563 (30 июня 2015 г.) Гийома Пагеса ( gitster
)
(Объединено Юнио С Хамано - gitster
- в коммите 178d2c7, 3 августа 2015 г.)
status
: дать больше информации во времяrebase -i
git status
дает больше информации во времяrebase -i
, о списке команд, которые выполняются при ребазе.
Он отображает:
- последние две команды выполнены и
- следующие две строки должны быть выполнены.
Это также дает подсказки, чтобы найти целые файлы в
.git
каталог.
Вы также можете проверить, как такое обнаружение выполняется в __git_ps1
функция вcontrib/completion/git-prompt.sh
, которая может быть использована для gash -ware bash:
if [ -f "$g/rebase-merge/interactive" ]; then
r="|REBASE-i"
b="$(cat "$g/rebase-merge/head-name")"
elif [ -d "$g/rebase-merge" ]; then
r="|REBASE-m"
b="$(cat "$g/rebase-merge/head-name")"
else
if [ -d "$g/rebase-apply" ]; then
if [ -f "$g/rebase-apply/rebasing" ]; then
r="|REBASE"
elif [ -f "$g/rebase-apply/applying" ]; then
r="|AM"
else
r="|AM/REBASE"
fi
Здесь есть несколько плохих ответов.
git
на самом деле нет спецификации того, как это должно работать, поэтому единственный ответ - «как git это делает?». Код здесь:
int wt_status_check_rebase(const struct worktree *wt,
struct wt_status_state *state)
{
struct stat st;
if (!stat(worktree_git_path(wt, "rebase-apply"), &st)) {
if (!stat(worktree_git_path(wt, "rebase-apply/applying"), &st)) {
state->am_in_progress = 1;
if (!stat(worktree_git_path(wt, "rebase-apply/patch"), &st) && !st.st_size)
state->am_empty_patch = 1;
} else {
state->rebase_in_progress = 1;
state->branch = get_branch(wt, "rebase-apply/head-name");
state->onto = get_branch(wt, "rebase-apply/onto");
}
} else if (!stat(worktree_git_path(wt, "rebase-merge"), &st)) {
if (!stat(worktree_git_path(wt, "rebase-merge/interactive"), &st))
state->rebase_interactive_in_progress = 1;
else
state->rebase_in_progress = 1;
state->branch = get_branch(wt, "rebase-merge/head-name");
state->onto = get_branch(wt, "rebase-merge/onto");
} else
return 0;
return 1;
}
Он в основном проверяет, существуют ли эти несколько файлов / каталогов (примечание
!stat()
означает "файл существует").
am
является
git am
который предназначен для применения патчей из почтового ящика, которые, я сомневаюсь, использует кто-либо, кроме разработчиков Linux.
-
rebase_in_progress
:.git/rebase-apply && !.git/rebase-apply/applying || .git/rebase-merge && !.git/rebase-merge/interactive
-
interactive_rebase_in_progress
:.git/rebase-merge && .git/rebase-merge/interactive
-
am_in_progress
:.git/rebase-apply && .git/rebase-apply/applying
Я думаю, если вы хотите знать, происходит ли какое-либо перебазирование / я, просто проверьте, есть ли
.git/rebase-apply
или же
.git/rebase-merge
существовать.
Если происходит интерактивная перебазировка, это скажет вам, где вы находитесь в процессе:
$ cat .git/rebase-merge/done
pick 786139e lrg
edit 668b8a6 ktio
$
Прямо сейчас я редактирую патч "ktio" в интерактивной перебазировке.
Если перебазирование не происходит, это будет выглядеть так:
$ cat .git/rebase-merge/done
cat: .git/rebase-merge/done: No such file or directory
$
Из командной строки bash:
ls `git rev-parse --git-dir` | grep rebase
Это вернет код выхода 0 (успех), если есть папка rebase, и выведет папку rebase в STDOUT. Если вы не находитесь в середине перебазирования, он ничего не выдаст и вернет код выхода, отличный от 0. Таким образом, вы могли бы даже сделать что-то вроде этого:
ls `git rev-parse --git-dir` | grep rebase || echo no rebase
Если у вас есть EasyGit, eg status
скажу тебе:
$ eg status
(Not currently on any branch.)
(YOU ARE IN THE MIDDLE OF A INTERACTIVE REBASE; RUN 'eg help topic middle-of-rebase' FOR MORE INFO.)
Changes ready to be committed ("staged"):
modified: .gitmodules
renamed: config_loader.rb -> code/config_loader.rb
Newly created unknown files:
vendor/
(YOU ARE IN THE MIDDLE OF A INTERACTIVE REBASE; RUN 'eg help topic middle-of-rebase' FOR MORE INFO.)
В цветном терминале уведомление очень заметное:
например, статус code> демонстрационный скриншот в середине перебазирования">
(eg help topic middle-of-rebase
отображает документацию " Как решить или отменить неполное обновление ".)
Я использую эту команду is_rebase=$(git status | grep "rebasing" | wc -l)
Я не видел, чтобы это было четко указано, поэтому вот оно:
во время процесса перебазирования, если он уже выполняется, git status
теперь достаточно, так как он дает информацию (для справки, я возглавляю небольшие ветки с именем master
а также rbBr
):
interactive rebase in progress; onto 5f8e534
Last command done (1 command done):
pick 1b7a450 BRANCH: another comment
No commands remaining.
You are currently rebasing branch 'rbBr' on '5f8e534'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: User.java
no changes added to commit (use "git add" and/or "git commit -a")
Это отображается до разрешения конфликтов, после разрешения конфликтов показывает:
interactive rebase in progress; onto 5f8e534
Last command done (1 command done):
pick 1b7a450 BRANCH: another comment
No commands remaining.
You are currently rebasing branch 'rbBr' on '5f8e534'.
(all conflicts fixed: run "git rebase --continue")
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: User.java
PS C:\my_git_repos\learning_git> git rebase --continue [detached HEAD 9645135] BRANCH: another comment
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/rbBr.