Git stash没有保存文件

时间:2017-05-18 11:56:34

标签: git

我有一个git问题,我在任何地方都没有阅读过,所以请向我解释一下。 让我们说我和同事都从提交A开始工作。此时文件X不存在。我和我的同事都在不知情的情况下创建了这个文件。他推了几个,所以我们站在提交E。我试图git pull,但是OFC它告诉我我的本地文件会被覆盖,我应该藏起来。好的,我已经使用了git stash,试图再次拉动。 Git表示存在本地冲突,显示该文件名为X,因此无法提取。好的,我已经把git藏起来了,做了一个提交。然后我拉了,git automerge告诉我它将合并冲突。好的,最后文件X的内容是我所推动的,而我的同事的工作也永久地消失了。

那发生了什么?我以某种方式覆盖了服务器上的文件或者什么?怎么可能呢?

2 个答案:

答案 0 :(得分:0)

首先,当您使用git stash save时,在命令之后它应该没有可用的修改文件,然后如果您git pull编辑了您的分支,则冲突不应该可用/发生。因此,我说你的第一个git stash save没有成功。

其次,如果您成功git pull分支您的分支后,您的同事的工作已自动合并到您的分支机构,该分支机构应该可用。

请通过以下方式检查git log

git log --name-status

然后,通过以下方式检查代码差异:

git show <<Commit ID>>

您的需求代码是否可用。

答案 1 :(得分:0)

MVCE会帮助

如果你一步一步地展示完全你做了什么,或者甚至更好 - 提供了一个最小的,完整的,可验证的例子(也称为MVCE),这将有所帮助。当然,你的问题的关键是你不知道你是如何做到这一点的。但问题是,我们也不是!我们只能猜测

我的猜测是你从来没有git add编辑过该文件。让我们来看看我的 MVCE。我首先创建一个带有master分支的一个提交存储库,只有一个README文件。 (顺便说一下,这些提交消息很糟糕。)

$ mkdir tt; cd tt
$ git init
Initialized empty Git repository in ...
$ echo demo failure to save file in stash > README
$ git add README
$ git commit -m initial
[master (root-commit) 0442487] initial
 1 file changed, 1 insertion(+)
 create mode 100644 README

现在让我们成为您的同事分支,您最终会将其作为origin/master带入您的存储库。我们无法以这种方式建立远程跟踪分支(我可以通过作弊来实现)所以让我们只使用常规分支:

$ git checkout -b other
Switched to a new branch 'other'
$ echo new file X > X
$ git add X
$ git commit -m 'new file X on branch other'
[other 37681f5] new file X on branch other
 1 file changed, 1 insertion(+)
 create mode 100644 X
$ git checkout master
Switched to branch 'master'

现在我们准备回到你身边。让我们创建一个新文件,但不能git add它。我们还要修改README:我们需要这样做才能让git stash做任何事情。我们可以git add README更改,或git add更改,无论我们更喜欢哪个;这部分没有区别。

$ echo our new file X is different from his > X
$ echo 'add extra line to readme' >> README

您现在运行git pull并收到投诉。我们确实无法在这里运行git pull,但我们不必:所有git pull都会运行git fetch以获取提交权限您的上游远程,然后运行git merge将这些提交合并到您当前的分支。我总是建议那些刚接触Git的人避免使用git pull:对于那些粗心大意的人来说,它会充满陷阱,而且如果你自己只使用两个单独的命令,那么你会遇到更多问题。

因此,我们将执行两个单独命令的事情。但是:在这个例子中,我们没有(我们可以没有)git fetch你的工作者提交,这就是我们在上面创建一个名为other的分支的原因第一名。所以我们直接进入第二个命令git merge

$ git merge other
Updating 0442487..37681f5
error: The following untracked working tree files would be overwritten by merge:
    X
Please move or remove them before you merge.
Aborting

(顺便提一下,当您运行git pull时,它会有效地运行git merge origin/master,而不是git merge other。我们在这里使用other,因为我们制作了这个,而不是通过git fetch。)

藏匿什么,不做什么

我们现已达到您运行git stash的阶段。如果你首先运行git status,你会看到这一点,这可能是一个线索,虽然很难知道这部分应该引起什么样的关注:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    X

no changes added to commit (use "git add" and/or "git commit -a")

这里有两个有趣的信息,我们有一个经过修改但尚未上演的README,这对我们的git stash步骤更重要 - 未跟踪 file X

无论如何,让我们现在运行git stash(这意味着git stash save):

$ git stash
Saved working directory and index state WIP on master: 0442487 initial
HEAD is now at 0442487 initial

现在让我们看看git status(我猜你没有 - 这是一个错误;你应该经常检查git status):

$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    X

nothing added to commit but untracked files present (use "git add" to track)

还有令人讨厌的X!这里的要点是默认情况下git stash save 不会保存未跟踪的文件。 (你可以这样做,但如果你有,那就更糟了。不要这样做,直到你真正理解合并和合并的问题:你将自己陷入一个巨大的陷阱,可以只有通过了解合并问题才能解决。这是避免git pull的另一个原因:如果您学会直接使用git merge,那么您将了解合并和偶尔出现的问题。)

现在让我们再次模拟git pull。我们必须再次跳过获取步骤并直接转到git merge

$ git merge other
Updating 0442487..37681f5
error: The following untracked working tree files would be overwritten by merge:
    X
Please move or remove them before you merge.
Aborting

我们在这里:git stash没有帮助。

让我们尝试撤消现有的存储(将README恢复为修改但未添加的模式),然后git add X。通常我建议先使用git stash apply仔细检查结果,然后仅在您对结果感到满意时使用git stash drop ,但我们&# 39; ll只运行git stash pop,这意味着git stash apply && git stash drop

$ git stash pop
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    X

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (1e7d19ea701fcc3dd8e0157c9a8a8555f74316a4)

足够git stash!让我们继续正常提交和合并......

现在我们git add这两个文件并提交,而不是存储:

$ git add README X
$ git commit -m 'created file X'
[master 699e149] created file X
 2 files changed, 2 insertions(+)
 create mode 100644 X

现在我们可以合并。 (或者,如果我们有一个遥控器,我们可以通过pull来获取和合并。但是没有什么新东西可以获取,而且我们没有遥控器。此外,它还有#39;是时候了解合并是如何工作的!所以我们只是合并。)我们将得到添加/添加冲突:

$ git merge other
Auto-merging X
CONFLICT (add/add): Merge conflict in X
Automatic merge failed; fix conflicts and then commit the result.

同样,在您自己的情况下,您将执行git merge origin/master - 或只是git merge,它使用您当前分支的上游设置,这是大概是origin/master。但无论如何,我们现在有了这个&#34;添加/添加冲突&#34;。

解决冲突

当Git停止与冲突合并时,这意味着Git不知道该怎么做。 必须在此处提供帮助。你可以运行git status来看看Git到底有多远:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both added:      X

no changes added to commit (use "git add" and/or "git commit -a")

Git在我们的工作树中留下了文件X。但是有两个文件名为X:我们的,以及您的同事(我们将其模拟为other)。 Git离开了哪一个?这是X中的内容:

$ cat X
<<<<<<< HEAD
our new file X is different from his
||||||| merged common ancestors
=======
new file X
>>>>>>> other

所以,答案是它在工作树中留下了{em>两个版本的X。 (我将merge.conflictStyle设置为diff3,以便我的演出&#34;合并共同的祖先&#34;此处。如果您有默认的merge.conflictStyle设置,Git不会显示部分。由于没有共同的祖先,无论如何这部分都是空的 - 它在这里并不实用。它只在共同祖先时才有用,在期间修改/修改冲突。)

现在你的工作是提出X的合并版本,或者将这两个版本分成两个不同的文件。准确地说,你想要什么,以及你想怎么做,取决于你。我们要说我们要将我们的 X重命名为其他内容,并提取他们的(您的同事等) )X完整无缺:

$ git show HEAD:X > X.ours
$ git checkout --theirs X
$ cat X.ours
our new file X is different from his
$ cat X
new file X

现在git status将显示新的未跟踪文件X.ours以及冲突的文件。让git add调整X(仅回到他的版本)和新X.ours

$ git add X.ours X
$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   X
    new file:   X.ours

由于我们现在准备提交,我们现在可以与git commit结束合并。

(这是正确解决添加/添加冲突的示例。我注意到您说这不是发生的事情;但我不知道您做了什么这样做,如果没有更多信息,我甚至无法猜到那是什么。我已经集中精力于git stash 无法做到的事情 do:它无法帮助添加/添加冲突,默认情况下它不会保存未跟踪的文件。)