public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-dev] [PATCH] git-r3.eclass: Support checking out repo by date, #510704
@ 2016-05-26 12:08 Michał Górny
  2016-05-27  2:48 ` [gentoo-dev] " Duncan
  2016-05-31 13:41 ` [gentoo-dev] " Michał Górny
  0 siblings, 2 replies; 3+ messages in thread
From: Michał Górny @ 2016-05-26 12:08 UTC (permalink / raw
  To: gentoo-dev; +Cc: Michał Górny

---
 eclass/git-r3.eclass | 69 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 11 deletions(-)

diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass
index b7a93338..0ac9d90 100644
--- a/eclass/git-r3.eclass
+++ b/eclass/git-r3.eclass
@@ -159,6 +159,21 @@ fi
 #
 # It can be overriden via env using ${PN}_LIVE_COMMIT variable.
 
+# @ECLASS-VARIABLE: EGIT_COMMIT_DATE
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Attempt to check out the repository state for the specified timestamp.
+# The date should be in format understood by 'git rev-list'.
+#
+# The eclass will select the last commit with commit date preceding
+# the specified date. When merge commits are found, only first parents
+# will be considered in order to avoid switching into external branches
+# (assuming that merges are done correctly). In other words, each merge
+# will be considered alike a single commit with date corresponding
+# to the merge commit date.
+#
+# It can be overriden via env using ${PN}_LIVE_COMMIT_DATE variable.
+
 # @ECLASS-VARIABLE: EGIT_CHECKOUT_DIR
 # @DESCRIPTION:
 # The directory to check the git sources out to.
@@ -254,6 +269,15 @@ _git-r3_env_setup() {
 	[[ ${!livevar} ]] \
 		&& ewarn "Using ${livevar}, no support will be provided"
 
+	livevar=${esc_pn}_LIVE_COMMIT_DATE
+	EGIT_COMMIT_DATE=${!livevar-${EGIT_COMMIT_DATE}}
+	[[ ${!livevar} ]] \
+		&& ewarn "Using ${livevar}, no support will be provided"
+
+	if [[ ${EGIT_COMMIT} && ${EGIT_COMMIT_DATE} ]]; then
+		die "EGIT_COMMIT and EGIT_COMMIT_DATE can not be specified simultaneously"
+	fi
+
 	# Migration helpers. Remove them when git-2 is removed.
 
 	if [[ ${EGIT_SOURCEDIR} ]]; then
@@ -495,7 +519,7 @@ _git-r3_is_local_repo() {
 }
 
 # @FUNCTION: git-r3_fetch
-# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]]
+# @USAGE: [<repo-uri> [<remote-ref> [<local-id> [<commit-date>]]]]
 # @DESCRIPTION:
 # Fetch new commits to the local clone of repository.
 #
@@ -518,6 +542,9 @@ _git-r3_is_local_repo() {
 # This default should be fine unless you are fetching multiple trees
 # from the same repository in the same ebuild.
 #
+# <commit-id> requests attempting to use repository state as of specific
+# date. For more details, see EGIT_COMMIT_DATE.
+#
 # The fetch operation will affect the EGIT_STORE only. It will not touch
 # the working copy, nor export any environment variables.
 # If the repository contains submodules, they will be fetched
@@ -538,6 +565,7 @@ git-r3_fetch() {
 	local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
 	local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}}
 	local local_ref=refs/git-r3/${local_id}/__main__
+	local commit_date=${4:-${EGIT_COMMIT_DATE}}
 
 	[[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
 
@@ -621,6 +649,11 @@ git-r3_fetch() {
 					fi
 				fi
 
+				# checkout by date does not make sense in shallow mode
+				if [[ ${commit_date} && ${clone_type} == shallow ]]; then
+					clone_type=single
+				fi
+
 				if [[ ${fetch_l} == HEAD ]]; then
 					fetch_r=refs/git-r3/HEAD
 				else
@@ -667,17 +700,31 @@ git-r3_fetch() {
 		fi
 
 		# now let's see what the user wants from us
-		local full_remote_ref=$(
-			git rev-parse --verify --symbolic-full-name "${remote_ref}"
-		)
-
-		if [[ ${full_remote_ref} ]]; then
-			# when we are given a ref, create a symbolic ref
-			# so that we preserve the actual argument
-			set -- git symbolic-ref "${local_ref}" "${full_remote_ref}"
+		if [[ ${commit_date} ]]; then
+			local dated_commit_id=$(
+				git rev-list --first-parent --before="${commit_date}" \
+					-n 1 "${remote_ref}"
+			)
+			if [[ ${?} -ne 0 ]]; then
+				die "Listing ${remote_ref} failed (wrong ref?)."
+			elif [[ ! ${dated_commit_id} ]]; then
+				die "Unable to find commit for date ${commit_date}."
+			else
+				set -- git update-ref --no-deref "${local_ref}" "${dated_commit_id}"
+			fi
 		else
-			# otherwise, we were likely given a commit id
-			set -- git update-ref --no-deref "${local_ref}" "${remote_ref}"
+			local full_remote_ref=$(
+				git rev-parse --verify --symbolic-full-name "${remote_ref}"
+			)
+
+			if [[ ${full_remote_ref} ]]; then
+				# when we are given a ref, create a symbolic ref
+				# so that we preserve the actual argument
+				set -- git symbolic-ref "${local_ref}" "${full_remote_ref}"
+			else
+				# otherwise, we were likely given a commit id
+				set -- git update-ref --no-deref "${local_ref}" "${remote_ref}"
+			fi
 		fi
 
 		echo "${@}" >&2
-- 
2.8.3



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-05-31 13:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-26 12:08 [gentoo-dev] [PATCH] git-r3.eclass: Support checking out repo by date, #510704 Michał Górny
2016-05-27  2:48 ` [gentoo-dev] " Duncan
2016-05-31 13:41 ` [gentoo-dev] " Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox