73

当我启动 agit rebase -i时,我可以发出git rebase --continue, 或之类的命令git rebase --abort。这些命令仅在 rebase 正在进行时才有效。

我怎么知道是否有正在进行的变基?

(我将非常感谢有关 rebase 如何在内部工作的一些细节;git 对 rebase 做了什么,使其处于“rebase in progress”状态,?)

4

8 回答 8

53

2021 年更新:

git stash正如我在“在 windows 上运行缓慢”中提到的,使用Git for Windows 2.19(2018 年 9 月),git stash(和git rebase)不再是仅脚本,而是实际上是用git.exe.

Tim回答说明了如何仍然难以确定变基是否正在进行中。

这在邮件列表中进行了讨论,导致补丁像“ statusrebase并且merge可以同时进行”:

git rebase -r推出以来,这是可能的。
但是我们的机器认为这是不可能的,并且在合并过程中没有说明正在进行的变基。

在此之前(2016 年)有一个“rebase in progress”检测的案例,带有“ worktree.c:检查分支是否在另一个工作树中变基

这个函数find_shared_symref()用在几个地方:

  1. in builtin/branch.c:用于检测分支是否在其他地方签出并拒绝删除该分支。
  2. in builtin/notes.c: 用于检测一个笔记是否被合并到另一个工作树中
  3. 在 中branch.c,该函数die_if_checked_out()实际上是由 " git checkout" 和 " git worktree add" 使用来查看分支是否已经在其他地方签出并拒绝操作。

在情况 1 和 3 中,如果 rebase 正在进行,“HEAD”将处于分离模式
find_shared_symref()未能检测到它并声明“ no branch is checked out here”,这并不是我们真正想要的。


原答案:2010

一方面,在 rebase 期间有一个ORIG_HEADin place(但不限于 rebase 命令)

但是您也可以查看 2010 Git 1.7.0git-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只显示 with rebase -i

嬉皮士还在2017 年评论说:

编码指南不鼓励使用-o(see Documentation/CodingGuidelines),所以现在正确的方法(2017 年,但也从 2011 年开始,Git 1.7.6)是:

(test -d ".git/rebase-merge" || test -d ".git/rebase-apply") || die "No rebase in progress?"

杰拉比在评论中建议:

(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>”。

Elizandro - SparcBR在评论中补充道:

也可以将错误重定向到 null:

(test -d "$(git rev-parse --git-path rebase-merge)" || test -d "$(git rev-parse --git-path rebase-apply) 2>/dev/null"

Git 2.6+(2015 年第三季度)将在 rebase 期间打印更多信息:

请参阅Guillaume Pagès ( )提交的592e412、提交84e6fb9 ( 2015 年 7 月 6 日)、提交 84e6fb9(2015 年 7 月 6 日)和提交 df25e94提交 05eb563(2015 年 6 月 30 日) 。(由Junio C Hamano 合并 -- --提交 178d2c7中,2015 年 8 月 3 日)gitster
gitster

status: 期间提供更多信息rebase -i

git status在 期间提供更多信息rebase -i,关于在变基期间完成的命令列表。
它显示:

  • 最后执行的两个命令和
  • 接下来要执行的两行。

它还提供了在.git目录中查找整个文件的提示。


尝试检测提示不适用于 Git 2.26+,如提交 6d04ce7中所示

" git rebase" 学会了默认使用合并后端(即驱动 " rebase -i" 的机器),同时允许 " --apply" 选项使用 " apply" 后端(例如,道德上的 " format-patch piped to am" 等价物)。
rebase.backend配置变量可以设置为自定义。)

请参阅提交10CDB9F提交8295ED6提交980b482提交C2417D3提交6D04CE7Commit 52EB733Commit 8AF14F0Commit Be50C93Commit 9312CCommit 9A70F3DCommit 93122C9Commit 55d2b6d提交,提交7db00f0,提交7db00f0 e98c426提交 d48e5e2(2020 年 2 月 15 日),并提交 a9ae8fd提交 22a69fd(2020 年 1 月 16 日),作者Elijah Newren(newren
(由Junio C Hamano 合并 -- gitster--8c22bd9 提交中,2020 年 3 月 2 日)

git-prompt:更改基于交互的变基的提示

过去,我们对不同类型的变基有不同的提示:

REBASE: for am-based rebases
REBASE-m: for merge-based rebases
REBASE-i: for interactive-based rebases

目前尚不清楚为什么这种区分是必要的或有帮助的。当在提交e752019中添加提示时(“改进 bash 提示以检测各种状态,例如未完成的合并”,2007-09-30,Git v1.5.5-rc0),它只是添加了这三种不同的类型。
也许当时有一个有用的目的,但发生了一些变化:

  • 合并后端在交互式后端实施后被删除,导致基于合并的变基的提示从更改REBASE-mREBASE-i.
  • 交互式后端用于多种不同类型的非交互式变基,因此-i提示的“”部分并不真正意味着它过去的含义。
  • Rebase 后端获得了更多的能力,并且有很多重叠,有时很难区分它们。
  • 后端之间的行为差​​异也得到了解决。
  • 我们想将默认后端从 am 更改为 interactive,这意味着REBASE-i如果我们不更改提示,人们将默认获得“”,并且只有当他们指定--am或者他们--whitespace-C获得“ REBASE”提示时。
  • 将来,我们计划让“ --whitespace”、“ -C”甚至“ --am”运行交互式后端,一旦它可以处理所有可以处理的事情am-backend

出于所有这些原因,将任何类型的变基的提示设为“ REBASE”。


自 Git 2.17(2018 年 3 月)以来,您还拥有:

git rebase --show-current-patch

它显示了.git/REBASE_HEAD可以在冲突期间暂停的交互式 rebase 期间的内容。

于 2010-10-13T08:29:55.163 回答
20

您还可以在__git_ps1函数 in 中contrib/completion/git-prompt.sh检查此类检测是如何完成的,可用于 git-aware 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
                        fi
                fi
于 2010-10-13T10:12:22.577 回答
4

如果正在进行交互式变基,这将告诉您您在此过程中的位置:

$ cat .git/rebase-merge/done 
pick 786139e lrg
edit 668b8a6 ktio
$ 

现在我正在交互式 rebase 中编辑“ktio”补丁。

如果没有变基,它将如下所示:

$ cat .git/rebase-merge/done 
cat: .git/rebase-merge/done: No such file or directory
$ 
于 2012-08-08T13:32:55.593 回答
4

从 bash 命令行:

ls `git rev-parse --git-dir` | grep rebase

如果存在变基文件夹,它将返回退出代码 0(成功),并将变基文件夹输出到 STDOUT。如果您不在变基中间,那么它将不输出任何内容并返回非 0 退出代码。所以你甚至可以做这样的事情:

ls `git rev-parse --git-dir` | grep rebase || echo no rebase
于 2014-04-24T18:45:31.747 回答
2

如果你有EasyGiteg 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 status</code> middle-of-rebase 演示截图

(eg help topic middle-of-rebase显示文档“<a href="http://people.gnome.org/~newren/eg/documentation/topic-middle-of-rebase.html" rel="nofollow noreferrer">如何解决或中止不完整的变基”。)

于 2012-08-23T18:48:12.467 回答
2

这里有一些不好的答案。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

于 2021-04-24T16:26:14.280 回答
0

我没有看到它说清楚,所以这里是:

在变基过程中,如果有一个正在进行中,git status现在就足够了,因为它提供了信息(作为参考,我领导了名为masterand的样本分支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.
于 2020-08-19T04:35:07.270 回答
-1

我正在使用这个命令is_rebase=$(git status | grep "rebasing" | wc -l)

于 2018-05-23T16:01:49.590 回答