Git 神秘地删除东西(编辑:实际上是 django-storages)
问题:有时(但并非每次)Git 会删除存储库的 static
目录。我们不确定是什么触发了它,但它似乎在分支之间合并或有时甚至只是检查分支时发生。它无需询问即可执行此操作,并吃掉跟踪的文件。
背景:
- 我有一个(私人)项目,有几个分支,“发布”,“开发”,多个功能线。
- 我们两个人(我和@stevejalim)正在处理这个仓库。这个问题发生在我们俩身上。
- 我纯粹使用命令行来执行 git 命令; Steve 混合使用了命令行和 Git Tower。
- 这是一个带有
static
目录的 Django 项目。我们可能在过去的某个时刻对static
目录进行了 git rm 编辑,或者将其放入.gitignore
中,但不是最近。我们的开发分支的负责人在.gitignore
中没有static
,并且在static
中跟踪了文件。 - 这种情况很少发生,以至于我们不确定这是否是我们正在做的事情,或者是间歇性问题,Git 的错误,或者损坏的树。
- 它可能只有在将另一个分支合并回<代码>开发。但分支总是从
develop
分支出来并返回到develop
。但我们不确定。 我们正在使用 git-flow,但在使用非 git-flow 命令时也会出现问题。
作为何时发生这种情况的示例:
1) Steve 有一个干净且稳定的开发分支(没有对提交或阶段进行任何更改)。他使用 git flow release start|finish 剪切了一个新版本,在此过程中(可能是从 master 到开发的反向合并),整个 /static/ 树被删除。
2) Steve 通过放弃更改来修复删除(实质上是取消删除文件)。但后来,史蒂夫只是从 master 切换回开发,/static/ 目录再次被破坏(这是 Git Tower 的情况)
3) 有时,仅从功能分支合并到开发作为临时合并就可以触发它。不过,在削减新版本时,这种情况似乎最常发生,
是否与我们如何修复 /static/ 目录的切换有关?批量取消删除已删除内容的最佳方法是什么?放弃本地更改或硬重置 HEAD 似乎都无法解决问题。变基可能对我们有帮助吗?
更新我们刚刚通过 git add 再次经历了这一点。
- 没有更改分支,没有合并。这对诊断有帮助吗?
这是 Steve 的 .git/config 的内容:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = [email protected]:foobarbazbam/bar.git
[branch "master"]
remote = origin
merge = refs/heads/master
[gitflow "branch"]
master = master
develop = develop
[gitflow "prefix"]
feature = feature/
release = release/
hotfix = hotfix/
support = support/
versiontag =
[difftool "tower"]
cmd = \"/Applications/Tower.app/Contents/Resources/CompareScripts/kaleidoscope.sh\" \"$LOCAL\" \"$REMOTE\"
这是 .gitignore
的内容:
.DS_Store
*.pyc
*.log
*.log.*
*.bak
*~
settings_local.py
/build/
/static_collected/*
/static/uploads/*
/static/theme_files/*
/static/picture/*
pip-log.txt
*.tmproj
*.dot
*.db
*.sublime-project
*.sublime-workspace
/docs/_*
The issue: sometimes, but not every time, Git deletes the static
directory of a repo. We're not sure what triggers it, but it appears to happen when either merging between branches or sometimes even just checking out branches. It does this without asking, and eats tracked files.
The background:
- I have a (private) project which has a few branches, 'release', 'develop', multiple feature lines.
- There are two of us (me and @stevejalim) working on the repo. This problem happens to both of us.
- I am using purely the command line for my git commands; Steve is using a mixture of the command line and Git Tower.
- It's a Django project with a
static
directory. We may havegit rm
ed thestatic
directory at some point in the past, or put it in.gitignore
, but not recently. And the head of our develop branch doesn't havestatic
in.gitignore
and has files instatic
tracked. - This happens so infrequently that we're not sure if it's something we're doing, or an intermittent problem, a bug with Git, or a corrupted tree
- It might happen only when merging another branch back into
develop
. But branches are always branched fromdevelop
and back intodevelop
. But we're not sure. We are using git-flow, but the issue happens when using non-git-flow commands, too.
As examples of when this can strike:
1) Steve had a develop branch that was clean (no changes to commit or stage) and stable. He cut a new release with
git flow release start|finish
and in the process (possibly the back-merge from master to develop), the entire /static/ tree got deleted.2) Steve repaired the delete by discarding the changes (to essentially undelete the file). But then, Steve simply switched from master back to develop and the /static/ dir got zapped again (this was with Git Tower)
3) Sometimes just merging from a feature branch to develop as an interim merge can trigger it. It does seem to happen most often when cutting a new release, though
Could it be related to how we repair the zapping of the /static/ dir? What is the best way to bulk-undelete things that have been deleted? Neither discarding local changes or a hard reset to HEAD seems to cure things. Might a rebase help us?
UPDATE We've just experienced this again simply with a git add .
- no changing branches, no merging. Does that help diagnosis at all?
Here is the content of Steve's .git/config:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = [email protected]:foobarbazbam/bar.git
[branch "master"]
remote = origin
merge = refs/heads/master
[gitflow "branch"]
master = master
develop = develop
[gitflow "prefix"]
feature = feature/
release = release/
hotfix = hotfix/
support = support/
versiontag =
[difftool "tower"]
cmd = \"/Applications/Tower.app/Contents/Resources/CompareScripts/kaleidoscope.sh\" \"$LOCAL\" \"$REMOTE\"
Here is the content of .gitignore
:
.DS_Store
*.pyc
*.log
*.log.*
*.bak
*~
settings_local.py
/build/
/static_collected/*
/static/uploads/*
/static/theme_files/*
/static/picture/*
pip-log.txt
*.tmproj
*.dot
*.db
*.sublime-project
*.sublime-workspace
/docs/_*
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,女士们先生们,我要公开道歉。 Git 不应该受到指责。我将把这个问题留在这里,作为对其他可能遇到同样问题的人的教训。
我们使用 django-storages 后端(一个“插件”,使 Django 能够透明地在 Amazon S3 上存储文件)。它有一个名为
HashPathStorageTest
的测试。此测试的拆卸会删除设置为./static
的settings.MEDIA_ROOT
。在我看来,这是错误的。它没有业务一揽子删除不是它创建的文件。在签入之前,我们像好公民一样运行测试。大多数时候,我们只对代码运行测试,但偶尔我们也会对整个项目(包括第 3 方插件)运行测试。这产生了问题中的行为。因为我们同时运行 test 和 git 内容,所以很难确定哪个命令正在执行删除操作(并且删除的文件仅在我们运行 git status 时才显示)。
这样问题就解决了。再次对诽谤 Git 的好名声表示歉意!
Okay ladies and gents I have a public apology to make. Git was not to blame. I will leave this question here as a lesson to other people who may pass the same way.
We were using the django-storages backend (a 'plugin' to enable Django to store files on Amazon S3 transparently). This has a test called
HashPathStorageTest
. The tear-down this test deletessettings.MEDIA_ROOT
, which was set to./static
. This is faulty, in my opinion. It has no business blanket-deleting files that it didn't create.We were running our tests, like good citizens, before checking in. Most of the time we ran only tests for our code, but occasionally we ran tests for the whole project (including 3rd party plugins). This was producing the behaviour in the question. Because we ran test and git things together, it wasn't easy to pin down which command was doing the deleting (and the deleted files only showed up when we ran
git status
).So problem solved. Again, sorry for casting aspersions on the good name of Git!
这似乎是 git 决定合并到一个分支,该分支 A) 已删除文件夹 B) 它认为比您要合并到的分支更新。是否可能存在一台具有美国日期类型和欧洲日期类型的机器?或者您的任何测试是否涉及重置机器日期时间?
我会
a) 检查您的开发中包含的所有机器的区域。
b) 在您的开发中选择一个固定点,复制文件并创建一个新的存储库,然后从那里开始。
This would appear to be git deciding to merge to a branch which A) has the folder deleted B) it thinks is more recent than the branch you are merging to. Might there be a machine which has american date type and one which has european date type? Or does any of your testing involve resetting machine date time?
I would
a) check the regions of all machines included in your developement.
b) choose a fixed point in your development, copy the files out and create a new reprository and go from there.
好吧,这就发生了 - 我将其添加为一个单独的答案,因为它太愚蠢了。我们有一个用于 SQL 脚本的存储库,而一位新开发人员意外地编辑了 .gitignore 以包含 *.sql - 不用说,更改已停止在该分支上传播 - 幸运的是,它在严重损失开发时间之前被捕获。然而,这可能会产生上述问题,这并非不可想象 - 那么你检查过你的 git 指令文件吗?如果该文件夹被忽略(并且 .gitignore 也在那里 - 即被忽略),它可能会神奇地消失并重新出现。
Ok so this just happened - I'm adding it a separate answer because its so silly. We have a repositiory for our SQL scripts and a new developer accidentally edited .gitignore to contain *.sql - needless to say changes stopped being propagated on that branch - and fortunately it was caught prior to any signifficant loss of development time. However its not inconcievable that this could produce the issues above - so have you checked your git directive files? If the folder is ignored (and .gitignore is in there as well - i.e ignored) it could dissapear and reappear almost by magic.