Git 多个暂存区

Git 多个暂存区,git,Git,我可以拥有多个暂存区域,或者使用git实现类似的效果吗 我的典型工作流程如下: 工作,工作,工作 现在我有了一个有用的想法,让我们提交它git add-p,y,y 但首先,这些较小的样式更改:git重置头。 git add-p,n,n,y,q,git commit-m“样式更改” git add-p。。做真实的事情 有时,我要从一大堆更改中做出20个较小的承诺。如果我能运行像git add-p这样的补丁,然后将每个补丁“分派”到它自己的暂存区域,并分别提交每个区域,那我一天就可以节省几个小时

我可以拥有多个暂存区域,或者使用git实现类似的效果吗

我的典型工作流程如下:

  • 工作,工作,工作
  • 现在我有了一个有用的想法,让我们提交它
    git add-p
    y
    y
  • 但首先,这些较小的样式更改:
    git重置头。
  • git add-p
    n
    n
    y
    q
    git commit-m“样式更改”
  • git add-p
    。。做真实的事情

有时,我要从一大堆更改中做出20个较小的承诺。如果我能运行像git add-p这样的补丁,然后将每个补丁“分派”到它自己的暂存区域,并分别提交每个区域,那我一天就可以节省几个小时。

编辑,2020年5月30日:在git 2.15或更高版本中,我建议使用
git worktree
,而不是尝试执行以下操作。对添加的工作树有一些限制,这使得它们对于这种工作流有些恼人,但它可以工作,并且内置于现代Git中

请注意,如果您执行了下面我描述的操作,
git-gc
将不知道如何查看备用索引文件,事实上,从最初在git 2.5中引入到git 2.15中得到修复,
git-gc
忘记了检查添加的工作树及其索引文件

更多信息,请参阅


事实上,在git中可以有多个不同的暂存区域(更确切地说,是多个索引文件)。为了达到您想要的效果,您必须编写自己的
git add-p
变体,因此我在这里要做的是勾勒出一个轮廓,可以说,是如何做到这一点的

git使用的默认索引文件(如果您不将其指向其他索引文件)位于
.git/index
中(或者更准确地说,
$git\u DIR/.index
,其中
$git\u DIR
取自环境,如果没有设置,则取自
git rev parse--git DIR

但是,如果设置环境变量
GIT\u INDEX\u FILE
,GIT将使用该文件作为索引。因此,您可以通过以下操作开始“将更改分散到四个分支”过程:

GIT_DIR=${GIT_DIR:-$(git rev-parse --git-dir)} || exit 1
index_tmp_dir=$(mktemp -d) || exit 1
trap "rm -rf $index_tmp_dir" 0 1 2 3 15 # clean up on exit

# make four copies of initial staging area
for f in i1 i2 i3 i4; do
    cp $GIT_DIR/index $index_tmp_dir/$f
done

# THIS IS THE HARD PART:
# Now, using `git diff-files -p` or similar, get patches
# (diff hunks).
# Whenever you're ready to stage one, pick an index for it,
# then use:
GIT_INDEX_FILE=$index_tmp_dir/$which git apply --cached < diffhunk

# Once done, commit each index file separately with some
# variation on:
for f in i1 i2 i3 i4; do
    GIT_INDEX_FILE=$index_tmp_dir/$which git commit
done
GIT_DIR=${GIT_DIR:-$(GIT rev parse--GIT DIR)}| |退出1
索引_tmp_dir=$(mktemp-d)|退出1
陷阱“rm-rf$index_tmp_dir”01 2 3 15#出口清理
#制作初始暂存区的四份副本
对于i1i2i3i4中的f;做
cp$GIT\U目录/索引$index\tmp\U目录/f
完成
#这是最难的部分:
#现在,使用'git diff files-p'或类似工具,获得补丁
#(不同的大块头)。
#当你准备好第一阶段时,为它选择一个索引,
#然后使用:
GIT_INDEX_FILE=$INDEX_tmp_dir/$哪个GIT应用--缓存
对于标记为“硬部分”的部分,您最好复制git的AddInteractivePerl脚本,该脚本位于
$(git--exec path)/git add--interactive
,然后根据需要修改它。要删除“恰好四次提交”限制,请使此修改的交互式添加动态创建一个新的索引文件(通过复制原始文件,或者创建一个等于
提交或任何内容的“空”索引;也请参见
git read tree

编辑:部分的一些变体实际上应该几乎肯定地使用
git write tree
git commit tree
从每个提交中生成新的分支,使用当前提交的父级作为它们的父级,而不是允许
git commit
将提交作为线性链串在一起。这意味着还必须为这些新创建的分支选择某种命名方案。

2015年7月,它允许一个克隆、多个工作树,您可以在其中隔离各种修改

但是现在(2019年第4季度),您将无法再修改
git-add--interactive.perl
,因为在git 2.25(2020年第1季度)中,“
git-add-i
”已经被扩展到了除“
补丁
”之外的子命令

参见,,,,(2019年11月29日)by.
(于2019年12月16日合并)

:执行
补丁
命令 签字人:Johannes Schindelin

嗯,它还没有完全实现。为了使其易于检查(并且易于排除bug),我们仍然将工作交给Perl脚本来完成

补丁
功能实际上占了git add--interactive.perl的1800多行的一半以上。稍后,它将以增量方式从Perl移植到C

仍然在重写git插件C的上下文中:更多的测试覆盖率更新,为“
git add-i
”的进一步工作做准备

参见,,,,(2019年12月6日)by.
(于2019年12月16日合并)

:当差异生成失败时,使用非零退出代码 签字人:Johannes Schindelin

git add-p
做的第一件事是生成一个差异。如果无法生成这个差异,
git add-p
不应该像什么都没有发生一样继续,而是失败

我们在这里实际做的事情要广泛得多:现在,我们为每个
run\u cmd\u pipe()
调用验证生成的进程是否确实成功

注意,我们必须在这个补丁中更改两个调用者,因为我们需要将生成的进程的输出存储在一个局部变量中,这意味着调用者不再能够决定是在数组中还是在标量上下文中解释
返回

这个bug是在为diff.algorithm特性编写测试用例时发现的,我们也让这个测试用例作为这个固定bug的回归测试


通过Git 2.25(2020年第1季度),努力