多个登台区域 [英] Multiple staging areas

查看:58
本文介绍了多个登台区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用git来实现多个暂存区或达到类似的效果吗?

Can I have multiple staging areas or achieve a similar effect using git?

我的典型工作流程如下:

My typical work flow is along the lines of:

  • 工作,工作,工作
  • 现在我有了一些有用的想法,让我们提交它git add -pyy
  • 但首先这些较小的样式更改:git reset HEAD .
  • git add -pnnyqgit commit -m "style changes"
  • git add -p ..提交实际的东西
  • work, work, work
  • now I have an idea of something useful, let's commit it git add -p, y, y
  • but first these smaller style changes: git reset HEAD .
  • git add -p, n, n, y, q, git commit -m "style changes"
  • git add -p .. commit the actual thing

有时候,我需要通过大量更改来进行20次较小的提交.如果我可以遍历git add -p之类的补丁程序,然后将每个补丁程序分发"到其自己的暂存区域并分别提交每个区域,则可以每天为我节省几个小时.

Sometimes I have 20 smaller commits to make from a huge pile of changes. It would save me hours a day, if I could run through the patches like git add -p and then "dispatch" each patch to it's own staging area and commit each area separately.

推荐答案

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

Edit, 30 May 2020: In Git 2.15 or later I recommend using git worktree instead of trying to do the below. There are some restrictions on added work-trees that make them somewhat annoying for this kind of work-flow, but it can work, and is built in to modern Git.

请注意,如果您执行 的操作,如下所述,则git gc将不知道在备用索引文件中查找,实际上,从最初在Git 2.5中引入到现在为止,已在Git 2.15中修复,git gc忘记了检查添加的工作树及其索引文件!

Note that if you do do something like I describe below, git gc won't know to look in your alternate index files, and in fact, from its original introduction in Git 2.5 until it was fixed in Git 2.15, git gc forgot to check added work-trees and their index files!

有关更多信息,请参见 VonC的答案.

See VonC's answer for more.

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

You can in fact have multiple different staging areas (more literally, multiple index files) in git. To achieve the effect you want you would have to write your own variant of git add -p anyway, so what I will do here is sketch an outline, as it were, of how to do this.

默认索引文件(如果不将其定向到其他索引文件,则使用一个git)位于.git/index(或更确切地说,是$GIT_DIR/.index,其中$GIT_DIR来自环境)或者,如果未设置,请从git rev-parse --git-dir).

The default index file—the one git uses if you don't direct it to some other index file—lives in .git/index (or, more shell-correctly, $GIT_DIR/.index where $GIT_DIR is taken from the environment or, if not set there, from git rev-parse --git-dir).

但是,如果设置环境变量GIT_INDEX_FILE,则git将使用该文件作为索引.因此,您可以通过执行以下操作来开始将更改分散到四个分支"过程:

If you set the environment variable GIT_INDEX_FILE, however, git will use that file instead as the index. Thus, you might begin your "scatter changes to four branches" process by doing something like this:

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的add-interactive perl脚本(在$(git --exec-path)/git-add--interactive中找到),然后对其进行修改以适合需要.要删除恰好四个提交"限制,请使此修改后的交互式添加动态创建一个新的索引文件(通过复制原始索引文件,或者创建一个等于HEAD提交或其他内容的空"索引;请参见git read-tree也是如此).

For the part labeled "hard part", your best bet might well be to copy git's add-interactive perl script, found in $(git --exec-path)/git-add--interactive, then modify it to suit. To remove the "exactly four commits" restriction, make this modified interactive-add create a new index file dynamically (by copying the original, or perhaps creating an "empty" index equal to the HEAD commit or whatever; see git read-tree as well).

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

the some variation on section really should almost certainly use git write-tree and git commit-tree to make new branches out of each of these commits, using the parent of the current commit as their parent, rather than allowing git commit to string the commits together as a linear chain. That means one must also choose some naming scheme for these various newly-created branches.

这篇关于多个登台区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆