简体   繁体   English

Git push 不会删除已删除的文件

[英]Git push does not remove deleted files

I'm no GIT expert and forgive me if this is the wrong forum for this, but I'm using GIT to deploy code to my production server which works fine, I simply do git push production master where production points to my WPEngine server and it will obviously be a copy of the master branch.我不是 GIT 专家,如果这是一个错误的论坛,请原谅我,但我正在使用 GIT 将代码部署到我的生产服务器,这工作正常,我只是执行git push production master ,其中production指向我的 WPEngine 服务器和它显然是 master 分支的副本。

The problem with this approach is that we need to include everything that's needed for prod to work in the repo.这种方法的问题在于,我们需要在 repo 中包含 prod 工作所需的一切。 This includes stuff like dist/ (generated CSS/JS etc) as well as vendor/ (composer installed third party libraries) which is obviously not ideal.这包括dist/ (生成的 CSS/JS 等)以及vendor/ (作曲家安装的第三方库)之类的东西,这显然不理想。

To combat this I had a (in my mind) simple idea of separate .gitignore s.为了解决这个问题,我有一个(在我看来)单独的.gitignore的简单想法。 One for origin and one for production .一为origin ,一为production The way I set this up is that I have my normal .gitignore and then I also have a .prodignore .我设置的方式是我有我的正常.gitignore然后我还有一个.prodignore

I then wrote a simple shell script ( deploy.sh ) that does the following:然后我编写了一个简单的 shell 脚本 ( deploy.sh ),它执行以下操作:

  1. Go through every .prodignore file and rename it .gitignore :浏览每个.prodignore文件并将其重命名为.gitignore

     for prodignore in $(find . -name '.prodignore'); do gitignore=$(echo $prodignore | sed 's/prodignore/gitignore/') mv $prodignore $gitignore done
  2. Remove all files from GIT but keep them on disk: git rm -r --cached --quiet .从 GIT 中删除所有文件,但将它们保留在磁盘上: git rm -r --cached --quiet . (this takes care of removing files that are now in the new .gitignore - like src/ ) (这负责删除现在在新.gitignore ——比如src/

  3. Now re-add all files with the new .gitignore : git add --all (this takes care of adding files that were previously in .gitignore - like dist/ )现在使用新的.gitignore重新添加所有文件: git add --all (这负责添加以前在.gitignore文件 - 如dist/

  4. Commit and push to the production remote: git commit --quiet -m 'Sleek Deploy' && git push --quiet --force production master提交并推送到production远程: git commit --quiet -m 'Sleek Deploy' && git push --quiet --force production master

  5. Finally go back one commit so we undo all we just did: git reset HEAD~ && git reset --hard HEAD最后返回一次提交,以便我们撤消刚才所做的一切: git reset HEAD~ && git reset --hard HEAD

This all works mostly fine too.这一切也都很好。 The correct new files are pushed to production and my local repo as well as origin still look good and have no weird histories as far as I can tell.正确的新文件被推送到production ,我的本地存储库和origin看起来仍然不错,据我所知没有奇怪的历史记录。

What does not work however - which I only recently noticed - is that if I delete a file from my local machine, push the delete to origin and then deploy to production using the above steps the deleted file will not be removed.什么工作,但是-这是我最近才发现-是,如果我删除我的本地机器的文件时,推到删除origin ,然后部署到production使用上述步骤删除的文件不会被删除。

Why is this?为什么是这样? Is there something I can do to make sure it gets deleted?我能做些什么来确保它被删除吗? Is my entire approach to this flawed?我对此的整个方法有缺陷吗? Imo having separate .gitignore files for separate remotes is such a simple solution to this problem, but perhaps I've bitten off more than I can chew. Imo 为单独的遥控器提供单独的.gitignore文件是解决这个问题的一个简单的解决方案,但也许我已经咬掉了我无法咀嚼的东西。

It's worth noting that If I don't --force push in step 4 the remote tells me we are out of sync (which makes sense seeing as it has a commit that doesn't actually exist anywhere else - right?)值得注意的是,如果我不--force push 在第 4 步,遥控器会告诉我我们不同步(这是有道理的,因为它有一个实际上并不存在于其他任何地方的提交 - 对吧?)

Edit: A little more info:编辑:更多信息:

  • When I did git push production master like normal, and production was a copy of master , I never had this issue当我像往常一样执行git push production master并且productionmaster的副本时,我从来没有遇到过这个问题

  • This does not have to do with what's in .gitignore .这与.gitignore无关。 The files I'm talking about have never been in either .gitignore or .prodignore .我正在谈论的文件从未出现在.gitignore.prodignore I only mentioned them for background information and why I need to push a commit to production that is never pushed to origin.我提到它们只是为了提供背景信息以及为什么我需要将从未推送到源的提交提交到生产中。 This just happens if I:这只会发生在我:

    1. Create any random file, say "test.txt"创建任何随机文件,比如“test.txt”
    2. Push the file to origin将文件推送到origin
    3. Push the file to production using the above steps使用上述步骤将文件推送到production
    4. Delete the file删除文件
    5. Push the deletion to origin (the file is no longer in the repo)将删除推送到origin (文件不再在 repo 中)
    6. Push the deletion to production using the above steps (the file is still on the production server for some reason)使用上述步骤将删除推送到production (由于某种原因,该文件仍在production服务器上)

If I never push the file to production to begin with, just to origin and then remove it, it will never end up on production .如果我从不将文件推送到production开始,只是将其推送到origin然后将其删除,那么它永远不会在production结束。

production is as far as I am aware a bare repo if that helps.据我所知,如果有帮助, production是一个裸回购。

if the deleted file is in the new .gitignore , it'll definitely not be deleted as your commit wouldn't look at that file at all.如果删除的文件在新的.gitignore ,它肯定不会被删除,因为您的提交根本不会查看该文件。

If it's and you still want it to be deleted, you'll have to push to production using your original .gitignore files, then continue with you're 'Sleek Deploy'如果它是,并且您仍然希望将其删除,则必须使用原始.gitignore文件推送到生产环境,然后继续“Sleek Deploy”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM