62

是否可以进行以下操作?

  1. 仅将git rebase --interactive标准样板输出到文件,而不是输出到文件并在编辑器中打开它。
  2. 让用户编辑文件。
  3. 让用户以编辑后的文件名重新运行git rebase
  4. 继续通常的变基过程。

用例:当然是脚本化的变基。例如,查看如何以非交互方式在 Git 中重新排序提交

4

10 回答 10

63

经过一番思考和研究,答案被证明是微不足道的:git rebase -i从著名的 EDITOR/VISUAL 环境变量中获取编辑器名称,因此覆盖它以指向非交互式脚本就可以了。

但是,EDITOR/VISUAL 对提交列表、改写时的提交消息和其他任何内容都无动于衷。因此,由于http://git.kernel.org/?p=git ​​/git.git;a=commit;h=821881d88d3012a64a52ece9a8c2571ca00c35cd ,有一个特殊的环境变量 GIT_SEQUENCE_EDITOR 仅适用于提交列表。

因此,重新排序或展平提交的方法是:

运行:GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>。您<script>应该接受一个参数:包含标准变基提交列表的文件的路径。它应该就地重写它并退出。之后发生通常的变基处理。

于 2012-09-12T19:31:40.790 回答
18

添加到@pfalcon 的答案,您可以使用 sed 作为您的 GIT_SEQUENCE_EDITOR。例如,我想编辑每个提交,所以我这样做了:

GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
于 2013-03-13T19:36:48.083 回答
9

该变量GIT_SEQUENCE_EDITOR最初用于更改编辑器。可以将脚本传递给该变量以git rebase -i以非交互方式使用。所以可以使用:

GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick 134567/e 1234567/'" git rebase -i 1234567^

此命令将在 .sed提供的文件上运行git rebase -i。它将将该行更改pick 134567e 1234567(因此,编辑提交 1234567)。您可以e使用r(rework)、f(fixup)、s(squash) 或d(drop) 进行更改(旧版本不支持后者git)。

基于此,我编写了一个脚本来自动化这个任务:

#!/bin/bash

ACTION=$1
COMMIT=$(git rev-parse --short $2)
[[ "$COMMIT" ]] || exit 1
CORRECT=
for A in p pick r reword e edit s squash f fixup d drop t split; do
     [[ $ACTION == $A ]] && CORRECT=1
done 
[[ "$CORRECT" ]] || exit 1
git merge-base --is-ancestor $COMMIT HEAD || exit 1
if [[ $ACTION == "drop" || $ACTION == "d" ]]; then
    GIT_SEQUENCE_EDITOR="sed -i -e '/^pick $COMMIT/d'" git rebase -i $COMMIT^^
elif [[ $ACTION == "split" || $ACTION == "t" ]]; then
    GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/edit $COMMIT/'" git rebase -i $COMMIT^^ || exit 1
    git reset --soft HEAD^
    echo "Hints:"
    echo "  Select files to be commited using 'git reset', 'git add' or 'git add -p'"
    echo "  Commit using 'git commit -c $COMMIT'"
    echo "  Finish with 'git rebase --continue'"
else
    GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/$1 $COMMIT/'" git rebase -i $COMMIT^^
fi

第一个参数应该是一个动作。该脚本使用与 git-rebase 相同的操作名称。它还添加了“拆分”操作(并允许drop与旧版本的 git 一起使用)。

它还检查您要求的提交是否是 HEAD 的祖先。这是一个常见(而且非常烦人)的错误rebase -i

第二个参数是要编辑/删除/拆分/改写的提交。

然后你为你的 .gitconfig 添加一个别名:

[alias]
  autorebase = ! path_to_your_script
于 2013-10-09T08:45:52.320 回答
7

扩展 pfalcon 的答案:

运行GIT_SEQUENCE_EDITOR=<script> git rebase -i <params><script>应该接受单个参数 - 包含标准变基提交列表的文件的路径。脚本应该就地重写它并退出。之后发生通常的变基处理。

如果您有一个包含所需内容的环境变量:

GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>]

Catting 文件也可以:

GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>]
于 2014-05-22T15:42:56.870 回答
4

您可以touch用作编辑器,它会触摸文件,因此它会显示为已修改。例如

GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]

给它取别名,baseline作为我想要重新定位的标签给出

git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline'

该别名在 Windows 下工作,因为它正在执行的 shellbash不是cmd.

于 2016-05-14T07:36:10.360 回答
3

交互模式会调出要使用的集合编辑器。
可以通过以下方式检索正在使用的编辑器:

git config --get core.editor

因此,如果您设置了一个非交互式编辑器——即在标准输入上接受命令的编辑器,您可以--interactive非交互式方式使用 :)
我知道肯定vim接受命令,标准编辑器 ed也是如此,当然。

所以,拿着交互式编辑器(如果需要)

$ ied="$(git config --get core.editor)"

设置非交互式编辑器

$ git config --unset-all core.editor
$ git config --add core.editor ed

并使用它..

$ printf '%s\n' "some-ed-cmd" "another-ed-cmd" "wq" | git rebase -i HEAD~5

并恢复编辑器(如果需要)

$ git config --unset-all core.editor
$ git config --add core.editor "$ied"
于 2012-09-12T19:33:02.633 回答
2

我找到了解决方案。您可以使用:

$ GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash $COMMIT_HASH~1
于 2019-08-08T09:46:46.543 回答
1

要完全按照原始问题的要求进行操作,请sed -i '1s/^/b\n/'用作您的编辑器

git -c sequence.editor="sed -i '1s/^/b\n/'" rebase --interactive

解释

  • git -c指定以指定的设置运行以下 git 命令
  • sequence.editor确定将编辑 redbase-todo 文件的“编辑器”的设置
  • sed -i就地运行 sed 命令
    • 1s在第一行
    • ^匹配开头
    • b\n插入b和换行符\nb或者break是停止交互式变基的变基命令。
  • rebase --interactive运行变基命令

这会立即停止交互式变基。现在您可以编辑.git/rebase-merge/git-rebase-todo并运行git rebase --continue.

于 2021-12-10T09:36:19.490 回答
0

正如其他人所提到的,您需要提供一个自定义GIT_SEQUENCE_EDITOR值来修改交互式变基文件。如果您只想对单个提交执行操作,可以按如下方式执行:

# Runs "edit" on HEAD~3
GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/edit/'" git rebase -i HEAD~3

或者,这是一个概括这一点的函数:

# Usage: git-rebase-custom edit HEAD~3
git-rebase-custom() {
    local action=$1
    shift

    GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/$action/'" git rebase -i "$@"
}
于 2019-08-04T02:50:09.460 回答
-1

根据Jezz 的回答,我制作了一个与 shell 无关的脚本 ( GitReb ),它适用于多参数修订、 :/<text>语法、根提交,并且还进行了一些健全性检查。

我还使它更简单,并删除了IMO 超出此脚本范围的t/split操作和delete->转换。drop

于 2017-02-23T08:20:14.203 回答