This is a git question concerning our C# Xamarin project.
We have a couple files in an Assets folder that are copied in there by a pre-build event command. The files are not used directly by the compiler but if they are missing our CI server will fail the build. The versions of them that are on all the dev machines are probably different so whenever we build on our machines the files get copied in and git shows that they are changed
It's annoying because changes to these files really don't matter so we never need to commit them. I want to ignore changes to these files but not remove them from the repo. If they are removed as mentioned above CI will fail. If I straight up "remove and stop tracking" them they will be deleted from the CI server when it pulls.
From other stack overflow questions I have tried both of these:
git update-index --assume-unchanged [path]
git update-index --skip-worktree [path]
Both succeed in hiding the file changes but both present the following problem. When I try to switch branches it tells me I must discard unstaged changes before switching and lists those files. I then type:
git reset -- .
git checkout .
Both fail to discard the changes to the files until I reverse the update-index commands, only then can I discard the changes and be allowed to switch branches.
Is there a solution to this? Are we doing something outside the box or just plain wrong?
This is a very common problem.
Sometimes it's the well known custom.js, custom.min.js, custom.css, custom.min.css, and the likes. Other times it's another kind of "source files" that somehow needs to be "there" in order for software to work, but we dont really care about what's in them.
Sounds familiar? It's called compiled files. Now I know they are not actually compiled files - they are source files. But for all intents and puposes these files are pretty much the same as compiled files. They are not really anything you care about, and would rather the computer just figured out how to maintain them.
Why treat them any different, than actual compiled files? You mention a pre-build event command makes these files every time you build. That practically makes them part of the build process.
The solution is rather straightforward. On the CI server include the pre-build event that generates the files, before the actual compiling, and add the files to the .gitignore file.
Related
I have a new application i would like to deploy to a Managed Server I have recently signed up for. I would like to know what would be the best way to deploy to it. In my experience I have seen that many of the asp.net applications just push dlls to the server. How is this achieved?.
I have Tortoise SVN as my subversioning system. I have a repository on another server and usually i commit my changes and then update my release folder in the managed server but this has all the .aspx, solution and other files I belive are not needed. How can I do my set up so that I only push the dlls and when updating that only dlls are updated?.
I am not too clear on this and would like an explanation and best practices given this scenario.
I have faced similar questions before and follow the below steps every time I move the compiled files for incremental fixes in my application.
Maintain two separate copies of the solution files - Local Application and Production application
//This is very important because once you go to production environment. One copy for your local working and other copy only for deploying in the live server. This copy should be up to date with your live server copy.
Make the changes to files and compile and test the application in your local application folder/solution. Now commit only the files that you edited. SVN will take care of this. It will show you a possible "red mark" for the files which differ from the updates present in the repository. In this way you can track the pages which were modified.
Now open open your production solution folder and update the folder. This will update the files in production application folder.
Now compile and test the changes done. Verify if its issue is fixed or the changes are reflected same as the Local application copy. Now build the application and publish to a folder.
To know the modified files:
DLLs:
Go to the bin location of the folder and "order by" modified date. These are the dlls which are to be copied and replaced with in your life server.
ASPX/ASCX
a) Open SVN of production application folder. Right click and click show log. This will show all the files modified/updated with date. Select the ones last updated and note down the location.
b) Now navigate to the location in your published folder and select those files "ordered by" descending/ascending modified date of the files. Replace those files alone to your LIVE server.
Note: This is certainly not the best possible solution, but one of the general practices followed throughout the industry. There are few other plugins which can track changes and publish the relevant files to your published folder. But again ,this is applicable only if you have the source codes and application files in the same machine as of the one you are hosting the application from. Let me know if you have any question in this.
You can just use visual studio web deploy, it will automagically figure out what needs to be updated and only pushes what is necessary unless you ask it otherwise.
I'm tidying my projects. And I found the way to remove the object folder with adding:
%TEMP%
In my projects. But I want somehow to make this global setting or to auto delete my obj dirs after a build. Is there a way to do that?
I personally like having a specific Output folder in my project where I put all the compiled files.
I have the following command line in the Post-build events.
copy "$(TargetPath)" "$(SolutionDir)\Output\$(TargetFileName)"
This will copy the compiled file to the Output directory inside the Solution. You would need to add this to all the projects in your solution.
If you have any dependencies that also needs to be copied you could add something like this as well.
copy "$(ProjectDir)Dependencies\Language.xml" "$(SolutionDir)\Output\Extensions\Language.xml"
[EDIT]
You can try the following to have the file copied first, and then once that is done delete the object folder.
copy "$(TargetPath)" "$(SolutionDir)\Output\$(TargetFileName)"
rd /s /q "$(ProjectDir)\obj"
[EDIT2] Updated with screenshots to illustrate. :)
This is how my object folder normally would look like after compiling the project.
This is how it looks after compiling it with the above command. As you can see the folder is re-created after the event by Visual Studio, but the folder is empty.
You might want to double check that you are running Visual Studio with elevated permissions. To do so, simply right click on the Visual Studio and choose "Run as Administrator".
Are you using source control?
This comment sounds like you don't:
While archiving, those are unneeded megabytes.
("Archiving" sounds a bit like copying the whole project folder regularly to something like backup_yyyymmdd)
If you're not using source control, you should definitively consider starting to use it.
Apart from the general advantages (like, having a change history with dates and comments...), it has an out-of-the-box solution for your problem with the obj folders:
Every good source control software out there supports ignoring certain files or folders which you can define (ignoring means: they can never be committed to the source repository, you don't even see them in the list of changed files, not even when they were changed).
For example, in Mercurial (which I use) the ignore settings are saved in a file named .hgignore in the main folder (Git has the same, it's just called .gitignore).
My default .hgignore file for all Visual Studio projects looks like this:
syntax: glob
bin
obj
*.suo
*.user
The first line belongs to Mercurial's ignore syntax, the rest are the settings what to ignore.
You can see that the bin and obj folders are ignored...and they are ignored no matter in which subfolder they are!
So I don't have to care about where the obj folders actually are, and I don't have to delete them manually every time I build my solution. They are simply non-existent in my source control history.
Plus, I have a variation of Fuji's answer about putting everything in one single output folder:
I like to do this as well, but I prefer changing the output folders in Visual Studio's project settings instead of using post-build events.
The default output folders are:
bin\Debug\
bin\Release\
I change them to:
..\build\Debug\
..\build\Release\
This compiles everything into subfolders of a build folder which is at the same level like the .sln file (which means: all projects in the solution directly compile into the same folder).
It also reduces compile time because Visual Studio won't have to copy all the dependencies after compiling (because everything already is in the same folder).
(I do it mainly because of the compile time, because I ignore the bin and obj folders anyway in Mercurial as described above, so I don't care where they actually are)
I have a quick question regarding debug and release in VS 2008.
I have an app i've been working on - its not yet complete but the bulk of the functionality is there. So basically i'm trying to give a copy of it now to the person helping with documentation - just so they can have a play and get the feel for what i've made.
Now the question is how to provide it to them. I was told to just copy the .exe out of the debug/bin folder and put that onto USB. But when testing, if I run this .exe anywhere else (outside of this folder) it crashes. I've now worked out why this is:
var path = ConfigurationManager.AppSettings["PathToUse"];
var files = Directory.GetFiles(path);
throws a null reference, so that App.config file is not being used. If I copy that file in with the .exe it works again.
So actually my question is regarding the best way to manage this situation. What is the best way to provide a working copy to people, and, is there a reference on preparing apps for release - so everything is packaged together and installed in a clean structured folder heirarchy?
If you want to be safe grab everything in the debug/bin folder. If you use the drop down in VS to change to release and then compile the project, there will be fewer files in the release/bin folder because many debug related files are not included.
If there are third party DLLs you are referencing, like if you downloaded log4net or something like that, then you can simply put them in the same folder as the exe. This is called side-by-side deployment, and in my opinion is the simplest and easiest to test.
You can search for XCOPY deployment to learn more about what you are trying to do.
You can take another step of compressing the bin folder into an archive like a zip file to make it easy for the user to extract them, or you could use a tool like WIX or NSIS to create an installer to extract and copy the files.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Which files in a Visual C# Studio project don’t need to be versioned?
when creating a repository, what do you include in the repository, should folders like Resharper, Debug and Bin folder be included? if not, is it possible to exclude files/folders from the unstaged changes check?
In order to ignore some files/directories, you have to create a .gitignore file ( http://kernel.osuosl.org/pub/software/scm/git/docs/v1.6.0.6/gitignore.html )
Depends on your requirements.
We mostly use C++ & SVN, but the idea should be the same for C# & git. We usually don't include debug/release & bin folders and .suo/.user files. We only include source/header files, resource files, data files and projects/solutions.
These are enough (as far as i can remember) for the others to checkout the project & compile themselves.
If you want others to be able to checkout the executables, you should add your bin folder too. But this causes a lot of conflicts between developers if they commit their bin folders because everyone is working on something else hence the contents of bin frequently changes.
As the other answers say you do not want to include bin folders, temp files etc.
The rule of thumb I use is to try to only check in code that is edited by humans, and everything else should be generated when you build the code. Obviously binaries get built for you but also things like autogenerated code should be created at build time. This isn't always practical, sometimes it is a lot easier to check in, say, a proxy to a web service to save having to build it everytime you recompile. You have to make compromises sometimes.
You should also avoid checking in any kind of local settings files generated by VS (e.g. .suo files). But DO check in project wide settings such as custom dictionaries and the like.
whatever can be generated/compiled out from you source code, don't source control it.
For some reason, we have a script that creates batch files to XCOPY our compiled assemblies, config files, and various other files to a network share for our beta testers. We do have an installer, but some don't have the permissions required to run the installer, or they're running over Citrix.
If you vomited all over your desk at the mentions of XCOPY and Citrix, use it as an excuse to go home early. You're welcome.
The code currently has hundreds of lines like:
CreateScripts(basePath, "Client", outputDir, FileType.EXE | FileType.DLL | FileType.XML | FileType.CONFIG);
It used to be worse, with 20 int parameters (one per file type) representing whether or not to copy that file type to the output directory.
These hundreds of lines create upload/download batch files with thousands of XCOPY lines. In our setup projects, we can reference things like "Primary output from Client" and "Content Files from Client". I'd love to be able to do that programmatically from a non-setup project, but I'm at a loss.
Obviously MS does it, either using an API or by parsing the .csproj files. How would I go about doing this? I'm just looking for a way to get a list of files for any of the setup categories, i.e.:
Primary Output
Localized Resources
Content Files
Documentation Files
EDIT:
I have a setup project like Hath suggested, and it's halfway to what I'm looking for. The only problem keeping that from being a perfect solution is that multiple projects depend on the same assemblies being in their own folder, and the setup will only copy the file once.
Example:
Projects Admin, Client, and Server all rely on ExceptionHandler.dll, and Admin and Client both rely on Util.dll, while Server does not. This is what I'm looking for:
Admin
Admin.exe
Admin.exe.config
ExceptionHandler.dll
Util.dll
Client
Client.exe
Client.exe.config
ExceptionHandler.dll
Util.dll
Server
Server.exe
Server.exe.config
ExceptionHandler.dll
Since the referenced assemblies are all the same, what I get is this:
Admin
Admin.exe
Admin.exe.config
ExceptionHandler.dll
Util.dll
Client
Client.exe
Client.exe.config
Server
Server.exe
Server.exe.config
This causes a FileNotFoundException when either Client or Server can't find one of the two DLLs it's expecting.
Is there a setup property I'm missing to make it always copy the output, even if it's duplicated elsewhere in another project's output?
EDIT AGAIN: All referenced DLLs are set to "Copy Local", and always have been. I found a decent article on using NAnt and XSLT to grab the list of files, so that may be a possible solution as well, as neouser99 suggested.
ACCEPTED SOLUTION: I'm pretty much back where I started. All .exe and .dll outputs are put into a "bin" directory in the setup project, loosely packed. The other per-application folders contain shortcuts to the executable in that directory.
The difference now is, I'm going to add a custom action to the installer to use reflection, enumerate the dependencies for each executable output, and copy the .exe and .dll files to the separate directories. Bit of a pain, as I just assumed there was a way to programmatically detect what files would be included via some setup library.
why not use another setup project and just set the 'Package files' setting to As Loose uncompressed files (setup project->properties)? then share the folder.. or something.
edit:
I see, you have 3 folders for your outputs. but the setup project only detects the ExceptionHandler.dll and Util.dll once, so it will just pick the first folder and put it in there.
You could do a setup project for each project - bit annoying maybe..
You could manually add in the dll's to the projects that are missing the assembly's
either by adding in the File by 'add file' or 'add assembly' or 'add project output' if you have those projects in the same solution.. (I doubt that's the case though).
or just dump all of them into one output directory...
Although it's designed as a build tool, you might find NAnt to be extremely useful in what you are talking about. The tasks (build, copy, move, delete, etc.) that you can define allow for very fine-grained file lookups, up to general, full folders. If you also incorporate NAnt into your build process, I think you could find that it helps out in more ways then one.
Another approach that has worked for me in the past is to add the shared resource (Assembly, DLL or project) as a reference to each of the Admin, Server and Client projects. Then open the properties panel for the referenced item in each project and set "Copy Local" to true.
Now when you build the projects, each will have its own instance of the Assembly copied into its output folder.
This should also cause the shared components added in this manner to be replicated in each of the output folders in the setup package.
A completely different approach could be to set them up as symbolic links on the network share. A symbolic link is basically a short-cut where the file-system hides the fact that it is a short-cut, so all other applications actually believes that the file has been copied (http://en.wikipedia.org/wiki/NTFS_symbolic_link).
One advantage of this approach is that the file is updated immediately as the file changes and not only when you build your projects. So when you for instance save one of the config-files with a text-editor the update is applied immediately.
The following MSBuild script part can build your SLN file (you can replace it with .csproj) and will report a list of all projects that were build (Dlls, EXEs).
<MSBuild Projects="MySolution.sln" Targets="Clean; Rebuild" Properties="Configuration=$(BuildMode);">
<Output TaskParameter="TargetOutputs"
ItemName="AssembliesBuilt" />
</MSBuild>
Now, this doesn't really solve your problem, but it gets you a list of everything that was build. You also have copylocal, so you could probably just take AssembiesBuild and copy all DLL and .CONFIG files from there.
Example:
AssembliesBuild = c:\myproj\something1\build.dll
you'd go to c:\myproj\something1\ and simply search for all *.dll and *.config files and include them. You can do this pretty easily with MSBuild or powershell, if you have it installed. To output a XCOPY script from MSBuild, I think you'll need MSBuild contrib projct installed.