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