1 |
commit: b53213b338fb86e2ee27535fdb9ed91137ad312d |
2 |
Author: Michał Górny <mgorny <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu May 26 12:01:27 2016 +0000 |
4 |
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue May 31 13:39:54 2016 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=b53213b3 |
7 |
|
8 |
git-r3.eclass: Support checking out repo by date, #510704 |
9 |
|
10 |
eclass/git-r3.eclass | 69 +++++++++++++++++++++++++++++++++++++++++++--------- |
11 |
1 file changed, 58 insertions(+), 11 deletions(-) |
12 |
|
13 |
diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass |
14 |
index b7a9333..0ac9d90 100644 |
15 |
--- a/eclass/git-r3.eclass |
16 |
+++ b/eclass/git-r3.eclass |
17 |
@@ -159,6 +159,21 @@ fi |
18 |
# |
19 |
# It can be overriden via env using ${PN}_LIVE_COMMIT variable. |
20 |
|
21 |
+# @ECLASS-VARIABLE: EGIT_COMMIT_DATE |
22 |
+# @DEFAULT_UNSET |
23 |
+# @DESCRIPTION: |
24 |
+# Attempt to check out the repository state for the specified timestamp. |
25 |
+# The date should be in format understood by 'git rev-list'. |
26 |
+# |
27 |
+# The eclass will select the last commit with commit date preceding |
28 |
+# the specified date. When merge commits are found, only first parents |
29 |
+# will be considered in order to avoid switching into external branches |
30 |
+# (assuming that merges are done correctly). In other words, each merge |
31 |
+# will be considered alike a single commit with date corresponding |
32 |
+# to the merge commit date. |
33 |
+# |
34 |
+# It can be overriden via env using ${PN}_LIVE_COMMIT_DATE variable. |
35 |
+ |
36 |
# @ECLASS-VARIABLE: EGIT_CHECKOUT_DIR |
37 |
# @DESCRIPTION: |
38 |
# The directory to check the git sources out to. |
39 |
@@ -254,6 +269,15 @@ _git-r3_env_setup() { |
40 |
[[ ${!livevar} ]] \ |
41 |
&& ewarn "Using ${livevar}, no support will be provided" |
42 |
|
43 |
+ livevar=${esc_pn}_LIVE_COMMIT_DATE |
44 |
+ EGIT_COMMIT_DATE=${!livevar-${EGIT_COMMIT_DATE}} |
45 |
+ [[ ${!livevar} ]] \ |
46 |
+ && ewarn "Using ${livevar}, no support will be provided" |
47 |
+ |
48 |
+ if [[ ${EGIT_COMMIT} && ${EGIT_COMMIT_DATE} ]]; then |
49 |
+ die "EGIT_COMMIT and EGIT_COMMIT_DATE can not be specified simultaneously" |
50 |
+ fi |
51 |
+ |
52 |
# Migration helpers. Remove them when git-2 is removed. |
53 |
|
54 |
if [[ ${EGIT_SOURCEDIR} ]]; then |
55 |
@@ -495,7 +519,7 @@ _git-r3_is_local_repo() { |
56 |
} |
57 |
|
58 |
# @FUNCTION: git-r3_fetch |
59 |
-# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]] |
60 |
+# @USAGE: [<repo-uri> [<remote-ref> [<local-id> [<commit-date>]]]] |
61 |
# @DESCRIPTION: |
62 |
# Fetch new commits to the local clone of repository. |
63 |
# |
64 |
@@ -518,6 +542,9 @@ _git-r3_is_local_repo() { |
65 |
# This default should be fine unless you are fetching multiple trees |
66 |
# from the same repository in the same ebuild. |
67 |
# |
68 |
+# <commit-id> requests attempting to use repository state as of specific |
69 |
+# date. For more details, see EGIT_COMMIT_DATE. |
70 |
+# |
71 |
# The fetch operation will affect the EGIT_STORE only. It will not touch |
72 |
# the working copy, nor export any environment variables. |
73 |
# If the repository contains submodules, they will be fetched |
74 |
@@ -538,6 +565,7 @@ git-r3_fetch() { |
75 |
local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}} |
76 |
local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}} |
77 |
local local_ref=refs/git-r3/${local_id}/__main__ |
78 |
+ local commit_date=${4:-${EGIT_COMMIT_DATE}} |
79 |
|
80 |
[[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset" |
81 |
|
82 |
@@ -621,6 +649,11 @@ git-r3_fetch() { |
83 |
fi |
84 |
fi |
85 |
|
86 |
+ # checkout by date does not make sense in shallow mode |
87 |
+ if [[ ${commit_date} && ${clone_type} == shallow ]]; then |
88 |
+ clone_type=single |
89 |
+ fi |
90 |
+ |
91 |
if [[ ${fetch_l} == HEAD ]]; then |
92 |
fetch_r=refs/git-r3/HEAD |
93 |
else |
94 |
@@ -667,17 +700,31 @@ git-r3_fetch() { |
95 |
fi |
96 |
|
97 |
# now let's see what the user wants from us |
98 |
- local full_remote_ref=$( |
99 |
- git rev-parse --verify --symbolic-full-name "${remote_ref}" |
100 |
- ) |
101 |
- |
102 |
- if [[ ${full_remote_ref} ]]; then |
103 |
- # when we are given a ref, create a symbolic ref |
104 |
- # so that we preserve the actual argument |
105 |
- set -- git symbolic-ref "${local_ref}" "${full_remote_ref}" |
106 |
+ if [[ ${commit_date} ]]; then |
107 |
+ local dated_commit_id=$( |
108 |
+ git rev-list --first-parent --before="${commit_date}" \ |
109 |
+ -n 1 "${remote_ref}" |
110 |
+ ) |
111 |
+ if [[ ${?} -ne 0 ]]; then |
112 |
+ die "Listing ${remote_ref} failed (wrong ref?)." |
113 |
+ elif [[ ! ${dated_commit_id} ]]; then |
114 |
+ die "Unable to find commit for date ${commit_date}." |
115 |
+ else |
116 |
+ set -- git update-ref --no-deref "${local_ref}" "${dated_commit_id}" |
117 |
+ fi |
118 |
else |
119 |
- # otherwise, we were likely given a commit id |
120 |
- set -- git update-ref --no-deref "${local_ref}" "${remote_ref}" |
121 |
+ local full_remote_ref=$( |
122 |
+ git rev-parse --verify --symbolic-full-name "${remote_ref}" |
123 |
+ ) |
124 |
+ |
125 |
+ if [[ ${full_remote_ref} ]]; then |
126 |
+ # when we are given a ref, create a symbolic ref |
127 |
+ # so that we preserve the actual argument |
128 |
+ set -- git symbolic-ref "${local_ref}" "${full_remote_ref}" |
129 |
+ else |
130 |
+ # otherwise, we were likely given a commit id |
131 |
+ set -- git update-ref --no-deref "${local_ref}" "${remote_ref}" |
132 |
+ fi |
133 |
fi |
134 |
|
135 |
echo "${@}" >&2 |