annotate hgsubversion/layouts/standard.py @ 1107:0f16e11b2c2b stable

layouts: fix crash when importing hgext_hgsubversion This change was introduced in 4a92eb1484ba and fixed importing issues for mercurial < 2.8. Unfortunately, this broke imports for newer versions of mercurial that have hgsubversion installed in sys.path. We now wrap the import in a try-block to catch this ImportError.
author Sean Farley <sean.michael.farley@gmail.com>
date Thu, 06 Feb 2014 14:30:05 -0600
parents 4a92eb1484ba
children eaefb3413b87
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1026
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
1 import os.path
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
2 import pickle
1012
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
3
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
4 import base
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
5
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
6 class StandardLayout(base.BaseLayout):
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
7 """The standard trunk, branches, tags layout"""
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
8
1026
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
9 def __init__(self, ui):
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
10 base.BaseLayout.__init__(self, ui)
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
11
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
12 self._tag_locations = None
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
13
1093
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
14 self._branch_dir = ui.config('hgsubversion', 'branchdir', 'branches')
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
15 if self._branch_dir[0] == '/':
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
16 self._branch_dir = self._branch_dir[1:]
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
17 if self._branch_dir[-1] != '/':
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
18 self._branch_dir += '/'
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
19
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
20 self._infix = ui.config('hgsubversion', 'infix', '').strip('/')
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
21 if self._infix:
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
22 self._infix = '/' + self._infix
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
23
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
24 self._trunk = 'trunk%s' % self._infix
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
25
1012
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
26 def localname(self, path):
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
27 if path == self._trunk:
1012
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
28 return None
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
29 elif path.startswith(self._branch_dir) and path.endswith(self._infix):
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
30 path = path[len(self._branch_dir):]
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
31 if self._infix:
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
32 path = path[:-len(self._infix)]
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
33 return path
1012
e8cd211684c4 layouts: refactor out svn path to mercurial branch logic
David Schleimer <dschleimer@fb.com>
parents:
diff changeset
34 return '../%s' % path
1013
d507c1a12dcb layouts: refactor mercurial branch to svn path mapping out of svnmeta
David Schleimer <dschleimer@fb.com>
parents: 1012
diff changeset
35
d507c1a12dcb layouts: refactor mercurial branch to svn path mapping out of svnmeta
David Schleimer <dschleimer@fb.com>
parents: 1012
diff changeset
36 def remotename(self, branch):
d507c1a12dcb layouts: refactor mercurial branch to svn path mapping out of svnmeta
David Schleimer <dschleimer@fb.com>
parents: 1012
diff changeset
37 if branch == 'default' or branch is None:
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
38 path = self._trunk
1013
d507c1a12dcb layouts: refactor mercurial branch to svn path mapping out of svnmeta
David Schleimer <dschleimer@fb.com>
parents: 1012
diff changeset
39 elif branch.startswith('../'):
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
40 path = branch[3:]
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
41 else:
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
42 path = ''.join((self._branch_dir, branch, self._infix))
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
43
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
44 return path
1014
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
45
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
46 def remotepath(self, branch, subdir='/'):
1090
80a456b77ade layouts: fix remotepath for default branch in standard layout
David Schleimer <dschleimer@fb.com>
parents: 1029
diff changeset
47 if subdir == '/':
80a456b77ade layouts: fix remotepath for default branch in standard layout
David Schleimer <dschleimer@fb.com>
parents: 1029
diff changeset
48 subdir = ''
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
49 branchpath = self._trunk
1090
80a456b77ade layouts: fix remotepath for default branch in standard layout
David Schleimer <dschleimer@fb.com>
parents: 1029
diff changeset
50 if branch and branch != 'default':
1014
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
51 if branch.startswith('../'):
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
52 branchpath = branch[3:]
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
53 else:
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
54 branchpath = ''.join((self._branch_dir, branch, self._infix))
1014
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
55
0ed7cf23e801 layouts: refactor path component of convinfo generation into layouts lib
David Schleimer <dschleimer@fb.com>
parents: 1013
diff changeset
56 return '%s/%s' % (subdir or '', branchpath)
1026
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
57
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
58 def taglocations(self, meta_data_dir):
1101
4a92eb1484ba layouts: fix crash when importing hgsubversion itself (issue #402)
Greg Ward <greg@gerg.ca>
parents: 1094
diff changeset
59 # import late to avoid trouble when running the test suite
1107
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
60 try:
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
61 # newer versions of mercurial >= 2.8 will import this because the
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
62 # hgext_ logic is already being done in core
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
63 from hgsubversion import util
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
64 except ImportError:
0f16e11b2c2b layouts: fix crash when importing hgext_hgsubversion
Sean Farley <sean.michael.farley@gmail.com>
parents: 1101
diff changeset
65 from hgext_hgsubversion import util
1101
4a92eb1484ba layouts: fix crash when importing hgsubversion itself (issue #402)
Greg Ward <greg@gerg.ca>
parents: 1094
diff changeset
66
1026
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
67 if self._tag_locations is None:
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
68
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
69 tag_locations_file = os.path.join(meta_data_dir, 'tag_locations')
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
70
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
71 if os.path.exists(tag_locations_file):
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
72 f = open(tag_locations_file)
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
73 self._tag_locations = pickle.load(f)
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
74 f.close()
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
75 else:
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
76 self._tag_locations = self.ui.configlist('hgsubversion',
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
77 'tagpaths',
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
78 ['tags'])
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
79 util.pickle_atomic(self._tag_locations, tag_locations_file)
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
80
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
81 # ensure nested paths are handled properly
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
82 self._tag_locations.sort()
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
83 self._tag_locations.reverse()
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
84
66395f232b7c layouts: pull tag location list management into layout module
David Schleimer <dschleimer@fb.com>
parents: 1014
diff changeset
85 return self._tag_locations
1027
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
86
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
87 def get_path_tag(self, path, taglocations):
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
88 for tagspath in taglocations:
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
89 if path.startswith(tagspath + '/'):
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
90 tag = path[len(tagspath) + 1:]
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
91 if tag:
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
92 return tag
16045f6f3fef layouts: pull svn path -> potential tag name mapping into layouts
David Schleimer <dschleimer@fb.com>
parents: 1026
diff changeset
93 return None
1029
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
94
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
95 def split_remote_name(self, path, known_branches):
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
96
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
97 # this odd evolution is how we deal with people doing things like
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
98 # creating brances (note the typo), committing to a branch under it,
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
99 # and then moving it to branches
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
100
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
101 # we need to find the ../foo branch names, if they exist, before
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
102 # trying to create a normally-named branch
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
103
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
104 components = path.split('/')
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
105 candidate = ''
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
106 while self.localname(candidate) not in known_branches and components:
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
107 if not candidate:
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
108 candidate = components.pop(0)
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
109 else:
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
110 candidate += '/'
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
111 candidate += components.pop(0)
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
112 if self.localname(candidate) in known_branches:
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
113 return candidate, '/'.join(components)
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
114
513f2b607b06 layouts: pull out logic for splitting svn paths into branch and local parts
David Schleimer <dschleimer@fb.com>
parents: 1027
diff changeset
115 if path == 'trunk' or path.startswith('trunk/'):
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
116 return self._trunk, path[len(self._trunk) + 1:]
1093
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
117
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
118 if path.startswith(self._branch_dir):
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
119 path = path[len(self._branch_dir):]
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
120 components = path.split('/', 1)
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
121 branch_path = ''.join((self._branch_dir, components[0]))
1093
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
122 if len(components) == 1:
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
123 local_path = ''
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
124 else:
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
125 local_path = components[1]
1094
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
126
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
127 if local_path == '':
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
128 branch_path += self._infix
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
129 elif local_path.startswith(self._infix[1:] + '/'):
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
130 branch_path += self._infix
9a7e3dbd0f6e layouts: add support for an infix between tbt and the hg root
David Schleimer <dschleimer@fb.com>
parents: 1093
diff changeset
131 local_path = local_path[len(self._infix):]
1093
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
132 return branch_path, local_path
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
133
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
134 components = path.split('/')
791382a21cc4 layouts: add support for configuring branches directory
David Schleimer <dschleimer@fb.com>
parents: 1090
diff changeset
135 return '/'.join(components[:-1]), components[-1]