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

whi*_*red 31 git

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

CB *_*ley 14

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

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

git commit -m "Saved staged"
git branch save-staged
Run Code Online (Sandbox Code Playgroud)

使用未分级的更改进行提交(如果未分级的更改包含您可能需要先显式更新的新文件git add):

git commit -a -m "Unstaged changes"
Run Code Online (Sandbox Code Playgroud)

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

git rebase --onto HEAD^^ HEAD^
Run Code Online (Sandbox Code Playgroud)

将暂存的更改重新基于未分级的更改(可能涉及冲突解决):

git reset --hard save-staged
git rebase --onto HEAD@{1} HEAD^
Run Code Online (Sandbox Code Playgroud)

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

git reset HEAD^
Run Code Online (Sandbox Code Playgroud)

并将分支指针移回原始HEAD:

git reset --soft HEAD^
Run Code Online (Sandbox Code Playgroud)

删除临时分支:

git branch -D save-staged
Run Code Online (Sandbox Code Playgroud)


whi*_*red 6

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

保存暂存和未暂存状态的补丁

git diff >> unstaged.patch
git diff --cached >> staged.patch
Run Code Online (Sandbox Code Playgroud)

应用最初未暂存的更改

git reset --hard
git apply unstaged.patch
Run Code Online (Sandbox Code Playgroud)

暂存此更改(补丁文件除外)

git add -A
git reset -- staged.patch unstaged.patch
Run Code Online (Sandbox Code Playgroud)

应用最初阶段的更改

git apply staged.patch
Run Code Online (Sandbox Code Playgroud)

删除补丁文件

rm staged.patch unstaged.patch
Run Code Online (Sandbox Code Playgroud)


Wal*_*ndt 5

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

INDEXTREE=`git write-tree`
git add -A
WORKTREE=`git write-tree`
git checkout $INDEXTREE -- .
git clean -f
git read-tree $WORKTREE
Run Code Online (Sandbox Code Playgroud)

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

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


Jes*_*eke 5

这是基于Walter Mundt的答案,但在新文件上演时效果更好.这旨在用作脚本,例如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
Run Code Online (Sandbox Code Playgroud)