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

6tdlim6h  于 2023-08-01  发布在  Git
关注(0)|答案(7)|浏览(106)

如果一些更改被添加到索引中,而另一些更改没有被添加到索引中,我如何交换这两组更改?

41ik7eoe

41ik7eoe1#

它认为使用临时提交最容易做到这一点。当你有staged和unstaged提交时,你在尝试重新排序更改时可能会发生冲突。
使用阶段性更改进行提交,创建一个分支供以后用途:

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

ewm0tg9j

ewm0tg9j2#

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

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

字符串
这样做的目的是在git store中构建两个临时树对象,一个用于索引,一个用于工作副本。然后,它恢复旧索引并将其 checkout 到工作树中。最后,它将索引重置为表示旧工作树的版本。
我还没有测试过它,所以我不确定它在处理索引或工作树中添加的文件时表现如何。

chy5wohz

chy5wohz3#

使用补丁的方式(它不适用于二进制更改):
保存暂存状态和未暂存状态的修补程序

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

brccelvz

brccelvz4#

这是基于Walter穆特的答案,但在暂存新文件时效果更好。这旨在用作脚本,例如第一个月

#!/bin/sh

# first, go to the root of the git repo
pushd `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

# return to the original folder
popd

字符串

hwazgwia

hwazgwia5#

Charles Bailey有一个更完整的解决方案,涉及提交和管理潜在的冲突解决方案。
我最初只尝试使用git stash,除了我最初忽略的是git stash save将保存 * 索引(暂存更改)和未暂存更改(当您想要交换索引内容与未暂存更改时,这是不方便的)。
因此,我修改为以下方法:

  • git commit-m“临时提交”(为当前索引创建一个提交)
  • git stash(显然是存储尚未添加到索引中的内容)
  • git reset --soft HEAD^(保留以前提交的文件)
  • git stash再次
  • git stash pop stash@{1}(不是应用你刚刚隐藏的内容,而是应用你之前隐藏的内容,即尚未添加到索引中的初始更改)
  • git add -A
  • git stash drop stash@{1}来清理我们之前应用的stash(stash@{0}仍然包含索引中的原始内容)

最后:

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

qij5mzcb6#

它可以通过3个步骤完成:

git stash push -S
git add .
git stash pop

字符串
你也可以把所有这些都打包在一个命令中,如下所示:

alias swap='git stash push -S && git add . && git stash pop'


现在您可以在命令行上简单地执行swap

omtl5h9j

omtl5h9j7#

use `git rebase -i the best solution.
备选项(太长):

Note the name of your current branch as:
<name-of-your-branch>

git checkout -b temp-unstaged
git commit -m "staged"
git branch temp-staged
git add .
git commit -m "unstaged"
git rebase --onto HEAD~2 HEAD~1
git checkout temp-staged
git rebase temp-unstaged
git reset HEAD~1
git reset --soft HEAD~1
git checkout <name-of-your-branch>
git branch -D temp-staged
git branch -D temp-unstaged

字符串
最后,可以验证暂存和未暂存的更改是否交换。

相关问题