我有一个git问题,我在任何地方都没有阅读过,所以请向我解释一下。 让我们说我和同事都从提交A开始工作。此时文件X不存在。我和我的同事都在不知情的情况下创建了这个文件。他推了几个,所以我们站在提交E。我试图git pull,但是OFC它告诉我我的本地文件会被覆盖,我应该藏起来。好的,我已经使用了git stash,试图再次拉动。 Git表示存在本地冲突,显示该文件名为X,因此无法提取。好的,我已经把git藏起来了,做了一个提交。然后我拉了,git automerge告诉我它将合并冲突。好的,最后文件X的内容是我所推动的,而我的同事的工作也永久地消失了。
那发生了什么?我以某种方式覆盖了服务器上的文件或者什么?怎么可能呢?
答案 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),这将有所帮助。当然,你的问题的关键是你不知道你是如何做到这一点的。但问题是,我们也不是!我们只能猜测。
我的猜测是你从来没有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:它无法帮助添加/添加冲突,默认情况下它不会保存未跟踪的文件。)