我已经不情愿地从分支develop
切换到分支analytics
,在那里我有未保存的更改。现在我正在尝试切换回analytics
分支并收到以下错误:
error: The following untracked working tree files would be overwritten by checkout:
application/db/some.sql
modules/analytics/config/database.php
如何在不丢失数据的情况下解决问题?
答案 0 :(得分:2)
您看到的错误消息表明相关文件未在当前分支中进行跟踪,但在您要切换到的分支中进行跟踪。
以下是一个例子,仅使用一个文件:
$ 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-file
,在分支dev
中进行跟踪。
$ git checkout master # get back to situation without dev-file
Switched to branch 'master'
$ ls
LICENSE.txt x.txt
我们发现此处不存在dev-file
。让我们来创造它。
$ 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-file
,如果/当我们设法git checkout dev
时。我们可以看到与git diff
进行比较:
$ git diff dev:dev-file dev-file
$
如果我们用不同的内容替换此未跟踪的文件(请记住,此时我们仍然在master
上),并尝试相同的git diff
,我们和#39;看到他们不匹配:
$ 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
$
但问题不是真的&#34;他们是否匹配&#34;,而是&#34;你想对这种情况做些什么&#34; (其中dev-file未在master
中跟踪,在dev
中跟踪,并且在我们为&#34;在分支master
&#34;)时存在于工作目录中。< / p>
你可以:
git add
和git commit
它(使其在当前分支上进行跟踪,在本例中为master
):它现在通过新提交永久保存; master
上时),以便git checkout dev
成功,然后git checkout dev
; git checkout -f dev
清除文件并立即进入分支dev
(与方法2相同); git stash -u
,或者手动将其复制到存储库之外的某处; 方法2和3简单地清除当前分支上的版本,将其替换为分支dev
上的版本。如果git diff
说当前版本和dev
版本之间没有区别,那么您显然没有丢失过程中的任何实际文件内容(因为它保留在分支{ {1}})。如果dev
表示 存在差异,那么您将失去非git diff
版本。
在任何一种情况下,如果你切换回dev
,文件将会消失:
master
(它回到$ git checkout -f dev
Switched to branch 'dev'
$ cat dev-file
contents
中的版本。)
dev
(它已经消失了。我们总是可以在$ git checkout master
Switched to branch 'master'
$ cat dev-file
cat: dev-file: No such file or directory
中检索版本,但我们之前放入的dev
已经消失了。)
如果使用different-contents
保存未跟踪的文件,您将有一个可以从中恢复未跟踪文件的位置。像这样使用git stash -u
会节省很多东西;请参阅git stash -u
的文档。
如果您将未经跟踪的文件完全保存在git之外,那么您将有一个(非git)地方可以从中恢复未跟踪的文件。
如果您将未跟踪的文件提交到原始分支,那么您将拥有一个实际位置,分支本身(此处为git stash
- 从中恢复文件,这些文件不再是未跟踪的。
哪种解决方案最好?没有人回答。也许他们应该被跟踪。也许他们应该像现在一样被跟踪#34;即使在分支master
中也许它们应该没有被跟踪(这意味着你必须在分支dev
上进行一些操作以使它们在那里变得不受限制:特别是,你会有检查该分支,使用dev
或git rm --cached
,并在该分支中进行新的提交。 Git不能为你做出这个决定,也不能;你需要弄清楚你想要用这些文件发生什么。
编辑:现在我们知道工作目录通过以下方式进入此状态:
git rm
我可以补充一点。我不能详细介绍,因为我自己没有尝试过很多细节,也没有使用任何细齿梳子在git中查看索引代码。但是,索引的一个方面是跟踪工作树中的内容。
它非常昂贵,至少在一个大型项目中,在很多目录中有很多文件中有很多代码来搜索整个工作树 - 但是有一些聪明,git不需要去做。我们假设您的工作树从git --work-tree=/path/outside/here checkout develop
开始,例如您有.
。在索引(modules/analytics/config/*
)内部,有一些条目跟踪stat
有关该目录中文件的信息,如签出。
Git也知道您(.git/index
会报告)git status
。然后你调用on branch analytics
。
git不是在工作目录中搜索&#34;那里有什么&#34;,而是可以使用索引中的数据假设&#34;什么&#34;那里&#34;是最后签出的。在某些情况下(我不确定哪些情况),git将重新执行git checkout develop
并知道索引已过期。在其他人(我再也不确定哪个)中,我可以通过观察看到它没有这样做:它只是假设stat
描述了工作树。
如果您总是使用相同的工作树,使用该(单个)索引,它就会起作用&#34;。如果你使用.git/index
将git指向另一个工作树,我已经看到它的作用相当于:&#34;啊,好吧,从--work-tree
切换到{{1}我只需要删除这个文件并将其替换为另一个文件&#34; - 这样就可以了。
您可以强制git使用analytics
的其他索引文件。例如,如果您想跟踪develop
中的内容,您可以拥有一个名为(例如)GIT_INDEX_FILE=path
的文件:
/path/outside/here
这还有另外一个问题,.git/index-alt
将切换您当前的分支。要解决此问题,请使用# 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 checkout ...
现在&#34;备用索引&#34;跟踪备用工作树,git checkout
永远不会更改,因此本地存储库永远不会被搞乱。 (我没有对此进行过测试,但是应该可以使用它 - 我已经计划在其中使用的东西作为&#34;以及如何最好地使用post-receive hooks在服务器上部署版本&#34;。 )
答案 1 :(得分:1)
您可以使用git stash git stash -u
。 Git Stash
答案 2 :(得分:1)
如果目的是获取当前更改并将其应用于分支analytics
,那么您应该执行以下操作
git stash
git checkout analytics
git stash pop
stash
命令将存储当前分支更改并将工作目录重置为HEAD
。切换到分析分支后,您可以使用stash pop
重新应用更改。这会将最新的stash
命令应用于当前工作目录