summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorPeter Kjellerstedt <peter.kjellerstedt@axis.com>2024-02-19 02:28:32 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-19 16:03:22 +0000
commit4cfd0f7e4e2db19344677999572e5b71ae97dfc4 (patch)
tree07f0d397468ec6eeeddb4a2bba1e6f8a6320f915 /scripts
parentdc2e09417d172ec3da01786e42ebe5e0734ee9ae (diff)
downloadpoky-4cfd0f7e4e2db19344677999572e5b71ae97dfc4.tar.gz
lib/oe/patch: Use git notes to store the filenames for the patches
The old way of keeping track of the filenames for the patches that correspond to the commits was to add a special comment line to the end of the commit message, e.g., "%% original patch: <filename>", using a temporary git hook. This method had some drawbacks, e.g.: * It caused problems if one wanted to push the commits upstream as the comment line had to be manually removed. * The comment line would end up in patches if someone used git format-path rather than devtool finish to generate the patches. * The comment line could interfere with global Git hooks used to validate the format of the Git commit message. * When regenerating patches with `devtool finish --force-patch-refresh`, the process typically resulted in adding empty lines to the end of the commit messages in the updated patches. A better way of keeping track of the patch filenames is to use Git notes. This way the commit messages remain unaffected, but the information is still shown when, e.g., doing `git log`. A special Git notes space, refs/notes/devtool, is used to not intefere with the default Git notes. It is configured to be shown in, e.g., `git log` and to survive rewrites (i.e., `git commit --amend` and `git rebase`). Since there is no longer any need for a temporary Git hook, the code that manipulated the .git/hooks directory has also been removed. To avoid potential problems due to global Git hooks, --no-verify was added to the `git commit` command. To not cause troubles for those who have done `devtool modify` for a recipe with the old solution and then do `devtool finish` with the new solution, the code will fall back to look for the old strings in the commit message if no Git note can be found. While not technically motivated like above, the way to keep track of ignored commits is also changed to use Git notes to avoid having different methods to store similar information. (From OE-Core rev: f5e6183b9557477bef74024a587de0bfcc2b7c0d) Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/devtool/standard.py15
-rw-r--r--scripts/lib/devtool/upgrade.py24
2 files changed, 28 insertions, 11 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 6d7fd17fbd..7972b4f822 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -937,14 +937,13 @@ def modify(args, config, basepath, workspace):
937 seen_patches = [] 937 seen_patches = []
938 for branch in branches: 938 for branch in branches:
939 branch_patches[branch] = [] 939 branch_patches[branch] = []
940 (stdout, _) = bb.process.run('git log devtool-base..%s' % branch, cwd=srctree) 940 (stdout, _) = bb.process.run('git rev-list devtool-base..%s' % branch, cwd=srctree)
941 for line in stdout.splitlines(): 941 for sha1 in stdout.splitlines():
942 line = line.strip() 942 notes = oe.patch.GitApplyTree.getNotes(srctree, sha1.strip())
943 if line.startswith(oe.patch.GitApplyTree.patch_line_prefix): 943 origpatch = notes.get(oe.patch.GitApplyTree.original_patch)
944 origpatch = line[len(oe.patch.GitApplyTree.patch_line_prefix):].split(':', 1)[-1].strip() 944 if origpatch and origpatch not in seen_patches:
945 if not origpatch in seen_patches: 945 seen_patches.append(origpatch)
946 seen_patches.append(origpatch) 946 branch_patches[branch].append(origpatch)
947 branch_patches[branch].append(origpatch)
948 947
949 # Need to grab this here in case the source is within a subdirectory 948 # Need to grab this here in case the source is within a subdirectory
950 srctreebase = srctree 949 srctreebase = srctree
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index ef58523dc8..fa5b8ef3c7 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -261,7 +261,7 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee
261 revs = {} 261 revs = {}
262 for path in paths: 262 for path in paths:
263 (stdout, _) = _run('git rev-parse HEAD', cwd=path) 263 (stdout, _) = _run('git rev-parse HEAD', cwd=path)
264 revs[os.path.relpath(path,srctree)] = stdout.rstrip() 264 revs[os.path.relpath(path, srctree)] = stdout.rstrip()
265 265
266 if no_patch: 266 if no_patch:
267 patches = oe.recipeutils.get_recipe_patches(crd) 267 patches = oe.recipeutils.get_recipe_patches(crd)
@@ -272,17 +272,35 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee
272 _run('git checkout devtool-patched -b %s' % branch, cwd=path) 272 _run('git checkout devtool-patched -b %s' % branch, cwd=path)
273 (stdout, _) = _run('git branch --list devtool-override-*', cwd=path) 273 (stdout, _) = _run('git branch --list devtool-override-*', cwd=path)
274 branches_to_rebase = [branch] + stdout.split() 274 branches_to_rebase = [branch] + stdout.split()
275 target_branch = revs[os.path.relpath(path, srctree)]
276
277 # There is a bug (or feature?) in git rebase where if a commit with
278 # a note is fully rebased away by being part of an old commit, the
279 # note is still attached to the old commit. Avoid this by making
280 # sure all old devtool related commits have a note attached to them
281 # (this assumes git config notes.rewriteMode is set to ignore).
282 (stdout, _) = __run('git rev-list devtool-base..%s' % target_branch)
283 for rev in stdout.splitlines():
284 if not oe.patch.GitApplyTree.getNotes(path, rev):
285 oe.patch.GitApplyTree.addNote(path, rev, "dummy")
286
275 for b in branches_to_rebase: 287 for b in branches_to_rebase:
276 logger.info("Rebasing {} onto {}".format(b, revs[os.path.relpath(path,srctree)])) 288 logger.info("Rebasing {} onto {}".format(b, target_branch))
277 _run('git checkout %s' % b, cwd=path) 289 _run('git checkout %s' % b, cwd=path)
278 try: 290 try:
279 _run('git rebase %s' % revs[os.path.relpath(path, srctree)], cwd=path) 291 _run('git rebase %s' % target_branch, cwd=path)
280 except bb.process.ExecutionError as e: 292 except bb.process.ExecutionError as e:
281 if 'conflict' in e.stdout: 293 if 'conflict' in e.stdout:
282 logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip())) 294 logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip()))
283 _run('git rebase --abort', cwd=path) 295 _run('git rebase --abort', cwd=path)
284 else: 296 else:
285 logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) 297 logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
298
299 # Remove any dummy notes added above.
300 (stdout, _) = __run('git rev-list devtool-base..%s' % target_branch)
301 for rev in stdout.splitlines():
302 oe.patch.GitApplyTree.removeNote(path, rev, "dummy")
303
286 _run('git checkout %s' % branch, cwd=path) 304 _run('git checkout %s' % branch, cwd=path)
287 305
288 if tmpsrctree: 306 if tmpsrctree: