从藏匿,奇怪的结果重新开始

时间:2013-07-25 04:46:49

标签: git

我只是出于好奇而问这个问题。在现实生活中还有其他方法可以解决这种情况,但我发现git的以下行为有点奇怪。

摘要: Stashing幕后创建两个提交,一个包含索引,另一个包含非添加的编辑。如果我们检查后者并尝试重新定义它,我们只能从索引中获取更改。那是为什么?

详细示例如下:

首先让我们使用一次提交创建一个repo,然后再添加一个编辑添加到index,然后再创建一个未添加到index的编辑,然后使用stash:

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中的任何内容都被忽略了。

问题:为什么?对这种行为有一些合理的解释吗?或者这应该被视为一个错误?

3 个答案:

答案 0 :(得分:1)

原来,git只是(默认情况下)在重新定位时忽略合并提交。并且存储创建WIP提交和索引提交,WIP提交是合并,因为它同时具有索引提交和c8af537作为父项。

与藏匿无关。

答案 1 :(得分:0)

今天早上我在GUI应用程序中意外丢下了一个藏匿处时遇到了这个问题。起初我像其他人一样尝试过变形,因为这是很自然的事情。然后我用duckduckgo搜索并找到了这个,但没有实际的解决方案。所以我尝试了一下,并想出了这个:

假设我们有以下分支/参考:

  • droppedStash 指向具有所需的人工合并提交 含量
  • parentOfStash 指向此的原始基本提交 前存储分支

然后我们可以做到:

  1. git checkout parentOfStash
  2. git cherry-pick -m 1 droppedStash
  3. 其中-m 1告诉git将其中一个祖先视为主线。塔达!享受: - )

答案 2 :(得分:-1)

大量编辑我的原始答案。

我做了一些潜入代码和我自己的一些测试,我发现了问题。当你在你的无头分支上做你的rebase时,你就会变大。 rebase命令验证您正在变基的分支的头部,在这种情况下不包括存储。试试这个:

git checkout -b stashbranch 5c00fc0
git rebase stashbranch
git log --oneline --decorate --all

您应该看到类似的内容:

b589f50 (HEAD, refs/stash, stashbranch) Second commit

注意:如果你处于一个独立的头部状态但是运行git rebase master,那么根据我的测试,它会把你的头放到主头。您可以完成git rebase 5c00fc0并获得与分支相同的结果。