git 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. #!/usr/bin/env bash
  2. # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
  3. # Copyright (C) 2019 Andrew Robbins <contact@andrewrobbins.info>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. BRANCH_PREFIX="libreboot-"
  18. DOTGIT=".git"
  19. HEAD="HEAD"
  20. ORIGIN_HEAD="origin/HEAD"
  21. WILDDOTPATCH="*.patch"
  22. GIT_NAME="Libreboot"
  23. GIT_EMAIL="libreboot@libreboot.org"
  24. git_check() {
  25. local repository_path=$1
  26. directory_filled_check "$repository_path/$DOTGIT"
  27. }
  28. git_clone() {
  29. local repository_path=$1
  30. local url=$2
  31. git clone "$url" "$repository_path"
  32. }
  33. git_submodule_update() {
  34. local repository_path=$1
  35. (
  36. cd "$repository_path"
  37. git submodule update --init
  38. )
  39. }
  40. git_merge() {
  41. local repository_path=$1
  42. local revision=$2
  43. (
  44. cd "$repository_path"
  45. git merge "$revision"
  46. )
  47. }
  48. git_branch_create() {
  49. local repository_path=$1
  50. local branch=$2
  51. local revision=$3
  52. (
  53. cd "$repository_path"
  54. git checkout -B "$branch"
  55. if [[ -n "$revision" ]]
  56. then
  57. git reset --hard "$revision"
  58. fi
  59. )
  60. }
  61. git_branch_delete() {
  62. local repository_path=$1
  63. local branch=$2
  64. (
  65. cd "$repository_path"
  66. git branch -D "$branch"
  67. )
  68. }
  69. git_branch_checkout() {
  70. local repository_path=$1
  71. local branch=$2
  72. (
  73. cd "$repository_path"
  74. git checkout "$branch" > /dev/null
  75. )
  76. }
  77. git_branch_check() {
  78. local repository_path=$1
  79. local branch=$2
  80. (
  81. cd "$repository_path" >/dev/null 2>&1 || return 1
  82. git rev-parse --verify "$branch" >/dev/null 2>&1
  83. )
  84. }
  85. git_fetch() {
  86. local repository_path=$1
  87. (
  88. cd "$repository_path"
  89. git fetch origin
  90. )
  91. }
  92. git_fetch_check() {
  93. local repository_path=$1
  94. (
  95. cd "$repository_path" >/dev/null 2>&1 || return 1
  96. git fetch --dry-run origin >/dev/null 2>&1
  97. )
  98. }
  99. git_clean() {
  100. local repository_path=$1
  101. (
  102. cd "$repository_path"
  103. git clean -df
  104. )
  105. }
  106. git_remove() {
  107. local repository_path=$1
  108. local path=$2
  109. (
  110. cd "$repository_path"
  111. git rm -rf "$path"
  112. )
  113. }
  114. git_commit() {
  115. local repository_path=$1
  116. local message=$2
  117. (
  118. export GIT_COMMITTER_NAME=$GIT_NAME
  119. export GIT_COMMITTER_EMAIL=$GIT_EMAIL
  120. cd "$repository_path"
  121. git commit --author="$GIT_NAME <$GIT_EMAIL>" -m "$message"
  122. )
  123. }
  124. git_am() {
  125. local repository_path=$1
  126. local branch=$2
  127. local patch=$3
  128. (
  129. export GIT_COMMITTER_NAME=$GIT_NAME
  130. export GIT_COMMITTER_EMAIL=$GIT_EMAIL
  131. cd "$repository_path"
  132. git checkout "$branch" >/dev/null 2>&1
  133. if git_apply_check "$repository_path" "$branch" "$patch"; then
  134. git am "$patch" || git am --abort
  135. fi
  136. )
  137. }
  138. git_apply() {
  139. local repository_path=$1
  140. local branch=$2
  141. local patch=$3
  142. (
  143. cd "$repository_path"
  144. git checkout "$branch" >/dev/null 2>&1
  145. if git_apply_check "$repository_path" "$branch" "$patch"; then
  146. git apply --index "$patch"
  147. fi
  148. )
  149. }
  150. git_apply_check() {
  151. local repository_path=$1
  152. local branch=$2
  153. local patch=$3
  154. (
  155. cd "$repository_path"
  156. git checkout "$branch" >/dev/null 2>&1
  157. git apply --check "$patch"
  158. )
  159. }
  160. git_patch() {
  161. local repository_path=$1
  162. local branch=$2
  163. local patch=$3
  164. case $patch in
  165. *.patch)
  166. git_am "$repository_path" "$branch" "$patch"
  167. ;;
  168. *.diff)
  169. git_apply "$repository_path" "$branch" "$patch" &&
  170. git_commit "$repository_path" "Applied ${patch##*/}"
  171. ;;
  172. *)
  173. ;;
  174. esac
  175. }
  176. git_revision() {
  177. local repository_path=$1
  178. (
  179. cd "$repository_path"
  180. git rev-parse "$HEAD"
  181. )
  182. }
  183. git_describe() {
  184. local repository_path=$1
  185. (
  186. cd "$repository_path"
  187. git describe --tags
  188. )
  189. }
  190. git_files() {
  191. local repository_path="$1"
  192. (
  193. cd "$repository_path"
  194. git ls-files -z | sort -z
  195. )
  196. }
  197. git_project_repository_path() {
  198. local repository=$1
  199. printf '%s\n' "$root/$SOURCES/$repository"
  200. }
  201. git_project_check() {
  202. local repository=$1
  203. local repository_path=$(git_project_repository_path "$repository")
  204. git_check "$repository_path"
  205. }
  206. git_project_patch_recursive() {
  207. local project=$1
  208. local repository=$2
  209. local branch=$3
  210. local path=$4
  211. local repository_path=$(git_project_repository_path "$repository")
  212. local project_path=$(project_path "$project")
  213. local patches_path=$project_path/$PATCHES/$path
  214. if ! [[ -d $project_path/$PATCHES ]]; then
  215. return
  216. fi
  217. if [[ $path != . ]]; then
  218. git_project_patch_recursive "$project" "$repository" "$branch" "$(dirname "$path")"
  219. fi
  220. for patch in "$patches_path"/[!.]*.@(patch|diff); do
  221. git_patch "$repository_path" "$branch" "$patch"
  222. done
  223. }
  224. git_project_clone() {
  225. local repository=$1
  226. shift
  227. local urls=$@
  228. local repository_path=$(git_project_repository_path "$repository")
  229. local directory_path=$(dirname "$repository_path")
  230. local url
  231. mkdir -p "$directory_path"
  232. (
  233. set +e
  234. for url in $urls
  235. do
  236. if git_clone "$repository_path" "$url"
  237. then
  238. return 0
  239. fi
  240. done
  241. return 1
  242. )
  243. }
  244. git_project_prepare() {
  245. local project=$1
  246. shift
  247. local repository=$1
  248. shift
  249. git_project_prepare_revision "$project" "$repository" "$@"
  250. git_project_prepare_patch "$project" "$repository" "$@"
  251. git_project_prepare_blobs "$project" "$repository" "$@"
  252. }
  253. git_project_prepare_blobs() {
  254. local project=$1
  255. shift
  256. local repository=$1
  257. shift
  258. local repository_path=$(git_project_repository_path "$repository")
  259. local blobs_path=$(project_blobs_path "$project" "$@")
  260. local blob
  261. if ! [[ -f "$blobs_path" ]]
  262. then
  263. return
  264. fi
  265. while read blob
  266. do
  267. git_remove "$repository_path" "$blob"
  268. done < "$blobs_path"
  269. git_commit "$repository_path" "Removed blobs"
  270. }
  271. git_project_prepare_patch() {
  272. local project=$1
  273. shift
  274. local repository=$1
  275. shift
  276. local branch=$project
  277. local argument
  278. local path
  279. for argument in "$@"
  280. do
  281. if [[ -z "$path" ]]
  282. then
  283. path="$argument"
  284. else
  285. path="$path/$argument"
  286. fi
  287. branch="$branch-$argument"
  288. done
  289. if [[ -n $branch ]]
  290. then
  291. local prepare_branch=$BRANCH_PREFIX$branch
  292. local prepare_path=$path
  293. git_project_patch_recursive "$project" "$repository" "$prepare_branch" "$prepare_path"
  294. fi
  295. }
  296. git_project_prepare_revision() {
  297. local project=$1
  298. shift
  299. local repository=$1
  300. shift
  301. local repository_path=$(git_project_repository_path "$repository")
  302. local project_path=$(project_path "$project")
  303. local configs_path="$project_path/$CONFIGS"
  304. local branch=$project
  305. local prepare_revision
  306. local argument
  307. local path
  308. for argument in "" "$@"
  309. do
  310. if [[ -n $argument ]]
  311. then
  312. if [[ -z $path ]]
  313. then
  314. path="$argument"
  315. else
  316. path="$path/$argument"
  317. fi
  318. branch="$branch-$argument"
  319. fi
  320. local revision_path="$configs_path/$path/$REVISION"
  321. if [[ -f $revision_path ]]; then
  322. prepare_revision=$(< "$revision_path")
  323. fi
  324. done
  325. if [[ -n $branch ]]
  326. then
  327. local prepare_branch=$BRANCH_PREFIX$branch
  328. git_branch_create "$repository_path" "$prepare_branch" "$prepare_revision"
  329. fi
  330. }
  331. git_project_prepare_check() {
  332. local project=$1
  333. shift
  334. local repository=$1
  335. shift
  336. local repository_path=$(git_project_repository_path "$repository")
  337. local branch=$project
  338. local argument
  339. for argument in "$@"
  340. do
  341. branch="$branch-$argument"
  342. done
  343. if [[ -n $branch ]]
  344. then
  345. local prepare_branch=$BRANCH_PREFIX$branch
  346. git_branch_check "$repository_path" "$prepare_branch"
  347. fi
  348. }
  349. git_project_prepare_clean() {
  350. local project=$1
  351. shift
  352. local repository=$1
  353. shift
  354. local repository_path=$(git_project_repository_path "$repository")
  355. local branch=$project
  356. local argument
  357. for argument in "$@"
  358. do
  359. branch="$branch-$argument"
  360. done
  361. if [[ -n $branch ]]
  362. then
  363. local prepare_branch=$BRANCH_PREFIX$branch
  364. if git_branch_check "$repository_path" "$prepare_branch"
  365. then
  366. git_branch_delete "$repository_path" "$prepare_branch"
  367. fi
  368. fi
  369. }
  370. git_project_checkout() {
  371. local project=$1
  372. shift
  373. local repository=$1
  374. shift
  375. local repository_path=$(git_project_repository_path "$repository")
  376. local branch=$project
  377. local argument
  378. for argument in "$@"
  379. do
  380. branch="$branch-$argument"
  381. done
  382. if [[ -n $branch ]]
  383. then
  384. local checkout_branch=$BRANCH_PREFIX$branch
  385. if git_branch_check "$repository_path" "$checkout_branch"
  386. then
  387. git_branch_checkout "$repository_path" "$checkout_branch"
  388. git_submodule_update "$repository_path"
  389. fi
  390. fi
  391. }
  392. git_project_update() {
  393. local project=$1
  394. shift
  395. local repository=$1
  396. shift
  397. local repository_path=$(git_project_repository_path "$repository")
  398. git_fetch "$repository_path"
  399. git_branch_checkout "$repository_path" "$ORIGIN_HEAD"
  400. git_project_prepare_clean "$project" "$repository" "$@"
  401. git_project_prepare "$project" "$repository" "$@"
  402. }
  403. git_project_update_check() {
  404. local project=$1
  405. shift
  406. local repository=$1
  407. shift
  408. git_project_prepare_check "$project" "$repository" "$@"
  409. git_fetch_check "$repository_path"
  410. }
  411. git_project_release() {
  412. local project=$1
  413. shift
  414. local repository=$1
  415. shift
  416. local repository_path=$(git_project_repository_path "$repository")
  417. local branch=$project
  418. local argument
  419. for argument in "$@"
  420. do
  421. branch="$branch-$argument"
  422. done
  423. if [[ -n $branch ]]
  424. then
  425. local release_branch=$BRANCH_PREFIX$branch
  426. if git_branch_check "$repository_path" "$release_branch"
  427. then
  428. local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$ARCHIVE"
  429. local sources_path="$root/$SOURCES/$repository"
  430. printf '%s\n' "Releasing sources archive for $project (with ${arguments:-no argument}) from "$repository" git"
  431. git_branch_checkout "$repository_path" "$release_branch"
  432. git_submodule_update "$repository_path"
  433. git_clean "$repository_path"
  434. archive_create "$archive_path" "$sources_path" "$release_branch"
  435. file_verification_create "$archive_path"
  436. fi
  437. fi
  438. }
  439. git_project_release_check() {
  440. local project=$1
  441. shift
  442. local repository=$1
  443. shift
  444. local repository_path=$(git_project_repository_path "$repository")
  445. local branch=$project
  446. local argument
  447. for argument in "$@"
  448. do
  449. branch="$branch-$argument"
  450. done
  451. if [[ -n $branch ]]
  452. then
  453. local release_branch=$BRANCH_PREFIX$branch
  454. if git_branch_check "$repository_path" "$release_branch"
  455. then
  456. local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$ARCHIVE"
  457. file_exists_check "$archive_path"
  458. fi
  459. fi
  460. }