Merge lp:~akretion-team/anybox.recipe.openerp/git-shallow-clone into lp:anybox.recipe.openerp

Proposed by Raphaël Valyi - http://www.akretion.com
Status: Work in progress
Proposed branch: lp:~akretion-team/anybox.recipe.openerp/git-shallow-clone
Merge into: lp:anybox.recipe.openerp
Prerequisite: lp:~acsone-openerp/anybox.recipe.openerp/git-merges
Diff against target: 681 lines (+368/-105) (has conflicts)
10 files modified
CHANGES.rst (+13/-0)
README.rst (+4/-0)
anybox/recipe/openerp/base.py (+24/-9)
anybox/recipe/openerp/runtime/session.py (+65/-0)
anybox/recipe/openerp/server.py (+14/-1)
anybox/recipe/openerp/vcs/bzr.py (+14/-0)
anybox/recipe/openerp/vcs/git.py (+36/-0)
anybox/recipe/openerp/vcs/tests/test_git.py (+179/-95)
doc/conf.py (+4/-0)
doc/configuration.rst (+15/-0)
Text conflict in CHANGES.rst
Text conflict in README.rst
Text conflict in anybox/recipe/openerp/vcs/bzr.py
Text conflict in anybox/recipe/openerp/vcs/git.py
Text conflict in anybox/recipe/openerp/vcs/tests/test_git.py
Text conflict in doc/conf.py
Text conflict in doc/configuration.rst
To merge this branch: bzr merge lp:~akretion-team/anybox.recipe.openerp/git-shallow-clone
Reviewer Review Type Date Requested Status
Georges Racinet Needs Fixing
Review via email: mp+222980@code.launchpad.net

Description of the change

git shallow clone support through the depth option. Save the planet from full clones!

To post a comment you must log in.
Revision history for this message
Laurent Mignon (Acsone) (lmi) wrote :

It would be nice to specify generically any argument in the options for the fetch command. We could imagine a naming convention for the options. ex 'fetch.depth', 'fetch.prune'.
The code could be:
for option, value in self.options.items():
   if not option.statswith('fetch'):
       continue
    arg = '--%s' %option.split('.')[1]
    if value:
       arg += "=%s"%value
    fetch_cmd.extend([arg]])

Just an idea

549. By Georges Racinet

1.8.4 release

550. By Georges Racinet

New dev cycle

551. By Georges Racinet

Bumped version in doc, and setup less confusing doc upload path

552. By Georges Racinet

[MRG] merged fix for #1249566

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Agree.

Also, it seems that at update having that depth option might cause issues.

Setting as work in progress for now.

Revision history for this message
Georges Racinet (gracinet) wrote :

I've got the vague feeling that it'd be preferable to have a globally named depth option rather that tying it as an option for fetch, because depth feels like a property of the repo, and we might in the future use other subcommands as fetch that would also be affected by it.

Revision history for this message
Georges Racinet (gracinet) wrote :

Did some testing, the suggested patch works for the master branch only.
That's because currently the recipe will fetch without arguments, and then try and checkout the wished branch.

Therefore I guess this very wanted feature will take a bit of refactoring.

review: Needs Fixing
Revision history for this message
Georges Racinet (gracinet) wrote :

To be clear, and not to waste your time : I'll try and come up with a working version today/this week.

553. By Georges Racinet

Providing environments initialization in runtime.session

This needs further testing, in particular with older OpenERP/Odoo versions
Besides, the current Odoo master version that this has been developped
against calls itself 9.0.0 alpha, one needs to check if the problem
exists for the 8.0 branch.

At this point, I'm not really sure of what happens for a script that would
spawn several threads.

554. By Raphaël Valyi - http://www.akretion.com

merge git-shallow-clone

555. By Raphaël Valyi - http://www.akretion.com

git checkout -f; git merge -> git pull

556. By Raphaël Valyi - http://www.akretion.com

WIP

557. By Raphaël Valyi - http://www.akretion.com

WIP

558. By Raphaël Valyi - http://www.akretion.com

WIP

559. By Raphaël Valyi - http://www.akretion.com

WIP

560. By Raphaël Valyi - http://www.akretion.com

working version with pip; hacky though

561. By Raphaël Valyi - http://www.akretion.com

WIP bypass zc.buildout totally

Unmerged revisions

561. By Raphaël Valyi - http://www.akretion.com

WIP bypass zc.buildout totally

560. By Raphaël Valyi - http://www.akretion.com

working version with pip; hacky though

559. By Raphaël Valyi - http://www.akretion.com

WIP

558. By Raphaël Valyi - http://www.akretion.com

WIP

557. By Raphaël Valyi - http://www.akretion.com

WIP

556. By Raphaël Valyi - http://www.akretion.com

WIP

555. By Raphaël Valyi - http://www.akretion.com

git checkout -f; git merge -> git pull

554. By Raphaël Valyi - http://www.akretion.com

merge git-shallow-clone

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGES.rst'
2--- CHANGES.rst 2014-06-16 23:27:47 +0000
3+++ CHANGES.rst 2014-07-18 23:12:56 +0000
4@@ -5,6 +5,7 @@
5 Changes displayed as "unreleased" in the stable series are released
6 with any higher released unstable versions.
7
8+<<<<<<< TREE
9 1.9.0 (unreleased)
10 ------------------
11 - launchpad #1294020: vcs-revert=on-merge option, and implementation
12@@ -21,6 +22,18 @@
13 1.8.4 (2014-06-16)
14 ------------------
15 - launchpad #1327756: support new addons layout on github
16+=======
17+1.8.5 (unreleased)
18+------------------
19+- launchpad #1338405: provided necessary environments init in session
20+ (needed for interactive session and various scripts)
21+- launchpad #1249566: [bzr] avoid outgoing requests in offline mode
22+ due to lp: locations resolution
23+
24+1.8.4 (2014-06-16)
25+------------------
26+- launchpad #1327756: support new addons layout on github
27+>>>>>>> MERGE-SOURCE
28 - launchpad #1324579: [odoo] generation of gevent script (longpolling)
29 and have it used through the --workers option
30 - launchpad #1321919: [v8] fixed potential masking of standard library
31
32=== modified file 'README.rst'
33--- README.rst 2014-06-16 23:27:47 +0000
34+++ README.rst 2014-07-18 23:12:56 +0000
35@@ -72,5 +72,9 @@
36 * Jacques-Etienne Baudoux
37 * Laurent Mignon
38 * Leonardo Pistone
39+<<<<<<< TREE
40 * Stefan Rijnhart
41 * Stéphane Bidoul
42+=======
43+ * Stefan Rijnhart
44+>>>>>>> MERGE-SOURCE
45
46=== modified file 'anybox/recipe/openerp/base.py'
47--- anybox/recipe/openerp/base.py 2014-06-16 23:27:47 +0000
48+++ anybox/recipe/openerp/base.py 2014-07-18 23:12:56 +0000
49@@ -3,6 +3,7 @@
50 import os
51 import sys
52 import urllib
53+import subprocess
54 import tarfile
55 import setuptools
56 import logging
57@@ -276,11 +277,18 @@
58 If some distributions are known as soft requirements, will retry
59 without them
60 """
61+ eggs = "\n".join([i for i in self.options['eggs'].split(os.linesep) if i not in ['Pillow', 'openerp', 'pychart', 'anybox.recipe.openerp', 'anybox']])
62+ requirement_file = os.path.join(os.getcwd(), 'odoo_requirements.txt')
63+ with open(requirement_file, 'w') as the_file:
64+ the_file.write('--find-links=http://download.gna.org/pychart\n')
65+ the_file.write(eggs)
66+ subprocess.call(['pip', 'install', '-r', requirement_file])
67 while True:
68 missing = None
69 eggs = zc.recipe.egg.Scripts(self.buildout, '', self.options)
70 try:
71- eggs.install()
72+ pass
73+# eggs.install()
74 except MissingDistribution, exc:
75 missing = exc.data[0].project_name
76 except VersionConflict:
77@@ -289,10 +297,10 @@
78 missing = exc.message.split(os.linesep)[0].split()[-1]
79
80 if missing is not None:
81- msg = self.missing_deps_instructions.get(missing)
82- if msg is None:
83- raise
84- logger.error("Could not find %r. " + msg, missing)
85+# msg = self.missing_deps_instructions.get(missing)
86+# if msg is None:
87+# raise
88+# logger.error("Could not find %r. " + msg, missing)
89 # GR this condition won't be enough in case of version
90 # conditions in requirement
91 if missing not in self.soft_requirements:
92@@ -304,7 +312,11 @@
93 else:
94 break
95
96- self.eggs_reqs, self.eggs_ws = eggs.working_set()
97+# offline = eggs.buildout['buildout'].get('offline')
98+# eggs.buildout['buildout']['offline'] = 'true'
99+# self.eggs_reqs, self.eggs_ws = eggs.working_set()
100+# eggs.buildout['buildout']['offline'] = offline
101+ self.eggs_reqs, self.eggs_ws = [], []#eggs.working_set()
102 self.ws = self.eggs_ws
103
104 def apply_version_dependent_decisions(self):
105@@ -813,9 +825,12 @@
106
107 if self.version_detected is None:
108 raise EnvironmentError('Version of OpenERP could not be detected')
109- self.merge_requirements()
110- self.install_requirements()
111-
112+ # NOTE we could eventually activate these 2 lines
113+ # that would try to install Odoo requirements with pip here
114+# self.merge_requirements()
115+# self.install_requirements()
116+ self.eggs_reqs, self.eggs_ws = [], []#eggs.working_set()
117+ self.ws = self.eggs_ws
118 self._install_startup_scripts()
119
120 # create the config file
121
122=== modified file 'anybox/recipe/openerp/runtime/session.py'
123--- anybox/recipe/openerp/runtime/session.py 2014-04-30 13:42:42 +0000
124+++ anybox/recipe/openerp/runtime/session.py 2014-07-18 23:12:56 +0000
125@@ -177,6 +177,67 @@
126 config['without_demo'] = saved_without_demo
127 self.init_cursor()
128 self.uid = SUPERUSER_ID
129+ self.init_environments()
130+
131+ def init_environments(self):
132+ """Enter the environments context manager, but don't leave it
133+
134+ Automatically called by :meth:`open` and registry altering methods.
135+ See :class:``openerp.api.Environment`` for explanations about
136+ environments.
137+
138+ For OpenERP/Odoo versions prior to the new style API merge, this
139+ is a no-op.
140+
141+ This thread-local ``environments`` is initialized and cleaned with
142+ each request in the normal usage of the framework.
143+ That's why is is provided as a context manager.
144+
145+ Therefore, user code probably needs in some case to clean it to avoid
146+ side effects. This can be done by calling :meth:`clean_environments`.
147+ """
148+ try:
149+ gen_factory = openerp.api.Environment.manage
150+ except AttributeError:
151+ return
152+
153+ self._environments_gen_context = gen_factory().gen
154+ self._environments_gen_context.next()
155+
156+ def clean_environments(self, reinit=True):
157+ """Cleans the thread-local environment.
158+
159+ See :meth:`init_environments` for more details.
160+ This method does nothing if the environments have not been initialized.
161+
162+ :param bool reinit: if ``True``, :meth:`init_environments` will be
163+ called again after cleaning
164+ """
165+ try:
166+ gen_context = self._environments_gen_context
167+ except AttributeError:
168+ return
169+
170+ try:
171+ gen_context.next()
172+ except StopIteration:
173+ pass
174+ else:
175+ logger.warn("clean_environments: we had the context manager, but "
176+ "it had not been called. This suggest low-leve "
177+ "tampering with it that should be more cautious. "
178+ "Proceeding with cleansing.")
179+ try:
180+ gen_context.next()
181+ except StopIteration:
182+ pass
183+ else:
184+ raise RuntimeError("Called the environments context manager "
185+ "twice and it's not finished. "
186+ "This is really unexpected.")
187+ del self._environments_gen_context
188+ if reinit:
189+ self.init_environments()
190
191 # A later version might read that from buildout configuration.
192 _version_parameter_name = DEFAULT_VERSION_PARAMETER
193@@ -277,6 +338,7 @@
194
195 def rollback(self):
196 self.cr.rollback()
197+ self.clean_environments()
198
199 def close(self):
200 """Close the cursor and forget about the current database.
201@@ -285,6 +347,7 @@
202 """
203 dbname = self.cr.dbname
204 self.cr.close()
205+ self.clean_environments()
206 openerp.modules.registry.RegistryManager.delete(dbname)
207
208 def update_modules(self, modules, db=None):
209@@ -315,6 +378,7 @@
210 db, update_module=True)
211 config['update'].clear()
212 self.init_cursor()
213+ self.clean_environments()
214
215 def install_modules(self, modules, db=None, update_modules_list=True,
216 open_with_demo=False):
217@@ -366,6 +430,7 @@
218 config['init'].clear()
219 config['without_demo'] = saved_without_demo
220 self.init_cursor()
221+ self.clean_environments()
222
223 def handle_command_line_options(self, to_handle):
224 """Handle prescribed command line options and eat them.
225
226=== modified file 'anybox/recipe/openerp/server.py'
227--- anybox/recipe/openerp/server.py 2014-06-08 12:37:29 +0000
228+++ anybox/recipe/openerp/server.py 2014-07-18 23:12:56 +0000
229@@ -47,6 +47,14 @@
230 # discarding, because we have a special behaviour with custom
231 # interpreters
232 opt.pop('interpreter', None)
233+ self.extra_paths = [
234+os.path.join(os.getcwd(), 'anybox.recipe.openerp')
235+# 'anybox.recipe.openerp',
236+# 'eggs/zc.buildout-2.2.1-py2.7.egg',
237+# 'eggs/zc.recipe.egg-2.0.1-py2.7.egg',
238+# 'eggs/distribute-0.7.3-py2.7.egg',
239+ ]
240+
241 self.openerp_scripts = {}
242 self.missing_deps_instructions.update({
243 'openerp-command': ("Please provide it with 'develop' or "
244@@ -500,7 +508,10 @@
245 ""))
246
247 reqs, ws = self.eggs_reqs, self.eggs_ws
248- return zc.buildout.easy_install.scripts(
249+ # NOTE the next line is a hack if we don't want to install the eggs dependencies
250+ # via the recipe.
251+ self.options['bin-directory'] = os.path.join(os.getcwd(), '..', '..', 'bin')
252+ x = zc.buildout.easy_install.scripts(
253 reqs, ws, sys.executable, self.options['bin-directory'],
254 scripts={},
255 interpreter=int_name,
256@@ -510,6 +521,8 @@
257 # TODO investigate these options:
258 # relative_paths=self._relative_paths,
259 )
260+ print x
261+ return x
262
263 def _install_openerp_scripts(self):
264 """Install scripts registered in self.openerp_scripts.
265
266=== modified file 'anybox/recipe/openerp/vcs/bzr.py'
267--- anybox/recipe/openerp/vcs/bzr.py 2014-05-16 13:14:27 +0000
268+++ anybox/recipe/openerp/vcs/bzr.py 2014-07-18 23:12:56 +0000
269@@ -174,6 +174,7 @@
270 if not os.path.exists(self.target_dir):
271 # not branched yet, there's nothing to clean
272 return
273+<<<<<<< TREE
274 subprocess.check_call(['bzr', 'clean-tree',
275 '--ignored', '--force'])
276 with working_directory_keeper:
277@@ -187,6 +188,19 @@
278 with working_directory_keeper:
279 os.chdir(self.target_dir)
280 subprocess.check_call(['bzr', 'revert', '-r', revision])
281+=======
282+ subprocess.check_call(['bzr', 'clean-tree',
283+ '--ignored', '--force'])
284+ with working_directory_keeper:
285+ os.chdir(self.target_dir)
286+ subprocess.check_call(['bzr', 'clean-tree',
287+ '--ignored', '--force'])
288+
289+ def revert(self, revision):
290+ with working_directory_keeper:
291+ os.chdir(self.target_dir)
292+ subprocess.check_call(['bzr', 'revert', '-r', revision])
293+>>>>>>> MERGE-SOURCE
294
295 def _update(self, revision):
296 """Update existing branch at target dir to given revision.
297
298=== modified file 'anybox/recipe/openerp/vcs/git.py'
299--- anybox/recipe/openerp/vcs/git.py 2014-07-03 22:15:08 +0000
300+++ anybox/recipe/openerp/vcs/git.py 2014-07-18 23:12:56 +0000
301@@ -75,6 +75,7 @@
302
303 if not offline:
304 # TODO what if remote repo is actually local fs ?
305+<<<<<<< TREE
306 # GR, redux: git has a two notions of local repos, which
307 # differ at least for shallow clones : path or file://
308 os.chdir(target_dir)
309@@ -110,6 +111,41 @@
310 # (seen with 1.7.2.5 from Debian 6)
311 subprocess.check_call(['git', 'pull', '--no-edit',
312 self.url, revision])
313+=======
314+ os.chdir(target_dir)
315+ logger.info("%s> git remote set-url %s %s",
316+ target_dir, BUILDOUT_ORIGIN, url)
317+ subprocess.call(['git', 'remote', 'set-url',
318+ BUILDOUT_ORIGIN, url])
319+ fetch_cmd = ['git', 'fetch', BUILDOUT_ORIGIN]
320+ if self.options.get('depth'):
321+ fetch_cmd.extend(["--depth=%s" % self.options['depth']])
322+ logger.info("%s> %s" % (target_dir, ' '.join(fetch_cmd)))
323+ subprocess.check_call(fetch_cmd)
324+ # TODO: check what happens when there are local changes
325+ # TODO: what about the 'clean' option
326+ logger.info("%s> git checkout -f %s", target_dir, revision)
327+ subprocess.check_call(['git', 'checkout', '-f', revision])
328+ if self._is_a_branch(revision):
329+ # fast forward
330+ logger.info("%s> git pull %s %s",
331+ target_dir, BUILDOUT_ORIGIN, revision)
332+ subprocess.check_call(['git', 'pull',
333+ BUILDOUT_ORIGIN, revision])
334+
335+ def merge(self, revision):
336+ """Merge revision into current branch"""
337+ with working_directory_keeper:
338+ if not self.is_versioned(self.target_dir):
339+ raise RuntimeError("Cannot merge into non existent "
340+ "or non git local directory %s" %
341+ self.target_dir)
342+ os.chdir(self.target_dir)
343+ logger.info("%s> git pull %s %s",
344+ self.target_dir, self.url, revision)
345+ subprocess.check_call(['git', 'pull', '--no-edit',
346+ self.url, revision])
347+>>>>>>> MERGE-SOURCE
348
349 def archive(self, target_path):
350 # TODO: does this work with merge-ins?
351
352=== modified file 'anybox/recipe/openerp/vcs/tests/test_git.py'
353--- anybox/recipe/openerp/vcs/tests/test_git.py 2014-06-17 09:36:40 +0000
354+++ anybox/recipe/openerp/vcs/tests/test_git.py 2014-07-18 23:12:56 +0000
355@@ -240,98 +240,182 @@
356 branch("remotebranch")
357 with open(os.path.join(target_dir, 'tracked')) as f:
358 self.assertEquals(f.read().strip(), "last after remote branch")
359-
360-
361-class GitMergeTestCase(GitBaseTestCase):
362-
363- def create_src(self):
364- GitBaseTestCase.create_src(self)
365- os.chdir(self.src_repo)
366-
367- self.make_branch(self.src_repo, 'branch1')
368- self.checkout_branch(self.src_repo, 'branch1')
369- git_write_commit(self.src_repo, 'file_on_branch1',
370- "file on branch 1", msg="on branch 1")
371- self.checkout_branch(self.src_repo, 'master')
372-
373- self.make_branch(self.src_repo, 'branch2')
374- self.checkout_branch(self.src_repo, 'branch2')
375- git_write_commit(self.src_repo, 'file_on_branch2',
376- "file on branch 2", msg="on branch 2")
377- self.checkout_branch(self.src_repo, 'master')
378-
379- def make_branch(self, src_dir, name):
380- """create a branch
381- """
382- subprocess.check_call(['git', 'branch', name], cwd=src_dir)
383-
384- def checkout_branch(self, src_dir, name):
385- """checkout a branch
386- """
387- subprocess.check_call(['git', 'checkout', name], cwd=src_dir)
388-
389- def test_01_check_src_repo(self):
390- """test if the creation of source repo worked as expected"""
391- target_dir = os.path.join(self.dst_dir, "to_repo")
392- repo = GitRepo(target_dir, self.src_repo)
393-
394- repo('master')
395- self.assertFalse(os.path.exists(os.path.join(target_dir,
396- 'file_on_branch1')),
397- 'file_on_branch1 should not exist')
398- self.assertFalse(os.path.exists(os.path.join(target_dir,
399- 'file_on_branch2')),
400- 'file_on_branch2 should not exist')
401-
402- repo('branch1')
403- self.assertTrue(os.path.exists(os.path.join(target_dir,
404- 'file_on_branch1')),
405- 'file_on_branch1 should exist')
406- self.assertFalse(os.path.exists(os.path.join(target_dir,
407- 'file_on_branch2')),
408- 'file_on_branch2 should not exist')
409-
410- repo('branch2')
411- self.assertFalse(os.path.exists(os.path.join(target_dir,
412- 'file_on_branch1')),
413- 'file_on_branch1 should not exist')
414- self.assertTrue(os.path.exists(os.path.join(target_dir,
415- 'file_on_branch2')),
416- 'file_on_branch2 should exist')
417-
418- def test_02_merge(self):
419- target_dir = os.path.join(self.dst_dir, "to_repo")
420- repo = GitRepo(target_dir, self.src_repo)
421- repo('master')
422- git_set_user_info(repo.target_dir)
423-
424- repo.merge('branch1')
425- self.assertTrue(os.path.exists(os.path.join(target_dir,
426- 'file_on_branch1')),
427- 'file_on_branch1 should exist')
428- self.assertFalse(os.path.exists(os.path.join(target_dir,
429- 'file_on_branch2')),
430- 'file_on_branch2 should not exist')
431- repo.merge('branch2')
432- self.assertTrue(os.path.exists(os.path.join(target_dir,
433- 'file_on_branch1')),
434- 'file_on_branch1 should exist')
435- self.assertTrue(os.path.exists(os.path.join(target_dir,
436- 'file_on_branch2')),
437- 'file_on_branch2 should exist')
438-
439- def test_03_revert(self):
440- target_dir = os.path.join(self.dst_dir, "to_repo")
441- repo = GitRepo(target_dir, self.src_repo)
442- repo('master')
443- git_set_user_info(repo.target_dir)
444-
445- repo.merge('branch1')
446- self.assertTrue(os.path.exists(os.path.join(target_dir,
447- 'file_on_branch1')),
448- 'file_on_branch1 should exist')
449-
450- repo.revert('master')
451- self.assertFalse(os.path.exists(os.path.join(target_dir,
452- 'file_on_branch1')),
453- 'file_on_branch1 should not exist')
454+<<<<<<< TREE
455+
456+
457+class GitMergeTestCase(GitBaseTestCase):
458+
459+ def create_src(self):
460+ GitBaseTestCase.create_src(self)
461+ os.chdir(self.src_repo)
462+
463+ self.make_branch(self.src_repo, 'branch1')
464+ self.checkout_branch(self.src_repo, 'branch1')
465+ git_write_commit(self.src_repo, 'file_on_branch1',
466+ "file on branch 1", msg="on branch 1")
467+ self.checkout_branch(self.src_repo, 'master')
468+
469+ self.make_branch(self.src_repo, 'branch2')
470+ self.checkout_branch(self.src_repo, 'branch2')
471+ git_write_commit(self.src_repo, 'file_on_branch2',
472+ "file on branch 2", msg="on branch 2")
473+ self.checkout_branch(self.src_repo, 'master')
474+
475+ def make_branch(self, src_dir, name):
476+ """create a branch
477+ """
478+ subprocess.check_call(['git', 'branch', name], cwd=src_dir)
479+
480+ def checkout_branch(self, src_dir, name):
481+ """checkout a branch
482+ """
483+ subprocess.check_call(['git', 'checkout', name], cwd=src_dir)
484+
485+ def test_01_check_src_repo(self):
486+ """test if the creation of source repo worked as expected"""
487+ target_dir = os.path.join(self.dst_dir, "to_repo")
488+ repo = GitRepo(target_dir, self.src_repo)
489+
490+ repo('master')
491+ self.assertFalse(os.path.exists(os.path.join(target_dir,
492+ 'file_on_branch1')),
493+ 'file_on_branch1 should not exist')
494+ self.assertFalse(os.path.exists(os.path.join(target_dir,
495+ 'file_on_branch2')),
496+ 'file_on_branch2 should not exist')
497+
498+ repo('branch1')
499+ self.assertTrue(os.path.exists(os.path.join(target_dir,
500+ 'file_on_branch1')),
501+ 'file_on_branch1 should exist')
502+ self.assertFalse(os.path.exists(os.path.join(target_dir,
503+ 'file_on_branch2')),
504+ 'file_on_branch2 should not exist')
505+
506+ repo('branch2')
507+ self.assertFalse(os.path.exists(os.path.join(target_dir,
508+ 'file_on_branch1')),
509+ 'file_on_branch1 should not exist')
510+ self.assertTrue(os.path.exists(os.path.join(target_dir,
511+ 'file_on_branch2')),
512+ 'file_on_branch2 should exist')
513+
514+ def test_02_merge(self):
515+ target_dir = os.path.join(self.dst_dir, "to_repo")
516+ repo = GitRepo(target_dir, self.src_repo)
517+ repo('master')
518+ git_set_user_info(repo.target_dir)
519+
520+ repo.merge('branch1')
521+ self.assertTrue(os.path.exists(os.path.join(target_dir,
522+ 'file_on_branch1')),
523+ 'file_on_branch1 should exist')
524+ self.assertFalse(os.path.exists(os.path.join(target_dir,
525+ 'file_on_branch2')),
526+ 'file_on_branch2 should not exist')
527+ repo.merge('branch2')
528+ self.assertTrue(os.path.exists(os.path.join(target_dir,
529+ 'file_on_branch1')),
530+ 'file_on_branch1 should exist')
531+ self.assertTrue(os.path.exists(os.path.join(target_dir,
532+ 'file_on_branch2')),
533+ 'file_on_branch2 should exist')
534+
535+ def test_03_revert(self):
536+ target_dir = os.path.join(self.dst_dir, "to_repo")
537+ repo = GitRepo(target_dir, self.src_repo)
538+ repo('master')
539+ git_set_user_info(repo.target_dir)
540+
541+ repo.merge('branch1')
542+ self.assertTrue(os.path.exists(os.path.join(target_dir,
543+ 'file_on_branch1')),
544+ 'file_on_branch1 should exist')
545+
546+ repo.revert('master')
547+ self.assertFalse(os.path.exists(os.path.join(target_dir,
548+ 'file_on_branch1')),
549+ 'file_on_branch1 should not exist')
550+=======
551+
552+
553+class GitMergeTestCase(GitBaseTestCase):
554+
555+ def create_src(self):
556+ GitBaseTestCase.create_src(self)
557+ os.chdir(self.src_repo)
558+
559+ self.make_branch(self.src_repo, 'branch1')
560+ self.checkout_branch(self.src_repo, 'branch1')
561+ git_write_commit(self.src_repo, 'file_on_branch1',
562+ "file on branch 1", msg="on branch 1")
563+ self.checkout_branch(self.src_repo, 'master')
564+
565+ self.make_branch(self.src_repo, 'branch2')
566+ self.checkout_branch(self.src_repo, 'branch2')
567+ git_write_commit(self.src_repo, 'file_on_branch2',
568+ "file on branch 2", msg="on branch 2")
569+ self.checkout_branch(self.src_repo, 'master')
570+
571+ def make_branch(self, src_dir, name):
572+ """create a branch
573+ """
574+ subprocess.check_call(['git', 'branch', name], cwd=src_dir)
575+
576+ def checkout_branch(self, src_dir, name):
577+ """checkout a branch
578+ """
579+ subprocess.check_call(['git', 'checkout', name], cwd=src_dir)
580+
581+ def test_01_check_src_repo(self):
582+ """test if the creation of source repo worked as expected"""
583+ target_dir = os.path.join(self.dst_dir, "to_repo")
584+ repo = GitRepo(target_dir, self.src_repo)
585+
586+ repo('master')
587+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
588+ 'file_on_branch1 should not exist')
589+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch2')),
590+ 'file_on_branch2 should not exist')
591+
592+ repo('branch1')
593+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
594+ 'file_on_branch1 should exist')
595+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch2')),
596+ 'file_on_branch2 should not exist')
597+
598+ repo('branch2')
599+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
600+ 'file_on_branch1 should not exist')
601+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch2')),
602+ 'file_on_branch2 should exist')
603+
604+ def test_02_merge(self):
605+ target_dir = os.path.join(self.dst_dir, "to_repo")
606+ repo = GitRepo(target_dir, self.src_repo)
607+ repo('master')
608+
609+ repo.merge('branch1')
610+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
611+ 'file_on_branch1 should exist')
612+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch2')),
613+ 'file_on_branch2 should not exist')
614+ repo.merge('branch2')
615+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
616+ 'file_on_branch1 should exist')
617+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch2')),
618+ 'file_on_branch2 should exist')
619+
620+ def test_03_revert(self):
621+ target_dir = os.path.join(self.dst_dir, "to_repo")
622+ repo = GitRepo(target_dir, self.src_repo)
623+ repo('master')
624+
625+ repo.merge('branch1')
626+ self.assertTrue(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
627+ 'file_on_branch1 should exist')
628+
629+ repo.revert('master')
630+ self.assertFalse(os.path.exists(os.path.join(target_dir, 'file_on_branch1')),
631+ 'file_on_branch1 should not exist')
632+>>>>>>> MERGE-SOURCE
633
634=== modified file 'doc/conf.py'
635--- doc/conf.py 2014-06-16 17:51:34 +0000
636+++ doc/conf.py 2014-07-18 23:12:56 +0000
637@@ -49,7 +49,11 @@
638 # The short X.Y version.
639 version = '1.9'
640 # The full version, including alpha/beta/rc tags.
641+<<<<<<< TREE
642 release = '1.9.0-dev'
643+=======
644+release = '1.8.5-dev'
645+>>>>>>> MERGE-SOURCE
646
647 # The language for content autogenerated by Sphinx. Refer to documentation
648 # for a list of supported languages.
649
650=== modified file 'doc/configuration.rst'
651--- doc/configuration.rst 2014-07-03 22:15:08 +0000
652+++ doc/configuration.rst 2014-07-18 23:12:56 +0000
653@@ -262,6 +262,7 @@
654 :lightweight-checkout: Working copy initialized with the command
655 ``bzr checkout --lightweight url ...``
656
657+<<<<<<< TREE
658 .. _merges:
659
660 merges
661@@ -275,6 +276,20 @@
662
663 .. note:: new in version 1.9.0
664
665+=======
666+.. _merges:
667+
668+merges
669+------
670+Specify which VCS branches need to be merged into repositories
671+specified under :ref:`addons` or :ref:`version`. The syntax is
672+the same as for repositories specified under these directives.
673+
674+Currently only merges on bzr repositories are supported.
675+
676+.. note:: new in version 1.9.0
677+
678+>>>>>>> MERGE-SOURCE
679 .. _eggs:
680
681 eggs

Subscribers

People subscribed via source and target branches