git 11 KB

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