在git中交换暂存和未分阶段更改的最短方法是什么?

时间:2010-08-26 08:37:00

标签: git

如果对索引添加了一些更改,并且某些更改未添加到索引中,我该如何交换这两组更改?

5 个答案:

答案 0 :(得分:13)

它认为这对于临时提交最容易。如果您有暂存和未暂存的提交,则在尝试重新排序更改时可能会发生冲突。

使用暂存的更改进行提交,创建一个分支供以后使用:

git commit -m "Saved staged"
git branch save-staged

使用未暂存的更改进行提交(如果未暂存的更改包含您可能需要首先明确git add的新文件):

git commit -a -m "Unstaged changes"

将未分段的更改重新定位到原始HEAD(可能涉及冲突解决):

git rebase --onto HEAD^^ HEAD^

将暂存的更改重新定位到未暂存的更改(可能涉及解决冲突):

git reset --hard save-staged
git rebase --onto HEAD@{1} HEAD^

最后,将索引重置为(最初)未暂停的更改:

git reset HEAD^

将分支指针移回原始HEAD:

git reset --soft HEAD^

删除了临时分支:

git branch -D save-staged

答案 1 :(得分:5)

对于较低级别的解决方案,您可以使用一些管道直接与索引进行对话:

INDEXTREE=`git write-tree`
git add -A
WORKTREE=`git write-tree`
git checkout $INDEXTREE -- .
git clean -f
git read-tree $WORKTREE

这样做是在git商店中构建一些临时树对象,一个用于索引,另一个用于工作副本。然后,它恢复旧索引并将其检出到工作树中。最后。它将索引重置为表示旧工作树的版本。

我没有测试过这个,所以我不确定它在索引或工作树中处理添加文件的效果如何。

答案 2 :(得分:5)

这基于Walter Mundt's answer,但在新文件上演时效果更好。这旨在用作脚本,例如git-invert-index

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# write out a tree with only the stuff in staging
INDEXTREE=`git write-tree`

# now write out a tree with everything
git add -A
ALL=`git write-tree`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
git clean -fd

# apply the changes that were originally staged, that we want to
# be unstaged
git checkout $INDEXTREE -- .
git reset

# apply the originally unstaged changes to the index
git diff-tree -p $INDEXTREE $ALL | git apply --index --reject

答案 3 :(得分:3)

Charles Bailey有一个more complete solution涉及提交和管理潜在的冲突解决方案。

我最初只尝试使用git stash,除了我最初忽略的是git stash保存将保存索引(分阶段更改)和未分阶段的更改(当您想要将索引内容与未分级的更改交换时,这是不方便的。

所以我改为采用以下方法:

  • git commit -m“temp commit”(为当前索引创建提交)
  • git stash(明显存放尚未添加到索引中的内容)
  • git reset --soft HEAD^(保留以前提交的文件)
  • git stash再次
  • git stash pop stash@{1}(不是应用你刚刚藏匿的东西,而是应用之前存储的内容,即尚未添加到索引中的初始更改)
  • git add -A
  • git stash drop stash@{1}清理我们之前申请的藏匿处(藏匿@ {0}仍包含最初在索引中的内容)

最后:

  • 现在添加了未添加到索引的内容。
  • 最初在索引中的内容最终被隐藏

答案 4 :(得分:3)

补丁的方式(它不适用于二进制更改):

保存分阶段和非分阶段状态的补丁

git diff >> unstaged.patch
git diff --cached >> staged.patch

应用最初的非分段更改

git reset --hard
git apply unstaged.patch

除了补丁文件

之外,此阶段会发生变化
git add -A
git reset -- staged.patch unstaged.patch

应用最初暂存的更改

git apply staged.patch

删除补丁文件

rm staged.patch unstaged.patch