Git 已签出未保存的更改
我无意中从分支Git 已签出未保存的更改,git,Git,我无意中从分支分析切换到分支开发,在那里我有未保存的更改。现在我尝试切换回分析分支,并得到以下错误: error: The following untracked working tree files would be overwritten by checkout: application/db/some.sql modules/analytics/config/database.php 如何在不丢失数据的情况下修复问题?您可以使用git stashgit stash-u 您可以使用git
分析
切换到分支开发
,在那里我有未保存的更改。现在我尝试切换回分析
分支,并得到以下错误:
error: The following untracked working tree files would be overwritten by checkout:
application/db/some.sql
modules/analytics/config/database.php
如何在不丢失数据的情况下修复问题?您可以使用git stash
git stash-u
您可以使用git stashgit stash-u
如果目的是获取当前更改并将其应用于分支分析
,则应执行以下操作
git stash
git checkout analytics
git stash pop
stash
命令将存储当前分支更改,并将工作目录重置为HEAD
。切换到analytics分支后,您可以使用stash pop
重新应用更改。这会将最新的隐藏
命令应用于当前工作目录如果目的是获取当前更改并将其应用于分支分析
,则应执行以下操作
git stash
git checkout analytics
git stash pop
stash
命令将存储当前分支更改,并将工作目录重置为HEAD
。切换到analytics分支后,您可以使用stash pop
重新应用更改。这将对当前工作目录应用最新的stash
命令您看到的错误消息表明,在您当前的分支中未跟踪有问题的文件,但在您要切换到的分支中进行了跟踪
下面是一个仅使用一个文件的示例:
$ git checkout -b dev # create new branch dev (I was on master)
Switched to a new branch 'dev'
$ echo contents > dev-file
$ git status
On branch dev
Untracked files:
(use "git add <file>..." to include in what will be committed)
dev-file
nothing added to commit but untracked files present (use "git add" to track)
$ git add dev-file
$ git commit -m 'dev-file is tracked in dev'
[dev 24e6171] dev-file is tracked in dev
1 file changed, 1 insertion(+)
create mode 100644 dev-file
我们看到这里不存在dev文件
。让我们创建它
$ echo contents > dev-file
$ git checkout dev
error: The following untracked working tree files would be overwritten by checkout:
dev-file
Please move or remove them before you can switch branches.
Aborting
$
问题是,您想对这些文件做什么
在本例中,我们创建了dev文件
,如果我们设法git checkout dev
的话,该文件将具有相同的内容。我们可以看到,与git diff相比:
$ git diff dev:dev-file dev-file
$
如果我们用不同的内容替换此未跟踪文件(请记住,此时我们仍在master
),并尝试相同的git diff
,我们将看到它们不匹配:
$ echo different-contents > dev-file
$ git diff dev:dev-file dev-file
diff --git a/dev-file b/dev-file
index 12f00e9..462c93f 100644
--- a/dev-file
+++ b/dev-file
@@ -1 +1 @@
-contents
+different-contents
$
然而,问题不是真正的“它们匹配吗”,而是“对于这种情况,您想做些什么”(在这种情况下,dev文件在master
中未被跟踪,在dev
中被跟踪,并且在我们“在分支master
上”时存在于工作目录中)
你可以:
git add
和git commit
它(在当前分支上跟踪它,在本例中为master
):它现在通过新提交永久保存李>
master
上时),以便git checkout dev
将成功,然后git checkout dev
李>
git checkout-f dev
一次性清除文件并进入分支dev
(与方法2相同)李>
git stash-u
,或者手动将其复制到存储库之外的某个位置李>
dev
上的版本。如果git diff
说当前版本和dev
-version之间没有区别,那么显然在这个过程中没有丢失任何实际的文件内容(因为它保存在分支dev
中)。如果git diff
表示存在差异,您将丢失非dev
版本
但是,无论哪种情况,如果切换回主控
,文件将消失:
$ git checkout -f dev
Switched to branch 'dev'
$ cat dev-file
contents
(回到dev
中的版本)
(它不见了。我们总是可以在dev
中检索版本,但我们先前放入其中的不同内容也不见了。)
如果使用git stash-u
保存未跟踪的文件,则可以从中恢复未跟踪的文件。像这样使用git stash-u
可以节省很多东西;请参阅git stash的文档
如果您将未跟踪的文件完全保存在git之外,您将有一个(非git)位置来恢复未跟踪的文件
如果您将未跟踪的文件提交到原始分支中,实际上您将有一个位置,分支本身,这里是master
——从中恢复不再未跟踪的文件
哪一个是最好的解决方案?没有人回答。也许他们应该被追踪。也许他们应该像现在这样“半途而废”。甚至在branchdev
中也应该取消对它们的跟踪(这意味着您必须在branchdev
上执行一些操作才能使它们在那里取消跟踪:特别是,您必须签出该分支,使用git rm--cached
或git rm
,并在该分支中进行新的提交)。吉特不能为你做这个决定,我也不能;您需要弄清楚这些文件会发生什么
编辑:现在我们知道工作目录通过以下方式进入此状态:
git --work-tree=/path/outside/here checkout develop
我可以补充一点。我不能说得太详细,因为我自己也没有做过太多的实验,也没有用任何形式的细细梳理过git中的索引代码。但是,索引的一点是跟踪工作树中的内容
搜索整个工作树是非常昂贵的,至少在一个大型项目中,有很多代码,有很多文件,有很多目录,但由于一些聪明,git不必这样做。假设您的工作树从
开始,您有模块/analytics/config/*
。在索引(.git/index
)中,有一些条目跟踪该目录中已签出的文件的信息
Git还知道您(正如Git status
将报告的那样)正在分支分析中
git --work-tree=/path/outside/here checkout develop
# note: this assumes $GIT_DIR is set, as it is with "git-sh-setup"
# so let's set it:
GIT_DIR=$(git rev-parse --git-dir) || exit
alt_index=${GIT_INDEX_FILE-"$GIT_DIR/index"}-alt
GIT_INDEX_FILE=$alt_index git --work-tree=/path/outside/here git checkout ...
GIT_INDEX_FILE=$alt_index git --work-tree=/path/outside/here checkout branchname -- .