@@ -39,6 +39,51 @@ macro(use_eh val)
3939 endif ()
4040endmacro (use_eh)
4141
42+ # Reads hash-commit from backported patch
43+ # This function assumes that each of files starts with (for example):
44+ # From 1a400928bf8fc86fa0f062524c25d0985c94ac6f Mon Sep 17 00:00:00 2001
45+ function (get_backport_patch_hash patch_path patch_hash)
46+ file (READ ${patch_path} first_line LIMIT 40 OFFSET 5)
47+ string (STRIP ${first_line} first_line_strip)
48+ set (patch_hash ${first_line_strip} PARENT_SCOPE)
49+ endfunction ()
50+
51+ # Checks if the the patch is present in current local branch
52+ function (is_backport_patch_present patch_path repo_dir patch_in_branch)
53+ get_backport_patch_hash(${patch_path} patch_hash)
54+ message (STATUS "[OPENCL-CLANG] Checking if patch ${patch_hash} is present in repository" )
55+ execute_process (
56+ COMMAND ${GIT_EXECUTABLE} merge-base --is-ancestor ${patch_hash} HEAD
57+ WORKING_DIRECTORY ${repo_dir}
58+ RESULT_VARIABLE patch_not_in_branches
59+ OUTPUT_QUIET
60+ ERROR_QUIET
61+ )
62+ if (patch_not_in_branches)
63+ set (patch_in_branch False PARENT_SCOPE) # The patch is not present in local branch
64+ else ()
65+ set (patch_in_branch True PARENT_SCOPE) # The patch is not present in local branch
66+ endif ()
67+ endfunction ()
68+
69+ # Validates if given SHA1/tag/branch name exists in local repo
70+ function (is_valid_revision repo_dir revision return_val)
71+ message (STATUS "[OPENCL-CLANG] Validating ${revision} in repository" )
72+ # Check if we have under revision existing branch/tag/SHA1 in this repo
73+ execute_process (
74+ COMMAND ${GIT_EXECUTABLE} log -1 ${revision}
75+ WORKING_DIRECTORY ${repo_dir}
76+ RESULT_VARIABLE output_var
77+ ERROR_QUIET
78+ OUTPUT_QUIET
79+ )
80+ if (${output_var} EQUAL 0)
81+ set (${return_val} True PARENT_SCOPE) # this tag/branch/sha1 exists in repo
82+ else ()
83+ set (${return_val} False PARENT_SCOPE) # this tag/branch/sha1 not exists in repo
84+ endif ()
85+ endfunction ()
86+
4287#
4388# Creates `target_branch` starting at the `base_revision` in the `repo_dir`.
4489# Then all patches from the `patches_dir` are committed to the `target_branch`.
@@ -47,31 +92,63 @@ endmacro(use_eh)
4792function (apply_patches repo_dir patches_dir base_revision target_branch)
4893 file (GLOB patches ${patches_dir} /*.patch)
4994 if (NOT patches)
50- message (STATUS "No patches in ${patches_dir} " )
95+ message (STATUS "[OPENCL-CLANG] No patches in ${patches_dir} " )
5196 return ()
5297 endif ()
5398
54- message (STATUS "${repo_dir} : " )
99+ message (STATUS "[OPENCL-CLANG] Patching repository ${repo_dir} " )
55100 # Check if the target branch already exists
56101 execute_process (
57102 COMMAND ${GIT_EXECUTABLE} rev-parse --verify --no -revs -q ${target_branch}
58103 WORKING_DIRECTORY ${repo_dir}
59104 RESULT_VARIABLE patches_needed
105+ ERROR_QUIET
106+ OUTPUT_QUIET
60107 )
61108 if (patches_needed) # The target branch doesn't exist
62109 list (SORT patches)
110+ is_valid_revision(${repo_dir} ${base_revision} exists_base_rev)
111+
112+ if (NOT ${exists_base_rev} )
113+ execute_process ( # take SHA1 from HEAD
114+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
115+ WORKING_DIRECTORY ${repo_dir}
116+ OUTPUT_VARIABLE repo_head
117+ OUTPUT_STRIP_TRAILING_WHITESPACE
118+ ERROR_QUIET
119+ )
120+ message (STATUS "[OPENCL-CLANG] ref ${base_revision} not exists in repository, using current HEAD:${repo_head} " )
121+ set (base_revision ${repo_head} )
122+ endif ()
63123 execute_process ( # Create the target branch
64124 COMMAND ${GIT_EXECUTABLE} checkout -b ${target_branch} ${base_revision}
65125 WORKING_DIRECTORY ${repo_dir}
66- )
67- execute_process ( # Apply the pathces
68- COMMAND ${GIT_EXECUTABLE} am --3way --ignore -whitespace ${patches}
69- WORKING_DIRECTORY ${repo_dir}
70- )
126+ RESULT_VARIABLE ret_check_out
127+ ERROR_STRIP_TRAILING_WHITESPACE
128+ ERROR_VARIABLE checkout_log
129+ OUTPUT_QUIET
130+ )
131+ message (STATUS "[OPENCL-CLANG] ${checkout_log} which starts from ref : ${base_revision} " )
132+ foreach (patch ${patches} )
133+ is_backport_patch_present(${patch} ${repo_dir} patch_in_branch)
134+ if (${patch_in_branch} )
135+ message (STATUS "[OPENCL-CLANG] Patch ${patch} is already in local branch - ignore patching" )
136+ else ()
137+ execute_process ( # Apply the patch
138+ COMMAND ${GIT_EXECUTABLE} am --3way --ignore -whitespace ${patch}
139+ WORKING_DIRECTORY ${repo_dir}
140+ OUTPUT_VARIABLE patching_log
141+ ERROR_QUIET
142+ )
143+ message (STATUS "[OPENCL-CLANG] Not present - ${patching_log} " )
144+ endif ()
145+ endforeach (patch)
71146 else () # The target branch already exists
72147 execute_process ( # Check it out
73148 COMMAND ${GIT_EXECUTABLE} checkout ${target_branch}
74149 WORKING_DIRECTORY ${repo_dir}
150+ ERROR_QUIET
151+ OUTPUT_QUIET
75152 )
76153 endif ()
77154endfunction ()
0 commit comments