{"thread":{"id":"29909","subject":"SVN Branch Description Format","startedAt":"2012-03-11T10:59:47Z","lastAt":"2012-03-31T01:27:59Z","messageCount":10,"participants":["Andrew Sayers","Steven Michalske","Jonathan Nieder","Jeff King","Ramkumar Ramachandra"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"186644","messageId":"4F5C85A3.4080806@pileofstuff.org","threadId":"29909","inReplyTo":null,"subject":"SVN Branch Description Format","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2012-03-11T10:59:47Z","receivedAt":"2012-03-11T10:59:47Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"(CCing everyone from the \"Approaches to SVN to Git conversion\" thread)\n\nA recent discussion of the remote helper for Subversion turned into a plan for\nseparating out revision->commit mapper projects.  Just as content import is\nsplit into three parts (svn-fe, fast-import protocol, git-fast-import), r2c\nmapping can be split into SVN export, protocol, and git import.  I've included\nan initial draft protocol below.\n\nMy approximate roadmap from here is to add test cases and a reference\nimplementation to the protocol, then create an SVN exporter from my existing\nproof-of-concept, then finally write a git importer.  My proof-of-concept work\nis at https://github.com/andrew-sayers/Proof-of-concept-History-Converter\n\nAll comments gladly welcomed, but I would particularly appreciate suggestions\nabout how to specify the format more clearly, example SVN use cases that can't\nbe readily expressed with the language as specified, and suggestions about\nwhether forward compatibility should be built in.\n\n\t- Andrew\n\n\nSVN Branch Description Format v0.1\n==================================\nAndrew Sayers <andrew-svn@pileofstuff.org>\n\nThis file specifies a simple format for describing how SVN revisions\napply to branches.  The goals of this format are to be a communication\nprotocol for programs operating on SVN history and to provide a common\nlanguage for developers discussing unusual SVN use cases.\n\nOverview\n--------\n\nThe SVN Branch Description Format (``BDF'') is a line-based ASCII\nformat, where each line specifies one action in the SVN history.  An\nSVN history file contains two sections: the first is the ``header''\nsection that provides information about the file as a whole, the\nsecond is the ``body'' section that provides information about things\nthat happened in specific revisions.\n\nAny line in a BDF file that begins with a hash or semicolon character,\nor that contains only whitespace (including empty lines) is considered\nto be a comment, and must be ignored.  Clients should use a leading\n'#' to create ordinary comments to be read by users, and a leading ';'\nfor commented-out actions the client wishes to suggest to a user.\nThis makes it easier for a user to accept/reject actions by\nsearch-and-replace.\n\nHere is an example file:\n\n    # the file must begin by specifying the revision of the format being used:\n    This is a version 0.1 SVN Branch Description file\n    Body:\n    In r1, create branch \"trunk\"\n    In r10, create branch \"branches/1.0\" from \"trunk\" r9\n    In r20, create tag \"tags/version_1\" from \"branches/1.0\" r19\n    In r20, deactivate \"tags/version_1\"\n    # User intervention is required to confirm this action:\n    ; In r25, merge \"trunk\" r24 into \"branches/1.0\"\n\nHeader section\n--------------\n\nThe header section begins with a version identifier, continues with\nany number of private actions, and ends with the header-body boundary\nmarker.\n\nAny unrecognised action in the header should be treated as a fatal\nerror.\n\nVersion identifier\n~~~~~~~~~~~~~~~~~~\n\nThe first action in this section must exactly match the following:\n\n    This is a version 0.1 SVN Branch Description file\n\nLater versions of the format will use a different identifier here.\nThis might be another number (e.g. ``version 3''), a non-numeric\nidentifier (e.g. ``experimental version''), a different format name\n(e.g. ``SVN-BDF file''), or anything else.  Clients should treat anything\nother than the exact string above as a fatal error.\n\nPrivate actions\n~~~~~~~~~~~~~~~\n\nPrivate actions begin with an open bracket and end with a close\nbracket.  For example:\n\n    (my-great-parser will write debugging information to \"debug.log\")\n\nThese actions are intended for internal use by clients using BDF as a\nstorage format.  Clients must begin any private action they create\nwith a client-specific identifier (`my-great-parser` in the above\nexample), and must ignore any private action that does not begin with\ntheir identifier.  These requirements are designed to ensure that\nclients do not use private actions to communicate with other clients -\nplease send such messages out-of-band (e.g. through arguments to a\ncommand-line program), or propose a revision to the format so that all\nclients can communicate using a standard language.\n\nHeader-body boundary marker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe last action in this section must exactly match the following:\n\n    Body:\n\nThis serves only to indicate that the header is finishing, and the\nbody beginning.  The remainder of the file must be treated as the body\nsection.\n\nBody section\n------------\n\nThe body section contains zero or more actions as described below.\nThe following components are widely used in these actions:\n\nRevision identifiers::\n  These strings begin with the letter `r`, followed by a number in the\n  range 1-9, then zero or more numbers in the range 0-9.  So `r1`,\n  `r10` and `r999` are valid revision identifiers, but `1`, `r01` and\n  `revision 999` are not.  Revision identifiers are indicated with\n  `<revision>` in the definition of an action.\n\nString identifiers::\n\n  These strings begin with a double quote, then contain zero or more\n  valid characters, then another double quote.  Valid characters\n  include a backslash followed by `\\`, `r`, `n`, or `\"`, or any\n  character other than backslash, carriage return, newline, or double\n  quote.  So `\"foo\"`, `\"foo\\\"\"` and `\"foo\\\\\"` are valid identifiers,\n  but `\"foo\\\"`, `\"foo\"\"` and `\"foo\\t\"` are not.  Clients must unescape\n  string identifiers by converting `\\\"`, `\\\\`, `\\r` and `\\n` to double\n  quote, backslash, carriage return and newline respectively.  String\n  identifiers are indicated with `<string>` in the definition of an\n  action.\n\nThese are the valid actions in the body section:\n\n    In <revision>, create branch <string>\n    In <revision>, create branch <string> as <string>\n    In <revision>, create branch <string> from <string> <revision>\n    In <revision>, create branch <string> as <string> from <string> <revision>\n\n    In <revision>, create tag <string>\n    In <revision>, create tag <string> as <string>\n    In <revision>, create tag <string> from <string> <revision>\n    In <revision>, create tag <string> as <string> from <string> <revision>\n\n    In <revision>, deactivate <string>\n    In <revision>, delete <string>\n\n    In <revision>, merge <string> up to <revision> into <string>\n    In <revision>, cherry-pick <string> <revision> into <string>\n    In <revision>, cherry-pick <string> <revision> to <revision> into <string>\n    In <revision>, revert <string> <revision> from <string>\n    In <revision>, revert <string> <revision> to <revision> from <string>\n\n    In <revision>, ignore <string>\n    In <revision>, amend <string>, keeping the old log message\n    In <revision>, amend <string>, keeping the new log message\n    In <revision>, amend <string>, keeping both log messages\n\nAll actions begin with `In <revision>,`.  This identifies the revision\nthe action applies to.  Each action must refer to a revision greater\nthan or equal to the previous action, except the first action which\nmust be greater than or equal to revision 1.  Clients should treat\nrevision numbers that are too low as fatal errors.  Clients may treat\nrevision numbers as errors if they are not present in the repository\n(i.e. higher than the maximum revision or not part of the\nsub-repository being examined)\n\nCreate actions\n~~~~~~~~~~~~~~\n\nThe `create branch` and `create tag` actions identify a branch or tag\nbeing created in the specified revision.  The first string identifier\nindicates the SVN directory name associated with the branch.  The `as\n<string>` identifier indicates the name the user intended for the\nbranch or tag (if unspecified, clients should assume the user intended\nthe branch to have the same name as the directory).  The `from\n<string> <revision>` identifiers indicate the directory associated\nwith a previously-named branch, and the revision number used as the\nparent for this branch or tag (if unspecified, clients should assume\nthe user intended this to be a trunk).  Here are some examples:\n\n    # Create a trunk branch named \"trunk\" from directory \"trunk\":\n    In r1, create branch \"trunk\"\n\n    # Create a branch named \"branches/foo\" from directory \"branches/foo\",\n    # whose parent is the directory \"trunk\" as it was in revision 5:\n    In r10, create branch \"branches/foo\" as \"foo\" from \"trunk\" r5\n\n    # Create a tag named \"1.0\" from directory \"tags/1.0\",\n    # whose parent is the directory \"branches/foo\" as it was in revision 15:\n    In r20, create tag \"tags/1.0\" as \"1.0\" from \"branches/foo\" r15\n\nClients should treat it as a fatal error if the `from` revision is\ngreater than the current revision, or if the `from` branch was not\nactive in the specified revision (i.e. it hadn't been created, had\nbeen deactivated or had been deleted).\n\nIf the `from` branch was active but not changed in the specified\nrevision, clients should behave as if the user specified the last\nrevision in which the branch was edited prior to the specified\nrevision.  If the `from` revision is equal to the current revision,\nclients should warn the user if the `from` branch was edited in that\nrevision.  These requirements make it significantly easier for users\nto manually edit a BDF file.\n\nClients should treat it as a fatal error if the name specified for a\nbranch or tag is currently in use.  A name is currently in use if it\nwas previously declared with one of the `create` actions, and has not\nyet been deleted with the `delete` action (the `deactivate` action\nmust not be treated as removing a branch name).  Clients that check\nfor names currently in use must treat branch and tag names to be in\ndifferent namespaces - in other words, it is legal to have a branch\nnamed `foo` at the same time as a tag named `foo`.\n\nDelete actions\n~~~~~~~~~~~~~~\n\nThe `deactivate` and `delete` actions identify a branch or tag that\nshould no longer be considered active.  The string identifier\nindicates the directory name associated with the branch.\n\nThe `deactivate` action indicates that a branch or tag is still of\nhistorical interest, but should no longer be updated when changes are\nmade.  For example, a tag might be deactivated after it is created, to\nindicate that the tag should be considered immutable even though\nchanges were accidentally made later on.\n\nThe `delete` action indicates that a branch or tag is no longer of any\ninterest, and can be ignored completely.  For example, a branch might\nbe deleted if it had been fully merged into another branch before the\ndirectory was removed.\n\nMerge actions\n~~~~~~~~~~~~~\n\nThe `merge`, `cherry-pick` and `revert` actions identify changes in\nthe relationship between two branches.  The first string identifier\nindicates the directory name for the action's source.  The last string\nidentifier indicates the directory name for the action's destination.\nThe revision identifier(s) indicates the revision(s) for the action's\nsource.\n\nThe `merge` action indicates that all revisions up to the specified\npoint have been applied from the source to the destination.  The\n`cherry-pick` and `revert` actions identify an inclusive set of\nrevisions that have been applied from the source to the destination.  The\n`merge` and `cherry-pick` actions indicate that revisions that\npreviously had not been merged now have been merged.  The `revert`\naction indicates that revisions which had previously been merged have\nno longer been merged.\n\nIf two revisions were specified, clients must treat it as a fatal\nerror if the second revision is less than or equal to the first.\n\nClients must treat it as a fatal error if the `from` branch was not\nactive in the specified revision.  If two revisions are specified,\nclients must treat it as a fatal error unless the `from` branch was\nactive in both revisions.\n\nFor the `merge` action, if the `from` branch was active but not\nchanged in the specified revision, clients must behave as if the user\nspecified the highest revision before the specified revision in which\nthe branch was changed.  If the `from` revision is equal to the\ncurrent revision, clients should warn the user if the from branch was\nchanged in that revision.\n\nFor the two-revision `revert` and `cherry-pick` actions, clients must\ntreat the second revision as in the previous paragraph.  If the branch\nwas not changed in the first revision, clients must behave as if the\nuser specified the lowest revision after the specified revision in\nwhich the branch was changed.\n\nFor all `revert` and `cherry-pick` actions, clients must treat it as a\nfatal error if no revisions in the specified range changed the branch.\n\nNote: the above requirements for altering revision numbers make it\nsignificantly easier for users to manually edit an SVN Branch\nDescription file.\n\nIf a `merge` action specifies a revision less than or equal to any\nearlier merge action that has not been reverted, clients must treat it\nas a fatal error.  Clients should not treat it as an error if the\nmerge includes revisions that have previously been cherry-picked.\n\nIf a `cherry-pick` action includes the first revision in which the\nbranch was changed after any earlier merge action, or if the\ndestination branch was originally created from the source branch and\nthe `cherry-pick` action includes the next revision in which the\nbranch was changed, clients should warn the user that they probably\nmeant to merge.\n\nIf a `revert` action specifies a revision that has not been\ncherry-picked, or is greater than any earlier merge action that has\nnot been reverted, clients should treat it as a fatal error.\n\nClients may warn about any merge actions they feel are unusual, but\nshould not treat anything as a fatal error unless specified above.\n\nNote: there is no `unmerge` action.  See the `merge` examples in the\nlibrary for how unmerging is achieved.\n\nEdit actions\n~~~~~~~~~~~~\n\nThe `ignore` and `amend` actions identify a directory and revision\nwhich should not create a new revision in the history.  For example,\nan accidental `svn commit` followed immediately by an `svn commit`\nreverting it might simply be ignored.  The string identifier indicates\nthe name of the directory to be edited.\n\nThe `ignore` action indicates that the client must act as if no\nchanges were made to the directory in the specified revision, whether\nor not changes were actually made.  Note that this only includes\nchanges made in the SVN repository itself, not those indicated by\nactions in the SVN history file.\n\nThe `amend` actions indicate that the state of the branch in the\ncurrent revision should overwrite the most recent revision for that\nbranch.  Clients may warn, but should not treat it as a fatal error,\nif the branch was not actually changed in the current revision.  When\noverwriting the most recent revision, clients must retain the revision\nlog from the previous revison if the action specifies `keeping the old\nlog message`, replace the revision log entirely with the log message\nfor the current revision if the action specifies `keeping the new log\nmessage`, or concatenate the new log message to the end of the old one\nif the action specifies `keeping both log messages`.  Clients may\nreformat log messages when keeping both, but are reminded of the need\nfor messages to look sensible when long chains of amendments are\ncreated.\n\nClients should treat it as a fatal error if an edit action is applied\nto a branch in the same revision as the branch is created.\n"},{"id":"187219","messageId":"7B2F5CA7-F2C1-483A-9913-B19A14AA9101@gmail.com","threadId":"29909","inReplyTo":"4F5C85A3.4080806@pileofstuff.org","subject":"Re: SVN Branch Description Format","fromName":"Steven Michalske","fromEmail":"smichalske@gmail.com","sentAt":"2012-03-18T23:18:03Z","receivedAt":"2012-03-18T23:18:03Z","isPatch":false,"sender":{"key":"smichalske@gmail.com","avatar":"https://gravatar.com/avatar/721f27456adc9ac84f3bb235f021a70015abb9e09222ae8622fc5579c6a203c1?d=mp&s=160"},"body":"Consider .SVN_BDF or .SVN.BDF instead of .BDF\n\nI worry about a branch or tag containing a \"\nCan subversion contain a \"?\n\nSteve\nOn Mar 11, 2012, at 3:59 AM, Andrew Sayers wrote:\n\n> (CCing everyone from the \"Approaches to SVN to Git conversion\" thread)\n> \n> A recent discussion of the remote helper for Subversion turned into a plan for\n> separating out revision->commit mapper projects.  Just as content import is\n> split into three parts (svn-fe, fast-import protocol, git-fast-import), r2c\n> mapping can be split into SVN export, protocol, and git import.  I've included\n> an initial draft protocol below.\n> \n> My approximate roadmap from here is to add test cases and a reference\n> implementation to the protocol, then create an SVN exporter from my existing\n> proof-of-concept, then finally write a git importer.  My proof-of-concept work\n> is at https://github.com/andrew-sayers/Proof-of-concept-History-Converter\n> \n> All comments gladly welcomed, but I would particularly appreciate suggestions\n> about how to specify the format more clearly, example SVN use cases that can't\n> be readily expressed with the language as specified, and suggestions about\n> whether forward compatibility should be built in.\n> \n> \t- Andrew\n> \n> \n> SVN Branch Description Format v0.1\n> ==================================\n> Andrew Sayers <andrew-svn@pileofstuff.org>\n> \n> This file specifies a simple format for describing how SVN revisions\n> apply to branches.  The goals of this format are to be a communication\n> protocol for programs operating on SVN history and to provide a common\n> language for developers discussing unusual SVN use cases.\n> \n> Overview\n> --------\n> \n> The SVN Branch Description Format (``BDF'') is a line-based ASCII\n> format, where each line specifies one action in the SVN history.  An\n> SVN history file contains two sections: the first is the ``header''\n> section that provides information about the file as a whole, the\n> second is the ``body'' section that provides information about things\n> that happened in specific revisions.\n> \n> Any line in a BDF file that begins with a hash or semicolon character,\n> or that contains only whitespace (including empty lines) is considered\n> to be a comment, and must be ignored.  Clients should use a leading\n> '#' to create ordinary comments to be read by users, and a leading ';'\n> for commented-out actions the client wishes to suggest to a user.\n> This makes it easier for a user to accept/reject actions by\n> search-and-replace.\n> \n> Here is an example file:\n> \n>    # the file must begin by specifying the revision of the format being used:\n>    This is a version 0.1 SVN Branch Description file\n>    Body:\n>    In r1, create branch \"trunk\"\n>    In r10, create branch \"branches/1.0\" from \"trunk\" r9\n>    In r20, create tag \"tags/version_1\" from \"branches/1.0\" r19\n>    In r20, deactivate \"tags/version_1\"\n>    # User intervention is required to confirm this action:\n>    ; In r25, merge \"trunk\" r24 into \"branches/1.0\"\n> \n> Header section\n> --------------\n> \n> The header section begins with a version identifier, continues with\n> any number of private actions, and ends with the header-body boundary\n> marker.\n> \n> Any unrecognised action in the header should be treated as a fatal\n> error.\n> \n> Version identifier\n> ~~~~~~~~~~~~~~~~~~\n> \n> The first action in this section must exactly match the following:\n> \n>    This is a version 0.1 SVN Branch Description file\n> \n> Later versions of the format will use a different identifier here.\n> This might be another number (e.g. ``version 3''), a non-numeric\n> identifier (e.g. ``experimental version''), a different format name\n> (e.g. ``SVN-BDF file''), or anything else.  Clients should treat anything\n> other than the exact string above as a fatal error.\n> \n> Private actions\n> ~~~~~~~~~~~~~~~\n> \n> Private actions begin with an open bracket and end with a close\n> bracket.  For example:\n> \n>    (my-great-parser will write debugging information to \"debug.log\")\n> \n> These actions are intended for internal use by clients using BDF as a\n> storage format.  Clients must begin any private action they create\n> with a client-specific identifier (`my-great-parser` in the above\n> example), and must ignore any private action that does not begin with\n> their identifier.  These requirements are designed to ensure that\n> clients do not use private actions to communicate with other clients -\n> please send such messages out-of-band (e.g. through arguments to a\n> command-line program), or propose a revision to the format so that all\n> clients can communicate using a standard language.\n> \n> Header-body boundary marker\n> ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n> \n> The last action in this section must exactly match the following:\n> \n>    Body:\n> \n> This serves only to indicate that the header is finishing, and the\n> body beginning.  The remainder of the file must be treated as the body\n> section.\n> \n> Body section\n> ------------\n> \n> The body section contains zero or more actions as described below.\n> The following components are widely used in these actions:\n> \n> Revision identifiers::\n>  These strings begin with the letter `r`, followed by a number in the\n>  range 1-9, then zero or more numbers in the range 0-9.  So `r1`,\n>  `r10` and `r999` are valid revision identifiers, but `1`, `r01` and\n>  `revision 999` are not.  Revision identifiers are indicated with\n>  `<revision>` in the definition of an action.\n> \n> String identifiers::\n> \n>  These strings begin with a double quote, then contain zero or more\n>  valid characters, then another double quote.  Valid characters\n>  include a backslash followed by `\\`, `r`, `n`, or `\"`, or any\n>  character other than backslash, carriage return, newline, or double\n>  quote.  So `\"foo\"`, `\"foo\\\"\"` and `\"foo\\\\\"` are valid identifiers,\n>  but `\"foo\\\"`, `\"foo\"\"` and `\"foo\\t\"` are not.  Clients must unescape\n>  string identifiers by converting `\\\"`, `\\\\`, `\\r` and `\\n` to double\n>  quote, backslash, carriage return and newline respectively.  String\n>  identifiers are indicated with `<string>` in the definition of an\n>  action.\n> \n> These are the valid actions in the body section:\n> \n>    In <revision>, create branch <string>\n>    In <revision>, create branch <string> as <string>\n>    In <revision>, create branch <string> from <string> <revision>\n>    In <revision>, create branch <string> as <string> from <string> <revision>\n> \n>    In <revision>, create tag <string>\n>    In <revision>, create tag <string> as <string>\n>    In <revision>, create tag <string> from <string> <revision>\n>    In <revision>, create tag <string> as <string> from <string> <revision>\n> \n>    In <revision>, deactivate <string>\n>    In <revision>, delete <string>\n> \n>    In <revision>, merge <string> up to <revision> into <string>\n>    In <revision>, cherry-pick <string> <revision> into <string>\n>    In <revision>, cherry-pick <string> <revision> to <revision> into <string>\n>    In <revision>, revert <string> <revision> from <string>\n>    In <revision>, revert <string> <revision> to <revision> from <string>\n> \n>    In <revision>, ignore <string>\n>    In <revision>, amend <string>, keeping the old log message\n>    In <revision>, amend <string>, keeping the new log message\n>    In <revision>, amend <string>, keeping both log messages\n> \n> All actions begin with `In <revision>,`.  This identifies the revision\n> the action applies to.  Each action must refer to a revision greater\n> than or equal to the previous action, except the first action which\n> must be greater than or equal to revision 1.  Clients should treat\n> revision numbers that are too low as fatal errors.  Clients may treat\n> revision numbers as errors if they are not present in the repository\n> (i.e. higher than the maximum revision or not part of the\n> sub-repository being examined)\n> \n> Create actions\n> ~~~~~~~~~~~~~~\n> \n> The `create branch` and `create tag` actions identify a branch or tag\n> being created in the specified revision.  The first string identifier\n> indicates the SVN directory name associated with the branch.  The `as\n> <string>` identifier indicates the name the user intended for the\n> branch or tag (if unspecified, clients should assume the user intended\n> the branch to have the same name as the directory).  The `from\n> <string> <revision>` identifiers indicate the directory associated\n> with a previously-named branch, and the revision number used as the\n> parent for this branch or tag (if unspecified, clients should assume\n> the user intended this to be a trunk).  Here are some examples:\n> \n>    # Create a trunk branch named \"trunk\" from directory \"trunk\":\n>    In r1, create branch \"trunk\"\n> \n>    # Create a branch named \"branches/foo\" from directory \"branches/foo\",\n>    # whose parent is the directory \"trunk\" as it was in revision 5:\n>    In r10, create branch \"branches/foo\" as \"foo\" from \"trunk\" r5\n> \n>    # Create a tag named \"1.0\" from directory \"tags/1.0\",\n>    # whose parent is the directory \"branches/foo\" as it was in revision 15:\n>    In r20, create tag \"tags/1.0\" as \"1.0\" from \"branches/foo\" r15\n> \n> Clients should treat it as a fatal error if the `from` revision is\n> greater than the current revision, or if the `from` branch was not\n> active in the specified revision (i.e. it hadn't been created, had\n> been deactivated or had been deleted).\n> \n> If the `from` branch was active but not changed in the specified\n> revision, clients should behave as if the user specified the last\n> revision in which the branch was edited prior to the specified\n> revision.  If the `from` revision is equal to the current revision,\n> clients should warn the user if the `from` branch was edited in that\n> revision.  These requirements make it significantly easier for users\n> to manually edit a BDF file.\n> \n> Clients should treat it as a fatal error if the name specified for a\n> branch or tag is currently in use.  A name is currently in use if it\n> was previously declared with one of the `create` actions, and has not\n> yet been deleted with the `delete` action (the `deactivate` action\n> must not be treated as removing a branch name).  Clients that check\n> for names currently in use must treat branch and tag names to be in\n> different namespaces - in other words, it is legal to have a branch\n> named `foo` at the same time as a tag named `foo`.\n> \n> Delete actions\n> ~~~~~~~~~~~~~~\n> \n> The `deactivate` and `delete` actions identify a branch or tag that\n> should no longer be considered active.  The string identifier\n> indicates the directory name associated with the branch.\n> \n> The `deactivate` action indicates that a branch or tag is still of\n> historical interest, but should no longer be updated when changes are\n> made.  For example, a tag might be deactivated after it is created, to\n> indicate that the tag should be considered immutable even though\n> changes were accidentally made later on.\n> \n> The `delete` action indicates that a branch or tag is no longer of any\n> interest, and can be ignored completely.  For example, a branch might\n> be deleted if it had been fully merged into another branch before the\n> directory was removed.\n> \n> Merge actions\n> ~~~~~~~~~~~~~\n> \n> The `merge`, `cherry-pick` and `revert` actions identify changes in\n> the relationship between two branches.  The first string identifier\n> indicates the directory name for the action's source.  The last string\n> identifier indicates the directory name for the action's destination.\n> The revision identifier(s) indicates the revision(s) for the action's\n> source.\n> \n> The `merge` action indicates that all revisions up to the specified\n> point have been applied from the source to the destination.  The\n> `cherry-pick` and `revert` actions identify an inclusive set of\n> revisions that have been applied from the source to the destination.  The\n> `merge` and `cherry-pick` actions indicate that revisions that\n> previously had not been merged now have been merged.  The `revert`\n> action indicates that revisions which had previously been merged have\n> no longer been merged.\n> \n> If two revisions were specified, clients must treat it as a fatal\n> error if the second revision is less than or equal to the first.\n> \n> Clients must treat it as a fatal error if the `from` branch was not\n> active in the specified revision.  If two revisions are specified,\n> clients must treat it as a fatal error unless the `from` branch was\n> active in both revisions.\n> \n> For the `merge` action, if the `from` branch was active but not\n> changed in the specified revision, clients must behave as if the user\n> specified the highest revision before the specified revision in which\n> the branch was changed.  If the `from` revision is equal to the\n> current revision, clients should warn the user if the from branch was\n> changed in that revision.\n> \n> For the two-revision `revert` and `cherry-pick` actions, clients must\n> treat the second revision as in the previous paragraph.  If the branch\n> was not changed in the first revision, clients must behave as if the\n> user specified the lowest revision after the specified revision in\n> which the branch was changed.\n> \n> For all `revert` and `cherry-pick` actions, clients must treat it as a\n> fatal error if no revisions in the specified range changed the branch.\n> \n> Note: the above requirements for altering revision numbers make it\n> significantly easier for users to manually edit an SVN Branch\n> Description file.\n> \n> If a `merge` action specifies a revision less than or equal to any\n> earlier merge action that has not been reverted, clients must treat it\n> as a fatal error.  Clients should not treat it as an error if the\n> merge includes revisions that have previously been cherry-picked.\n> \n> If a `cherry-pick` action includes the first revision in which the\n> branch was changed after any earlier merge action, or if the\n> destination branch was originally created from the source branch and\n> the `cherry-pick` action includes the next revision in which the\n> branch was changed, clients should warn the user that they probably\n> meant to merge.\n> \n> If a `revert` action specifies a revision that has not been\n> cherry-picked, or is greater than any earlier merge action that has\n> not been reverted, clients should treat it as a fatal error.\n> \n> Clients may warn about any merge actions they feel are unusual, but\n> should not treat anything as a fatal error unless specified above.\n> \n> Note: there is no `unmerge` action.  See the `merge` examples in the\n> library for how unmerging is achieved.\n> \n> Edit actions\n> ~~~~~~~~~~~~\n> \n> The `ignore` and `amend` actions identify a directory and revision\n> which should not create a new revision in the history.  For example,\n> an accidental `svn commit` followed immediately by an `svn commit`\n> reverting it might simply be ignored.  The string identifier indicates\n> the name of the directory to be edited.\n> \n> The `ignore` action indicates that the client must act as if no\n> changes were made to the directory in the specified revision, whether\n> or not changes were actually made.  Note that this only includes\n> changes made in the SVN repository itself, not those indicated by\n> actions in the SVN history file.\n> \n> The `amend` actions indicate that the state of the branch in the\n> current revision should overwrite the most recent revision for that\n> branch.  Clients may warn, but should not treat it as a fatal error,\n> if the branch was not actually changed in the current revision.  When\n> overwriting the most recent revision, clients must retain the revision\n> log from the previous revison if the action specifies `keeping the old\n> log message`, replace the revision log entirely with the log message\n> for the current revision if the action specifies `keeping the new log\n> message`, or concatenate the new log message to the end of the old one\n> if the action specifies `keeping both log messages`.  Clients may\n> reformat log messages when keeping both, but are reminded of the need\n> for messages to look sensible when long chains of amendments are\n> created.\n> \n> Clients should treat it as a fatal error if an edit action is applied\n> to a branch in the same revision as the branch is created.\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"187230","messageId":"4F668BCD.3010306@pileofstuff.org","threadId":"29909","inReplyTo":"7B2F5CA7-F2C1-483A-9913-B19A14AA9101@gmail.com","subject":"Re: SVN Branch Description Format","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2012-03-19T01:28:45Z","receivedAt":"2012-03-19T01:28:45Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"On 18/03/12 23:18, Steven Michalske wrote:\n> Consider .SVN_BDF or .SVN.BDF instead of .BDF\n> \n> I worry about a branch or tag containing a \"\n> Can subversion contain a \"?\n> \n> Steve\n\nI had a look into valid paths during the week, but hadn't checked quote\nmarks specifically.  Thankfully it seems to work:\n\nmkdir test_dir\ncd test_dir\nsvnadmin create repo\nmkdir checkout\nsvn checkout file://$(pwd)/repo/ checkout/\ncd checkout/\nmkdir '\"'\nsvn ci -m 'Created directory \"'\n\nI'll add this to the test suite :)\n\nOf course, it wouldn't do for SVN to make things that simple.  [1] seems\nto be the official definition of what a valid path looks like, and I've\nskipped over some important requirements in the spec.  Most importantly,\nredundant '/'s are allowed at the end of a path, and multiple '/'s are\ncollapsed down to one in SVN, so it seems prudent to import that little\neccentricity into this format.\n\nI could be persuaded about making '.svn-bdf' the recommended extension,\nbut I'd also be happy to go with a more TLA-friendly name for the whole\nthing.  \"SVN Branch Format\" would lend itself neatly to a three-letter\nextension (.sbf) that doesn't appear in Wikipedia's list of file\nformats[2], although it still encourages the RAS syndrome[3] I've\nrepeatedly stumbled over while writing the spec.  \"SVN Branching\nLanguage\" might work, and unlike \"BDF\" or \"SBF\", \"SBL\" doesn't sound at\nall like \"PDF\" when mumbled indistinctly.  Alternative suggestions are\nwelcome, with the obvious proviso that this is largely subjective and\nI'm going to pick whatever sounds best to my ear :)\n\nI'm approaching a natural break in defining the format, so I'll paste a\nnew version next week.  After that I'll probably pause the format and\nwork on the SVN exporter for a bit, so I'll have a structure to continue\nbuilding the tests and reference implementation against.\n\n\t- Andrew\n\n[1]http://subversion.apache.org/docs/api/latest/group__svn__fs__directories.html#details\n[2]http://en.wikipedia.org/wiki/List_of_file_formats\n[3]http://en.wikipedia.org/wiki/RAS_syndrome\n"},{"id":"187231","messageId":"4F668BD4.70808@pileofstuff.org","threadId":"29909","inReplyTo":"4F5C85A3.4080806@pileofstuff.org","subject":"Licensing a file format (was Re: SVN Branch Description Format)","fromName":"Andrew Sayers","fromEmail":"andrew-20120318@pileofstuff.org","sentAt":"2012-03-19T01:28:52Z","receivedAt":"2012-03-19T01:28:52Z","isPatch":false,"sender":{"key":"andrew-20120318@pileofstuff.org","avatar":null},"body":"(CCing Semen Vadishev as I'd like to know if the SubGit project has any\nopinion about this)\n\nIf you haven't been following the thread - this is a discussion of a new\nformat for describing SVN branching/merging/tagging behaviour.  Among\nother things, this would let people plug different SVN exporters into\ndifferent Git importers.\n\nI'd like advice/opinions from the community about licensing the\nspecification and reference implementation for this format, because it\nseems like establishing an open standard is a bit different to promoting\nopen source.  I've always thought of copyleft as the tool I use to\npromote sharing, but standards get more sharing by abandoning copyleft\nand relying on the network effect - forking a standard makes your\nproduct less valuable, unless you're not allowed to use the standard or\nyou have so much market share you don't have to care about standards in\nthe first place.\n\nI'm planning to release the spec under a Creative Commons\nAttribution-NoDerivs license (i.e. commercial use allowed, changes have\nto go through me) and the reference implementation under an MIT license\n(i.e. blatant theft of the exact recommended behaviour is encouraged).\nThis should minimise the barriers for people wanting to implement the\nformat as specified, and maximise the barriers for people wanting to\nsubvert the format.  The downside is that it makes life difficult for\neveryone if I'm hit by a bus, and makes me less inclined to put some of\nthe more complex algorithms into the non-copyleft reference implementation.\n\nJust to be clear, the format is one of three parts involved in getting\nSVN branches/merges/tags into git.  I plan to release an SVN exporter\nand git importer under the GPL, but expect to make a special case for\nthe format.\n\nSo the big question - would you be more inclined to use/contribute to\nthe SVN Branch Description Format if it had a different license?\n\n\t- Andrew\n"},{"id":"187233","messageId":"20120319013422.GC19680@burratino","threadId":"29909","inReplyTo":"4F668BD4.70808@pileofstuff.org","subject":"Re: Licensing a file format (was Re: SVN Branch Description Format)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-03-19T01:34:22Z","receivedAt":"2012-03-19T01:34:22Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Andrew,\n\nAndrew Sayers wrote:\n\n> I'm planning to release the spec under a Creative Commons\n> Attribution-NoDerivs license\n[...]\n> So the big question - would you be more inclined to use/contribute to\n> the SVN Branch Description Format if it had a different license?\n\nYes.  By the way, I think fear of forking/discussion of potential\nimprovements/translation into other languages in the context of\nstandards is misguided.  If you would like legal protection for your\nstandard, that is what trademark law is for.\n\nKind regards,\nJonathan\n"},{"id":"187276","messageId":"4F6797AD.2070501@pileofstuff.org","threadId":"29909","inReplyTo":"20120319013422.GC19680@burratino","subject":"Re: Licensing a file format (was Re: SVN Branch Description Format)","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2012-03-19T20:31:41Z","receivedAt":"2012-03-19T20:31:41Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"On 19/03/12 01:34, Jonathan Nieder wrote:\n> Hi Andrew,\n> \n> Andrew Sayers wrote:\n> \n>> I'm planning to release the spec under a Creative Commons\n>> Attribution-NoDerivs license\n> [...]\n>> So the big question - would you be more inclined to use/contribute to\n>> the SVN Branch Description Format if it had a different license?\n> \n> Yes.  By the way, I think fear of forking/discussion of potential\n> improvements/translation into other languages in the context of\n> standards is misguided.  If you would like legal protection for your\n> standard, that is what trademark law is for.\n> \n> Kind regards,\n> Jonathan\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n\nCould you expand on this?  A quick tour of the git codebase suggests\nyour objection is just to the \"no derivatives\" bit for documentation,\nand not to the MIT license for code?\n\nIt sounds like you're saying that forking isn't a big real-world\nproblem, which I guess makes sense - it'll all work out in the end as\nlong as a single standard is in everybody's interests.  So the CC-BY\nlicense is my favourite for now.\n\n\t- Andrew\n"},{"id":"187364","messageId":"20120320225918.GA31958@sigill.intra.peff.net","threadId":"29909","inReplyTo":"4F6797AD.2070501@pileofstuff.org","subject":"Re: Licensing a file format (was Re: SVN Branch Description Format)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-03-20T22:59:18Z","receivedAt":"2012-03-20T22:59:18Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 19, 2012 at 08:31:41PM +0000, Andrew Sayers wrote:\n\n> > Yes.  By the way, I think fear of forking/discussion of potential\n> > improvements/translation into other languages in the context of\n> > standards is misguided.  If you would like legal protection for your\n> > standard, that is what trademark law is for.\n> [...]\n> \n> Could you expand on this?  A quick tour of the git codebase suggests\n> your objection is just to the \"no derivatives\" bit for documentation,\n> and not to the MIT license for code?\n> \n> It sounds like you're saying that forking isn't a big real-world\n> problem, which I guess makes sense - it'll all work out in the end as\n> long as a single standard is in everybody's interests.  So the CC-BY\n> license is my favourite for now.\n\nI think the problem is that there are two levels of forking. You want\npeople to be able to build off of your standard for a number of\nlegitimate reasons. Perhaps they are publishing a draft proposal of\nenhancements. Perhaps they are adapting parts of the content of your\nstandard to a different domain. Perhaps the original author has become\nunresponsive and somebody else wants to pick up maintainership. Those\nare all things we do with code, and they help the ecosystem.\n\nWhat _isn't_ good is somebody modifying your standard and then claiming\nthat their implementation is \"the real SVN History Description\" format.\n\nI think Jonathan's point is that CC-BY-ND doesn't allow the legitimate\nthings in the top paragraph. And your real problem (in the second\nparagraph) is not derivatives, but derivatives claiming to be something\nthey are not (the official standard). And trademarks are the legal tool\nfor avoiding confusion like that.\n\nIn practice, I don't think this kind of name-hijacking is a big deal.\nThere are many forks of git, and somebody could make a derivative git\nthat is buggy, interacts badly with existing repository formats, or\ninteracts badly with other git clients via the network protocol. But\npeople are usually kind enough not to call their other implementations\n\"git\", and it just works out in practice. So you could probably get by\nwith just a regular source code license (but I am far from an expert, so\ntake the appropriate grain of salt).\n\n-Peff\n"},{"id":"187548","messageId":"4F6BBF02.3000701@pileofstuff.org","threadId":"29909","inReplyTo":"4F5C85A3.4080806@pileofstuff.org","subject":"SVN Branching Language (was Re: SVN Branch Description Format)","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2012-03-23T00:08:34Z","receivedAt":"2012-03-23T00:08:34Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"This is the second draft of the SVN branching language.  If you're\ninterested in how SVN revisions map to git commits, please read it and\nlet me know what you think.  You might also be interested in the\nreference implementation and nascent collection of tests[1], although\nthese wouldn't yet withstand a thorough review.\n\nI plan to pause language work and concentrate on SVN export for a\nwhile now, because it will be easier to e.g. write tests once I have\nsome code to test.\n\nHere's a little background for people new to the list:\n\nI'm interested in ways to map SVN revisions to git commits, but have\nfound it surprisingly hard to grasp the problem.  Having trouble\ngrasping a problem is generally a good sign that your solution is too\nsmall, so I split the problem in three:\n\n1. A language to describe SVN branching and merging\n2. A program to export such a file from an SVN repository\n3. A program to import such a file into a git repository\n\nThis has let me concentrate on manageable parts of the problem.  For\nexample, Sam Vilain recently pointed out[2] so-called \"piecemeal\nmerges\" that split a merge across several revisions.  There's no way I\ncould have figured out a plan to solve that in one go, but between us\nwe were able to find a representation and a way of importing it into\ngit.  I still don't know how to detect and export it from Subversion,\nbut I can worry about that another day.\n\nThis is the second draft I've brought to the git mailing list for\ndiscussion.  The list has a long and proud tradition of including\npatches in e-mails so people can review code from their e-mail client,\nbut in this case the patch would be so large that it's better simply\nto include the new text.  I've deliberately left the reference\nimplementation and tests out of this e-mail because they're not ready\nfor review.\n\n\t- Andrew\n\n[1] https://github.com/andrew-sayers/SVN-Branching-Language\n[2] http://article.gmane.org/gmane.comp.version-control.git/192418\n\n\n\nSVN Branching Language v0.1\n===========================\nAndrew Sayers <andrew-sbl@pileofstuff.org>\n\nThis file specifies a simple language for describing how SVN revisions\nrelate to branches.  The goals of this language are to be a\ncommunication protocol for programs operating on SVN history and to\nprovide a lingua franca for developers discussing unusual SVN use\ncases.\n\nOverview\n--------\n\nThe SVN Branching Language (``SBL'') is a line-based UTF-8 format,\nwhere each line specifies one action in the SVN history.  An SBL file\ncontains two sections: the first is the ``header'' section that\nprovides information about the file as a whole, the second is the\n``body'' section that provides information about things that happened\nin specific revisions.\n\nAny line in an SBL file that begins with a hash or semicolon\ncharacter, or that contains only whitespace (including empty lines) is\nconsidered to be a comment, and must be ignored.  Clients should use a\nleading '#' to create ordinary comments to be read by users, and a\nleading ';' for commented-out actions the client wishes to suggest to\na user.  This makes it easier for a user to accept/reject actions by\nsearch-and-replace.\n\nHere is an example file:\n\n    # the file must begin by specifying the revision of the language being used:\n    This is a version 0.1 SVN Branching Language file\n    Body:\n    In r1, create branch \"trunk\"\n    In r10, create branch \"branches/1.0\" from \"trunk\" r9\n    In r20, create tag \"tags/version_1\" from \"branches/1.0\" r19\n    In r20, deactivate \"tags/version_1\"\n    # User intervention is required to confirm this action:\n    ; In r25, merge \"trunk\" up to r24 into \"branches/1.0\"\n\nTerminology\n-----------\n\nThe following words should be interpreted as specified below:\n\nDirectory::\n  A string representing a directory in the SVN tree.  A directory can\n  have several flows (i.e. it can be created and deleted multiple\n  times), some of which may have names and others not.  The exact\n  rules for valid directory names are discussed below, but should be\n  as close as possible to the rules for a valid SVN directory name.\n\nName::\n  A string representing a branch or tag.  This is the conventional\n  name for a tag as described by users, and is not represented\n  anywhere in SVN.  For example, a directory \"branches/v1.x/v1.0\"\n  might have the name \"v1.0\".  Note that although tags and branches\n  are functionally identical, clients must treat tag names and branch\n  names as being in different namespaces - for example, a branch name\n  \"v1.0\" and a tag name \"v1.0\" can both exist at the same time.\n\nExist::\n  A directory is said to exist in a given revision if the directory\n  would appear in an `svn ls` command for that revision.  Clients can\n  fully implement this language without tracking whether directories\n  exist - the term is defined here purely to make discussion easier.\n\nActive::\n  A directory is said to be \"active\" if it its most recent \"create\"\n  action occurred more recently than its most recent \"delete\" or\n  \"deactivate\" action.  A branch will usually be active if it exists\n  and has a name, but there are special cases - for example, an\n  existent directory associated with a tag might be deactivated as a\n  precautionary measure in case of accidental commits.  Note that only\n  directories are said to be \"active\" - branches and tags are\n  instead \"accessible\" (under a slightly different set of\n  circumstances).\n\nAccessible::\n  A branch or tag is said to be \"accessible\" if it has been created\n  more recently than it has been deleted (but not deactivated).  Note\n  that only branches and tags are said to be \"accessible\".\n  Directories are instead \"active\" (under a slightly different set of\n  circumstances).\n\nTrunk::\n  A directory, branch or tag is said to be a \"trunk\" if it has no\n  parent directory, branch or tag.  Trunk tags are possible but\n  exceedingly rare.\n\nHeader section\n--------------\n\nThe header section begins with a version identifier, continues with\nany number of private actions, and ends with the header-body boundary\nmarker.\n\nAny unrecognised action in the header should be treated as a fatal\nerror.\n\nVersion identifier\n~~~~~~~~~~~~~~~~~~\n\nThe first action in this section (not including comments) must exactly\nmatch the following:\n\n    This is a version 0.1 SVN Branching Language file\n\nLater versions of the language will use a different identifier here.\nThis might be another number (e.g. ``version 3''), a non-numeric\nidentifier (e.g. ``experimental version''), a different name\n(e.g. ``SBL file''), or anything else.  Clients must treat anything\nother than the exact string above as a fatal error.\n\nPrivate actions\n~~~~~~~~~~~~~~~\n\nPrivate actions begin with an open bracket and end with a close\nbracket.  For example:\n\n    (my-great-parser will write debugging information to \"debug.log\")\n\nThese actions are intended for internal use by clients using SBL as a\nstorage format.  Clients must begin any private action they create\nwith a client-specific identifier followed by a space\n(`my-great-parser` in the above example), and must ignore any private\naction that does not begin with their identifier.  Client-specific\nidentifiers must contain one or more characters and must not include\nthe space, carriage return or newline characters.  These requirements\nare designed to ensure that clients do not use private actions to\ncommunicate with other clients - please send such messages out-of-band\n(e.g. through arguments to a command-line program), or propose a\nrevision to the language so that all clients can communicate using a\nstandard language.\n\nHeader-body boundary marker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe last action in this section must exactly match the following:\n\n    Body:\n\nThis serves only to indicate that the header is finishing, and the\nbody beginning.  The remainder of the file must be treated as the body\nsection.  Note that this action significantly reduces the complexity\nof writing an SBL parser, because clients can use this to switch\nbetween ``header'' and ``body'' parsing modes.\n\nBody section\n------------\n\nThe body section contains zero or more actions as described below.\nAny unrecognised action in the header should be treated as a fatal\nerror.\n\nThe following components are widely used in body actions:\n\nRevision identifiers::\n  These strings begin with the letter `r`, followed by a number in the\n  range 1-9, then zero or more numbers in the range 0-9.  So `r1`,\n  `r10` and `r999` are valid revision identifiers, but `1`, `r01` and\n  `revision 999` are not.  Revision identifiers are indicated with\n  `<revision>` in the definition of an action.\n\nString identifiers::\n\n  These strings begin with a double quote, then contain zero or more\n  valid characters, then another double quote.  Valid characters\n  include a backslash followed by `\\`, `r`, `n`, or `\"`, or any\n  character other than backslash, carriage return, newline, double\n  quote, or the null character (U+0000).  So `\"foo\"`, `\"foo\\\"\"` and\n  `\"foo\\\\\"` are valid identifiers, but `\"foo\\\"`, `\"foo\"\"` and\n  `\"foo\\t\"` are not.  Clients must unescape string identifiers by\n  removing the leading/trailing quotes and converting `\\\"`, `\\\\`, `\\r`\n  and `\\n` to double quote, backslash, carriage return and newline\n  respectively.\n\nDirectory identifiers::\n  These string identifiers indicate a directory.  As well as the\n  requirements of a string identifier, valid directory identifiers\n  must be valid directories when unescaped.  A valid directory must be\n  a sequence of zero or more directory entry names, separated by slash\n  characters `/`, and possibly ending with slash characters.  Each\n  directory entry name can contain any Unicode character except the\n  null character and the slash character `/`. No directory entry may\n  be named `.`, `..`, or the empty string.  When unescaping a\n  directory, clients must first do the unescaping for a string\n  identifier, then convert the identifier to Unicode canonical\n  decomposition (NFD) form, then collapse every series of '/'\n  characters to a single character (e.g. `foo//bar` should become\n  `foo/bar`), and finally remove any trailing `/` character.\n  Directory identifiers are indicated with `<directory>` in the\n  definition of an action.\n  Note that although this definition is based on SVN's own\n  documentation, SBL clients must follow the rules above instead of\n  the SVN rules in the event of any contradiction between the two.\n  SVN's documentation is available from their source repository:\n  http://subversion.apache.org/docs/api/latest/group__svn__fs__directories.html#details\n\nName identifiers::\n  These string identifiers indicate a branch or tag name.  As well as\n  the requirements for a string identifier, valid name identifiers\n  must be valid names when unescaped (see the \"terminology\" section\n  for details).  As well as the rules for string identifers, the empty\n  string is not a valid name identifier.\n\nThese are the valid actions in the body section:\n\n    In <revision>, create branch <directory>\n    In <revision>, create branch <directory> as <name>\n    In <revision>, create branch <directory> from <directory> <revision>\n    In <revision>, create branch <directory> as <name> from <directory> <revision>\n\n    In <revision>, create tag <directory>\n    In <revision>, create tag <directory> as <name>\n    In <revision>, create tag <directory> from <directory> <revision>\n    In <revision>, create tag <directory> as <name> from <directory> <revision>\n\n    In <revision>, deactivate <directory>\n    In <revision>, delete <directory>\n    In <revision>, delete branch <name>\n    In <revision>, delete tag <name>\n\n    In <revision>, merge <directory> up to <revision> into <directory>\n    In <revision>, cherry-pick <directory> <revision> into <directory>\n    In <revision>, cherry-pick <directory> <revision> to <revision> into <directory>\n    In <revision>, revert <directory> <revision> from <directory>\n    In <revision>, revert <directory> <revision> to <revision> from <directory>\n    \n    In <revision>, ignore <directory>\n    In <revision>, amend <directory>, keeping the old log message\n    In <revision>, amend <directory>, keeping the new log message\n    In <revision>, amend <directory>, keeping both log messages\n\nAll actions begin with `In <revision>,`.  This identifies the revision\nthe action applies to.  Each action must refer to a revision greater\nthan or equal to the previous action, except the first action which\nmust be greater than or equal to revision 1.  Clients should treat\nrevision numbers that are too low as fatal errors.\n\nCreate actions\n~~~~~~~~~~~~~~\n\nThe `create branch` and `create tag` actions identify a directory\nbeing made active and a branch/tag being made accessible in the\nspecified revision.  The first string identifier indicates the SVN\ndirectory name associated with the branch/tag.  The `as <name>`\nidentifier indicates the name the user intended for the branch/tag.\nIf the `as <name>` identifier is not specified, clients must use the\ndirectory name as the identifier, unless the directory name is the\nempty string (root directory), in which case they should treat it as a\nfatal error (because the empty string is a valid directory but not a\nvalid name).  The `from <directory> <revision>` identifiers indicate\nthe directory and revision number to be used as the parent for this\nbranch/tag (if unspecified, clients should assume the user intended\nthis to be a trunk).  Here are some examples:\n\n    # Create a trunk branch named \"trunk\" from directory \"trunk\":\n    In r1, create branch \"trunk\"\n\n    # Create a branch named \"branches/foo\" from directory \"branches/foo\",\n    # whose parent is the directory \"trunk\" as it was in revision 5:\n    In r10, create branch \"branches/foo\" as \"foo\" from \"trunk\" r5\n\n    # Create a tag named \"1.0\" from directory \"tags/1.0\",\n    # whose parent is the directory \"branches/foo\" as it was in revision 15:\n    In r20, create tag \"tags/1.0\" as \"1.0\" from \"branches/foo\" r15\n\nClients should treat it as a fatal error if the directory was already\nactive in the current revision.\n\nClients should treat it as a fatal error if the name was already\naccessible in the current revision (remember that branches and tags\nmust be treated as being in different namespaces).\n\nClients should treat it as a fatal error if the `from` revision is\ngreater than the current revision, or if the `from` directory was not\naccessible in the specified revision.\n\nIf the `from` directory was active but not changed in the specified\nrevision, clients should behave as if the user specified the last\nrevision in which the directory was changed prior to the specified\nrevision.  If the `from` revision is equal to the current revision,\nand the `from` directory was changed in the current revision, then\nclients should warn the user, but should not treat it as a fatal\nerror.  These requirements make it significantly easier for users to\nmanually edit SBL files.\n\nDelete actions\n~~~~~~~~~~~~~~\n\nThe `deactivate` and `delete` actions identify a name that should\nbecome inaccessible, and/or a directory that should become inactive.\nThe string identifier indicates the directory or name to be modified.\n\nThe `deactivate` action indicates that a directory should become\ninactive, but that the associated name should remain accessible.  This\nis commonly used for a branch or tag that is still of historical\ninterest, but should no longer be updated when changes are made.  For\nexample, a tag might be deactivated after it is created, to indicate\nthat the tag should be considered immutable even though changes were\naccidentally committed to the directory later on.\n\nThe `delete` action indicates that a directory should become inactive,\nand the associated name should become inaccessible.  This is commonly\nused when a branch or tag is no longer of any interest, and can be\nignored completely.  For example, a branch might be deleted if it had\nbeen fully merged into another branch before the directory was\nremoved.\n\nThe `delete branch` and `delete tag` actions indicate that a name\nshould become inaccessible, and the associated directory should become\ninactive if it is still active.  For example, the branch associated\nwith a deactivated directory might be deleted when the user wants to\ncreate a new branch with the same name.\n\nClients should only generate `delete branch` and `delete tag` actions\nif it would be unsafe to generate a `delete` action because the\ndirectory has already been deactivated, but should expect users\nto manually edit files and add any type of action.\n\nActions that deactivate a directory should treat it as a fatal error\nif the directory is not currently active.  This includes the `delete`\naction, which behave in ways users would not exect if the directory is\nrenamed or replaced in SVN before the action occurs.\n\nActions that make a name inaccessible should treat it as a fatal error\nif the name is not currently accessible.\n\nMerge actions\n~~~~~~~~~~~~~\n\nThe `merge`, `cherry-pick` and `revert` actions identify changes in\nthe relationship between two directories.  The first string identifier\nindicates the directory name for the action's source.  The last string\nidentifier indicates the directory name for the action's destination.\nThe revision identifier(s) indicates the revision(s) for the action's\nsource.\n\nThe `merge` action indicates that all revisions up to the specified\npoint have been applied from the source to the destination.  The\n`cherry-pick` and `revert` actions identify an inclusive set of\nrevisions that have been applied from the source to the destination.\nThe `merge` and `cherry-pick` actions indicate that revisions that\npreviously had not been applied now have been applied.  The `revert`\naction indicates that revisions which had previously been applied have\nno longer been applied.\n\nIf two revisions were specified, clients must treat it as a fatal\nerror if the first revision is greater than the second.\n\nClients must treat it as a fatal error if the `from` directory was not\nactive in the specified revision.  If two revisions are specified,\nclients must treat it as a fatal error if the `from` directory was\ninactive in either revision, or was deactivated after the first\nrevision and reactivated before the last revision.\n\nFor the `merge` action, if the `from` directory was active but not\nchanged in the specified revision, clients must behave as if the user\nspecified the highest revision in which the directory was changed\nbefore the revision they actually specified.  If the `from` revision\nis equal to the current revision, clients should warn the user if the\nfrom directory was changed in that revision.\n\nFor the two-revision `revert` and `cherry-pick` actions, clients must\ntreat the second revision as in the previous paragraph.  If the from\ndirectory was not changed in the first revision, clients must behave\nas if the user specified the lowest revision in which the directory\nwas changed after the specified revision.\n\nFor all `revert` and `cherry-pick` actions, clients must treat it as a\nfatal error if no revisions in the specified range changed the\ndirectory.\n\nNote: the above requirements for altering revision numbers make it\nsignificantly easier for users to manually edit an SBL file.\n\nIf a `merge` action specifies a revision less than or equal to any\nearlier merge action that has not been reverted, clients should treat\nit as a fatal error.  Clients should not treat it as a fatal error if\nthe merge includes revisions that have previously been cherry-picked.\n\nIf a `cherry-pick` action includes the first revision in which the\ndirectory was changed after any earlier merge action, or if the\ndestination directory was originally created from the source directory\nand the `cherry-pick` action includes the next revision in which the\ndirectory was changed, clients should warn the user that they probably\nmeant to merge.\n\nIf a `revert` action specifies a revision that has not been\ncherry-picked, or is greater than any earlier merge action that has\nnot been reverted, clients should treat it as a fatal error.\n\nClients may warn about any merge actions they feel are unusual, but\nshould not treat anything as a fatal error unless specified above.\n\nNote: there is no `unmerge` action.  See `t/basic/unmerge.sh` for\nhow unmerging is achieved.\n\nEdit actions\n~~~~~~~~~~~~\n\nThe `ignore` and `amend` actions identify a directory and revision\nwhich should not create a new revision in the history.  For example,\nan accidental `svn commit` followed immediately by an `svn commit`\nreverting it might simply be ignored.  The string identifier indicates\nthe name of the directory to be edited.\n\nThe `ignore` action indicates that the client must act as if no\nchanges were made to the directory in the specified revision, whether\nor not changes were actually made.  Note that this only includes\nchanges made in the SVN repository itself, not those indicated by\nactions in the SBL file.\n\nThe `amend` actions indicate that the state of the directory in the\ncurrent revision should overwrite the most recent revision for that\ndirectory.  When overwriting the most recent revision, clients must\nretain the revision log from the previous revision if the action\nspecifies `keeping the old log message`, replace the revision log\nentirely with the log message for the current revision if the action\nspecifies `keeping the new log message`, or concatenate the new log\nmessage to the end of the old one if the action specifies `keeping\nboth log messages`.  Clients may reformat log messages when keeping\nboth, but are reminded of the need for messages to look sensible when\nlong chains of amendments are created.\n\nClients may warn, but should not treat it as a fatal error, if an edit\naction is specified for a directory that was not changed in the\ncurrent revision.\n\nClients should treat it as a fatal error if an edit action is applied\nto a directory in the same revision as the directory becomes active.\n\nLimitations\n-----------\n\nSBL only allows a directory to be associated with a maximum of one\nbranch or one tag at once.  There is no clear use case for allowing a\nuser to e.g. associate a tag with a directory that is already a\nbranch, and disallowing it enables better detection of user errors.\nFuture versions of this language might allow multiple branches/tags\nper directory if a use case is found.\n\nAlthough not explicitly forbidden, clients are not required to support\nrecursive branches.  For example, if ``trunk'' is a branch, clients\nmay assume that ``trunk/foo'' is neither a branch nor a tag.\n\nSee `t/advanced/subproject_branch.sh` for a common edge case for\nparsers that disallow recursive branches.\n\nLicense\n-------\n\nSVN Branching Language by Andrew Sayers <andrew-sbl@pileofstuff.org>\nis licensed under a Creative Commons Attribution 3.0 Unported License.\n\nThe full license is available here: http://creativecommons.org/licenses/by/3.0/legalcode\nA human-readable summary is available here: http://creativecommons.org/licenses/by/3.0/\n\nThe following explanation must have no bearing on the meaning of the\nabove license:\n\nMy primary goal in drafting this language was to provide a single\nformat that everyone could use to describe the behaviour of SVN\nrepositories.  I felt this goal was best served by allowing commercial\nuse of the language, and by allowing other dialects to be formed but\ndiscouraged because of the network effect of a common language.\n"},{"id":"188123","messageId":"CALkWK0mh5hKz+=-Ur3bE2+YBiSwFiPtZXQOJdMwY=BemXrqwWQ@mail.gmail.com","threadId":"29909","inReplyTo":"4F5C85A3.4080806@pileofstuff.org","subject":"Re: SVN Branch Description Format","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2012-03-30T04:06:49Z","receivedAt":"2012-03-30T04:06:49Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nAndrew Sayers wrote:\n> SVN Branch Description Format v0.1\n\nI found this pretty interesting.  Doesn't it duplicate some of the\nfunctionality of reposurgeon [1] though?\n\n[1]: http://esr.ibiblio.org/?p=4071\n\n    Ram\n"},{"id":"188226","messageId":"4F765D9F.70404@pileofstuff.org","threadId":"29909","inReplyTo":"CALkWK0mh5hKz+=-Ur3bE2+YBiSwFiPtZXQOJdMwY=BemXrqwWQ@mail.gmail.com","subject":"Re: SVN Branch Description Format","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2012-03-31T01:27:59Z","receivedAt":"2012-03-31T01:27:59Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"On 30/03/12 05:06, Ramkumar Ramachandra wrote:\n> Hi,\n> \n> Andrew Sayers wrote:\n>> SVN Branch Description Format v0.1\n> \n> I found this pretty interesting.  Doesn't it duplicate some of the\n> functionality of reposurgeon [1] though?\n> \n> [1]: http://esr.ibiblio.org/?p=4071\n\nYes, I've been procrastinating all week instead of reading up on\nreposurgeon and contacting ESR about possibile collaboration.\n\nI think you need something a bit more expressive than reposurgeon's\nformat to do SVN<->Git conversion well, and I think you need something a\nbit more accessible in order to document SVN edge cases.  For example, I\ndon't see how reposurgeon could represent all the madness around SVN\ncherry-picks that become merges when you manually add information from\nrevision logs, then become cherry-picks again when you find a revert\ncoming in from another branch.  Having said that, a (lossy) conversion\nbetween SBL and reposurgeon format would probably be useful and not that\nhard.\n\nThe link above put it very well that most people leave an embarrassed\n“to be done” comment and disappear when they realise how much of a\nnightmare the mapping is.  What it doesn't mention is that everyone\nexperiences a slightly different part of the nightmare, and that we can\nonly really tackle the problem by getting everyone's freaky edge cases\nwritten up in one language in one place.  The test suite[1] isn't that\nimpressive right now, but in the long-term I'm really keen to get\nimplementers to pool their knowledge so we can all benefit.  SBL is\ndesigned to let people open the relevant test without reading the spec\nand say \"oh right I understand what a piecemeal merge is now.  I'll go\nimplement that in my project\".\n\nI'm currently working on code to read an SVN dump and write to SBL.\nThis will definitely overlap with reposurgeon's SVN export\nfunctionality, but without seeing the final code I can't say how much.\nThat's fine though - as I say, the only way to get a good solution is\nfor multiple implementers to investigate the problem and share the edge\ncases they find.\n\n\t- Andrew\n\n[1]https://github.com/andrew-sayers/SVN-Branching-Language/tree/master/t\n"}]}