#include "FoldTags.h"\r
#include "VisibleGraphNode.h"\r
\r
+// that the line from node downward have any visible copy targets?\r
+\r
+bool CFoldTags::CopyTargetsVisibile (const CVisibleGraphNode* node) const\r
+{\r
+ for (; node != NULL; node = node->GetNext())\r
+ if (node->GetFirstCopyTarget() != NULL)\r
+ return true;\r
+\r
+ return false;\r
+}\r
+\r
// construction\r
\r
CFoldTags::CFoldTags (CRevisionGraphOptionList& list)\r
\r
void CFoldTags::Apply (CVisibleGraph* graph, CVisibleGraphNode* node)\r
{\r
- // we won't fold this node, if there are modifications on this\r
- // or any of its sub-branches.\r
- // Also, we will not remove tags that get copied to non-tags.\r
+ // We will not remove tags that get copied to non-tags\r
+ // that have not yet been removed from the graph.\r
\r
DWORD forbidden = CNodeClassification::COPIES_TO_TRUNK \r
| CNodeClassification::COPIES_TO_BRANCH \r
| CNodeClassification::COPIES_TO_OTHER;\r
\r
+ CNodeClassification classification = node->GetClassification();\r
+ bool isTag = classification.Matches (CNodeClassification::IS_TAG, 0);\r
+ bool isFinalTag = classification.Matches (CNodeClassification::IS_TAG, forbidden);\r
+\r
// fold tags at the point of their creation\r
\r
- if (node->GetClassification().Matches (CNodeClassification::IS_TAG, forbidden))\r
+ if (isTag)\r
+ {\r
+ // this is a node on some tag but maybe not the creation point\r
+ // (e.g. if we don't want to fold a tag and that tag gets\r
+ // modified in several revisions)\r
+\r
if ( (node->GetCopySource() != NULL)\r
- || node->GetClassification().Is (CNodeClassification::IS_RENAMED))\r
+ || ( (node->GetPrevious() != NULL)\r
+ && classification.Is (CNodeClassification::IS_RENAMED)))\r
{\r
- node->FoldTag (graph);\r
+ // this is the point where the tag got created / renamed\r
+ // (CopyTargetsVisibile can be expensive -> don't do it\r
+ // in the first "if" condition 4 lines above)\r
+\r
+ if (isFinalTag || !CopyTargetsVisibile (node))\r
+ {\r
+ // it does not copy to branch etc.\r
+ // (if it copies to a tag, that one will be folded first\r
+ // and we will fold this one only in the next iteration)\r
+\r
+ node->FoldTag (graph);\r
+ }\r
}\r
+ }\r
}\r