@@ -191,38 +191,10 @@ def checkout_layers(layers, confdir, layerdir, d):
logger.plain("Making a symbolic link {} pointing to {}".format(dst, src))
os.symlink(src, dst)
- def _has_local_modifications(r_name, r_path):
- fixed_revisions = json.load(open(os.path.join(confdir, "sources-fixed-revisions.json")))
-
- if not r_name in fixed_revisions['sources']:
- logger.warning("""Source {} is added with path {}.
-This path already exists, but it has no entry in a fixed revisions
-record. To ensure possible local modifications are not lost, it will
-be preserved in a backup directory.""".format(r_name, r_path))
- return True
-
- rev = fixed_revisions['sources'][r_name]['git-remote']['rev']
+ def _has_uncommitted_changes(r_path):
status = bb.process.run('git -C {} status --porcelain'.format(r_path))[0]
if status:
return True
- diff = bb.process.run('git -C {} diff {} {}'.format(r_path, get_diff_color_param(), rev))[0]
- if diff:
- return True
- return False
-
- def _restrict_commits(r_name, r_path):
- hook_path = os.path.join(r_path, '.git', 'hooks', 'pre-commit')
- restrict_hook = """#!/bin/sh
-echo "This repository is managed by bitbake-setup, and making commits is restricted.
-If you wish to make local modifications, clone it separately, and re-initialize using
-bitbake-setup init -L {} /path/to/repo/checkout"
-exit 1
-""".format(r_name)
- with open(hook_path, 'w') as f:
- f.write(restrict_hook)
- import stat
- st = os.stat(hook_path)
- os.chmod(hook_path, st.st_mode | stat.S_IEXEC)
layers_fixed_revisions = copy.deepcopy(layers)
repodirs = []
@@ -242,19 +214,21 @@ exit 1
if os.path.lexists(repodir_path):
if os.path.islink(repodir_path):
os.remove(repodir_path)
- elif _has_local_modifications(r_name, repodir_path):
+ elif r_local:
backup_path = add_unique_timestamp_to_path(repodir_path + '-backup')
logger.warning("""Source {} in {} contains local modifications. Renaming to {} to preserve them.
For local development work it is recommended to clone the needed layers separately and re-initialize using -L option:
bitbake-setup init -L {} /path/to/repo/checkout""".format(
r_name, repodir_path, backup_path, r_name))
os.rename(repodir_path, backup_path)
- else:
- shutil.rmtree(repodir_path)
+ elif _has_uncommitted_changes(repodir_path):
+ logger.warning("""Source {} in {} contains uncommitted changes. They will be saved using 'git stash',
+to allow rebasing onto latest commits""".format(r_name, repodir_path))
+ bb.process.run("git -C {} add .".format(repodir_path))
+ bb.process.run("git -C {} stash".format(repodir_path))
if r_remote:
_checkout_git_remote(r_remote, repodir, layers_fixed_revisions)
- _restrict_commits(r_name, repodir_path)
if r_local:
_symlink_local(os.path.expanduser(r_local["path"]), repodir_path)
@@ -830,7 +804,7 @@ def do_fetch(fetcher, dir):
oldstdout = sys.stdout
sys.stdout = f
fetcher.download()
- fetcher.unpack(dir)
+ fetcher.unpack_update(dir)
sys.stdout = oldstdout
def update_registry(registry, cachedir, d):
@@ -447,16 +447,27 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
self.assertEqual(self.testrepopath, os.path.realpath(custom_layer_path))
self.config_is_unchanged(custom_setup_path)
+ def _check_layer_backups(layer_path, expected_backups):
+ files = os.listdir(layer_path)
+ backups = len([f for f in files if 'backup' in f])
+ self.assertEqual(backups, expected_backups, msg = "Expected {} layer backups, got {}, directory listing: {}".format(expected_backups, backups, files))
+
# Change the configuration to refer to a local source, then to another local source, then back to a git remote
# Run status/update after each change and verify that nothing breaks
+ # Also check that layer backups happen when expected
c = 'gadget'
setuppath = self.get_setup_path('test-config-1', c)
self.config_is_unchanged(setuppath)
+ layers_path = os.path.join(setuppath, 'layers')
+ layer_path = os.path.join(layers_path, 'test-repo')
+ _check_layer_backups(layers_path, 0)
+
json_1 = self.add_local_json_config_to_registry('test-config-1.conf.json', self.testrepopath)
os.environ['BBPATH'] = os.path.join(setuppath, 'build')
out = self.runbbsetup("update --update-bb-conf='yes'")
_check_local_sources(setuppath)
+ _check_layer_backups(layers_path, 1)
prev_path = self.testrepopath
self.testrepopath = prev_path + "-2"
@@ -465,23 +476,14 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
os.environ['BBPATH'] = os.path.join(setuppath, 'build')
out = self.runbbsetup("update --update-bb-conf='yes'")
_check_local_sources(setuppath)
+ _check_layer_backups(layers_path, 1)
self.testrepopath = prev_path
json_1 = self.add_json_config_to_registry('test-config-1.conf.json', branch, branch)
os.environ['BBPATH'] = os.path.join(setuppath, 'build')
out = self.runbbsetup("update --update-bb-conf='yes'")
self.check_setupdir_files(setuppath, test_file_content)
-
- # Also check that there are no layer backups up to this point, then make a change that should
- # result in a layer backup, and check that it does happen.
- def _check_layer_backups(layer_path, expected_backups):
- files = os.listdir(layer_path)
- backups = len([f for f in files if 'backup' in f])
- self.assertEqual(backups, expected_backups, msg = "Expected {} layer backups, got {}, directory listing: {}".format(expected_backups, backups, files))
-
- layers_path = os.path.join(setuppath, 'layers')
- layer_path = os.path.join(layers_path, 'test-repo')
- _check_layer_backups(layers_path, 0)
+ _check_layer_backups(layers_path, 1)
## edit a file without making a commit
with open(os.path.join(layer_path, 'local-modification'), 'w') as f:
@@ -492,16 +494,26 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
out = self.runbbsetup("update --update-bb-conf='yes'")
_check_layer_backups(layers_path, 1)
- ## edit a file and try to make a commit; this should be rejected
+ ## edit a file and make a commit such that no rebase conflicts occur
with open(os.path.join(layer_path, 'local-modification'), 'w') as f:
f.write('locally-modified-again\n')
self.git('add .', cwd=layer_path)
- with self.assertRaisesRegex(bb.process.ExecutionError, "making commits is restricted"):
- self.git('commit -m "Adding a local modification"', cwd=layer_path)
+ self.git('commit -m "Adding a local modification"', cwd=layer_path)
test_file_content = "modified-again-and-again\n"
self.add_file_to_testrepo('test-file', test_file_content)
out = self.runbbsetup("update --update-bb-conf='yes'")
- _check_layer_backups(layers_path, 2)
+ _check_layer_backups(layers_path, 1)
+
+ ## edit a file and make a commit in a way that causes a rebase conflict
+ with open(os.path.join(layer_path, 'test-file'), 'w') as f:
+ f.write('locally-modified\n')
+ self.git('add .', cwd=layer_path)
+ self.git('commit -m "Adding a local modification"', cwd=layer_path)
+ test_file_content = "remotely-modified\n"
+ self.add_file_to_testrepo('test-file', test_file_content)
+ with self.assertRaisesRegex(bb.process.ExecutionError, "Merge conflict in test-file"):
+ out = self.runbbsetup("update --update-bb-conf='yes'")
+ _check_layer_backups(layers_path, 1)
# check source overrides, local sources provided with symlinks, and custom setup dir name
source_override_content = """