Bug 226457 - Sharing cdt-project files in repository always causes conflicts
Summary: Sharing cdt-project files in repository always causes conflicts
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-core (show other bugs)
Version: 4.0.3   Edit
Hardware: PC Windows XP
: P3 critical with 16 votes (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
: 217055 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-04-10 04:48 EDT by Oliver Mueller CLA
Modified: 2020-09-04 15:23 EDT (History)
19 users (show)

See Also:


Attachments
Patch to persist second level storageModules in separate files (26.95 KB, patch)
2008-05-29 11:26 EDT, James Blackburn CLA
no flags Details | Diff
Regenerated - disable delete of external files for the moment (27.01 KB, patch)
2008-06-04 10:48 EDT, James Blackburn CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Mueller CLA 2008-04-10 04:48:13 EDT
Build ID: M20080221-1800

Steps To Reproduce:
1.change cdt configuration in workspace (from debug -> release)
2.you get outgoing chances in cdt-project files (.cproject, .project)
3.another developer does the same thing concurrently
4.conflicts...conflicts...conflicts. not acceptable for a setting in which you try to manage 40 CDT (sub-)projects (all but one are libraries) and share them among 15 developers in 5 different countries!!!


More information:
we use cdt to manage our c++ development of our product. we recently switched from CDT 3.1.2 to CDT 4.0.2 and converted all projects in our workspace. all projects are managed c++ projects and all are under source control using cvs.
so we used to keep all our .cdtbuild and .cdtproject files under version control as well. once the projects were set up correctly, the content of those files did not change even when switching to a different cdt-project configuration (e.g. from "debug" to "release")
with CDT 4 those files disappeared and we got the new .cproject and also an apparently different form of .project files.
now i have the problem that i get changes in those files all the time.
that is a problem since now we tend to get conflicting changes in the cvs.
i almost feel that this is a bug but i'm not sure if i use those project specific settings correctly. at least i'm pretty sure it is not a good idea to store the current configuration in those files.
Comment 1 Oliver Mueller CLA 2008-05-21 04:07:32 EDT
the information stored in the .cproject files seems sometimes to be somewhat superfluous. i regularly get conflicting versions where one version is 5 times as long (in locs) than the other. (in my case 1200 vs. 5900 lines). most of this is some kind of "scannerConfigBuildInfo".
is there a strategy that determines what project related information has to go where? if there is how can i find out? i would try to go in and fix this but it seems to involve some design decisions by the cdt guys...
Comment 2 James Blackburn CLA 2008-05-21 05:24:23 EDT
*** Bug 217055 has been marked as a duplicate of this bug. ***
Comment 3 James Blackburn CLA 2008-05-29 11:26:55 EDT
Created attachment 102659 [details]
Patch to persist second level storageModules in separate files

This small patch modifies the Serialize / createStorage mechanism in CProjectDescriptionManager to allow second level storageModule Elements (i.e. the ones under the cconfiguration elements) to be persisted to separate files.  In their place, in the original tree, is an attribute with pointer to the filename, for deserializing.

The project loading will cdt 4.0.x .cproject files, and serialize them to version 5.0.0. 

The in memory data structure is the same as before (see comment at the end).  And all the cdt.core tests continue to pass.

The files are stored in a .csettings directory in the root of the project with names: configurationID_storageModuleId e.g.:
com.broadcom.cdt.build.target.fpexe.debug.625434707_cdtBuildSystem

This means that all the build configuration settings are stored in a separate file for each configuration, and the build settings file is distinct to scanner config settings...

Possible improvements (what's missing):
- Even finer grained splitting?
   - Modify the XmlStorageElement, adding the external c element attribute, so the tree splitting is not hard coded to the storageModule children of cconfiguration
- Warn users that they're .cproject file will not be openable in previous version of Eclipse
- Add a preference allowing users to turn on and off the splitting mechanism (deserialization is the same...) -- I suspect it would be good to find a sensible splitting setting rather than clutter preferences further.

Any feedback would be greatly appreciated!

[Comment: I originally tried for a slightly more intrusive change.  I though it would be a good idea to allow the XmlStorageElement children exist in a separate file from the parents, but this eventually fell down due to ICDescriptor.getProjectData which returns an XML Element(!)...]
Comment 4 Oliver Mueller CLA 2008-06-04 10:05:29 EDT
james,
i think it is a very good idea to split up the configuration data into separate files. if i mess around with my unit test configuration, i don't want to touch the information of any other configuration.
we are currently stuck with cdt 4 but i will try out the stuff you implemented asap.
did you also change the serialization of the individual configuration settings? i'm not quite sure but from what i recall the scanner config settings where not the only settings that caused automatic changes in the .cproject file...
still another issue is that buildLocation changes when you select a different project configuration (and that is now stored in the .project file)
Comment 5 James Blackburn CLA 2008-06-04 10:48:11 EDT
Created attachment 103567 [details]
Regenerated - disable delete of external files for the moment

(In reply to comment #4)
> james,
> i think it is a very good idea to split up the configuration data into separate
> files. if i mess around with my unit test configuration, i don't want to touch
> the information of any other configuration.
> we are currently stuck with cdt 4 but i will try out the stuff you implemented
> asap.

So the patch will cause older .cproject config files to be split if a change is made that would cause the configuration file to be re-serialized. It also isn't terribly difficult to piece it back together again -- though definitely worth making sure you have backups of your project just in case :).

> did you also change the serialization of the individual configuration settings?
> i'm not quite sure but from what i recall the scanner config settings where not
> the only settings that caused automatic changes in the .cproject file...
> still another issue is that buildLocation changes when you select a different
> project configuration (and that is now stored in the .project file)

I haven't altered what's put into the .project file.  The big aim for us is to be able to version control the configuration setting needed to rebuild the product.  Deltas on files that don't serve this need -- i.e. files users will check out once at the beginning of time, never likely to be recommited -- are much less important in my opinion.  

Currently each configuration is split by stroageModule element, so my .csettings directory for a stdmake project looks like:
bash:jamesb:xl-cbga-20:5695> ls ../../../../.csettings/
com.broadcom.cdt.build.toolchain.gnu.base.1650727635_cdtBuildSystem
com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.core.externalSettings
com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.core.settings
com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.make.core.buildtargets
com.broadcom.cdt.build.toolchain.gnu.base.1650727635_scannerConfiguration

with the .cproject being much cleaner:
<?xml version="1.0" encoding="UTF-8"?>
<?fileVersion 5.0.0?>
<cproject>
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.broadcom.cdt.build.toolchain.gnu.base.1650727635">
<storageModule externalCElementFile="com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.core.settings" moduleId="org.eclipse.cdt.core.settings"/>
<storageModule externalCElementFile="com.broadcom.cdt.build.toolchain.gnu.base.1650727635_cdtBuildSystem" version="4.0.0"/>
<storageModule externalCElementFile="com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.core.externalSettings"/>
<storageModule externalCElementFile="com.broadcom.cdt.build.toolchain.gnu.base.1650727635_scannerConfiguration"/>
<storageModule externalCElementFile="com.broadcom.cdt.build.toolchain.gnu.base.1650727635_org.eclipse.cdt.make.core.buildtargets"/>
</cconfiguration>
...

It's probably worth improving this such that ICStorageElement's have a flag of fileName field indicating whether they should be stored externally; I'll probably take a look at this at some point soon.

Just regenerated the patch -- it's against CDT4_0_3 (possibly requiring Java 5). The difference here is that I no longer purge storageModule files when removeStorage is called (this prevents a possible data loss bug, when removing configurations and pressing cancel on the dialog...).

Let me know if you have any problems with the current patch.
Comment 6 James Blackburn CLA 2008-11-04 11:15:59 EST
I've create some patches to allow ISVs to plug-in custom project description storages (bug252966).  As well as supporting the built-in .cproject file, it provides a storage type which serializes to separate files as the patch on this bug did.
Comment 7 James Blackburn CLA 2009-01-08 19:10:29 EST
The patches here have morphed into a large contribution on bug 252966.  This provides for pluggable project description storages.  The separation of the configuration's storage modules does reduce the number of superfluous changes, however the attribute / element sort in XML is unstable which means there are some bogus changes in the diffs.

An idea we had for addressing this was dumping the build configuration to a simple human readable text-based form (we currently have an action to do this in our product). This text file could be used as the basis of the diff, and developers can see at a glance what effect checking in the large xml blob will have.  Does anyone have any opinions / ideas on this?

Making this better is still high on my list of Todos.  Version control of the project model is currently _too_ hard.
Comment 8 Anton Leherbauer CLA 2009-01-09 04:36:02 EST
(In reply to comment #7)
> Does anyone have any opinions / ideas on this?
> Making this better is still high on my list of Todos.  Version control of the
> project model is currently _too_ hard.

What about implementing a specialized compare viewer for the .cproject file. Maybe there is already one for XML trees which does a better job than the default text compare.
Comment 9 James Blackburn CLA 2009-01-09 04:45:07 EST
(In reply to comment #8)
> (In reply to comment #7)
> > Does anyone have any opinions / ideas on this?
> > Making this better is still high on my list of Todos.  Version control of the
> > project model is currently _too_ hard.
> 
> What about implementing a specialized compare viewer for the .cproject file.
> Maybe there is already one for XML trees which does a better job than the
> default text compare.


Yes, that's a good idea.  There's an XML compare editor in the eclipse examples (org.eclipse.compare.examples.xml) which apparently does unordered compare which might do the trick.  Will investigate.

Comment 10 Marc-André Laperle CLA 2010-03-07 14:32:20 EST
Any chance to have this fixed in 7.0? It seems like one of the bigger bugs and there has been no discussion in more than a year. I would like to help but the .cproject file is pretty arcane to me.
Comment 11 James Blackburn CLA 2010-03-08 07:15:37 EST
(In reply to comment #10)
> Any chance to have this fixed in 7.0? It seems like one of the bigger bugs and
> there has been no discussion in more than a year. I would like to help but the
> .cproject file is pretty arcane to me.

I came to the conclusion that it would be pretty hard to use a generic XML tree based diff of the .cproject as:
  - Langugage settings are stored deep in the build system under tool option entries.
  - Tool-chain item IDs are not human readable, and you need to defer to the tool / option name 

As I wanted fine-grained control of the look of the configuration output, what I did instead is hook into the project model delta directly, dumping it to a human readable text file having removed a bunch of duplication (/pushing common settings up the tree, and presenting diff-style output for files / folders below the project). We then check this file in with the .{c}project so users can quickly see what changes were made to the configuration.  [Ideally we would generate this on the fly from the .{c}project files, but we don't yet...]

If this is generally useful, I could factor this out to a standalone plugin, as a start at a way to produce a human readable configuration dump.
Comment 12 Oliver Mueller CLA 2010-03-08 07:41:26 EST
(In reply to comment #11)

james...i think your approach goes into the right direction. having a human readable text file instead of this xml-mess.

but i think it might be tedious and error prone and not DRY to keep 2 representations of basically the same content.

would it be a lot of work to enhance your textual representation so it contains all information and we can get rid of the dumb xml file?

actually because of the .cproject file madness (and some other reasons) we currently peruse the idea of moving away from the built-in make-builder completely. but that's of course slightly of topic here...
Comment 13 Erik Ekman CLA 2010-03-08 07:47:39 EST
Is it possible to split these settings? Some are common, some should be local (at least as override).

In my project we are 5 or so users running CDT and we would like to share build configurations but the number of threads to use while compiling and some of the include paths needs to be individually.
Comment 14 James Blackburn CLA 2011-02-15 04:36:03 EST
I'm doing some exploratory work on this.
Comment 15 Judson CLA 2011-03-03 01:48:16 EST
I agree that this is a terrible problem.  My project has lots and lots of include files and libraries due to my use of GTK+, and I do not want to re-enter all of them every time I check out a copy of the project.  It would be nice if there were a simple project file that contained all this information and only changed if I changed something within a build configuration.  Also I hope to be able to read it (which is very important when trying to decide what to commit!)

I have used IAR Embedded Workbench in the past, and that program's simple use of XML configuration files performed this task almost effortlessly, except for a few mystery tags.  There is a project settings file, which contains the configurations, and a separate debug file, which had all the settings being used for debugging at the moment.  The rule has always been "don't commit the debug file!".
Comment 16 Baltasar Belyavsky CLA 2012-01-13 11:59:29 EST
This bugzilla has morphed into a full blown design discussion, which is good for the long term. But going back to the original reported problem - I was investigating some simpler solutions for it. I am tracking my work in bug 340219. 

I've attached two patches to bug 340219, both are very small - one addresses the unnecessary touching of the .project file and the other, of the .cproject file. Please have a look at them - I've added some quick explanation of my reasoning for each. I will also add a test-case to test the patches shortly.
Comment 17 Marc-André Laperle CLA 2013-07-13 22:49:44 EDT
I'm curious, is it still causing conflicts since bug 340219 has been resolved?
Comment 18 Palmer Eldritch CLA 2013-07-14 08:21:13 EDT
Now that you are at this please also have a look at https://bugs.eclipse.org/bugs/show_bug.cgi?id=395223 also please