git 11 KB

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