我只是出于好奇才问这个。现实生活中这种情况还有其他的处理方式,但是我觉得git下面的行为有点奇怪。
摘要:隐藏在幕后创建了两个提交,一个包含索引,另一个包含未添加的编辑。如果我们检查后者并尝试对其进行变基,我们不知何故只能从索引中获取更改。这是为什么?
详细示例如下:
首先让我们使用一次提交创建一个 repo,然后再添加一次编辑到索引,然后再进行一次未添加到索引的编辑,然后存储:
git init
echo 1 > a.txt
git add a.txt
git commit -m"First commit"
echo 2 >> a.txt
git add a.txt
echo 3 >> a.txt
git stash
git log --all --graph --oneline
* 5c00fc0 WIP on master: c8af537 First commit
|\
| * 965c986 index on master: c8af537 First commit
|/
* c8af537 First commit
因此,git stash
似乎将索引和未添加的编辑都保存为具有自己哈希值的提交(在我的情况下,索引为 965c986,未添加的编辑为 5c00fc0)。
现在编辑一个新文件并提交:
echo x >> b.txt
git add b.txt
git commit -m"Second commit"
所以所有的提交现在看起来像:
git log --all --graph --oneline
* b589f50 Second commit
| * 5c00fc0 WIP on master: c8af537 First commit
| |\
|/ /
| * 965c986 index on master: c8af537 First commit
|/
* c8af537 First commit
比如说,我们现在想要获取隐藏的编辑并将它们与第二次提交结合起来。还有其他方法可以做到这一点(例如git stash apply
,但是如果我们已经清理了存储,然后从 reflog 中挖掘了提交怎么办),但让我们尝试一下:
git checkout 5c00fc0
[warning message here]
cat a.txt
1
2
3
git rebase master
First, rewinding head to replay your work on top of it...
Applying: index on master: c8af537 First commit
但是现在,生成的文件a.txt
只是:
cat a.txt
1
2
这是整个图表:
git log --all --graph --oneline
* 5fc3ade index on master: c8af537 First commit
* b589f50 Second commit
| * 5c00fc0 WIP on master: c8af537 First commit
| |\
|/ /
| * 965c986 index on master: c8af537 First commit
|/
* c8af537 First commit
所以看起来,即使我们检查了提交 5c00fc0,rebase 也只应用了提交 965c986 的更改,即我们隐藏时索引中的编辑。但是 5c00fc0 中的任何内容都被忽略了。
问:为什么会这样?这种行为有一些合理的解释吗?或者这应该被认为是一个错误?