This one's pretty similar to what we had before though a bit simpler.
For one, we don't have the 'smart fetching' anymore since it was complex
and unsafe.

Implementation-wise 'shallow' mode differs only when starting a new
branch. In that case, '--depth 1' is used to avoid fetching earlier
commits. Further updates are done through plain 'git fetch'.

So, if you enable shallow mode after cloning a repository in 'single'
mode, nothing will actually change :). However, if you switch branch
the repository will become partially 'shallow'.

This also comes with --unshallow support that requires >=git-1.8.2.1.
When 'single' or 'mirror' mode is requested, and the repository is
shallow, it guarantees that at least the requested branch is
unshallowed and fully useful.
---
 eclass/git-r3.eclass | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass
index 8b7d75d..c9c2da5 100644
--- a/eclass/git-r3.eclass
+++ b/eclass/git-r3.eclass
@@ -29,13 +29,13 @@ EXPORT_FUNCTIONS src_unpack
 if [[ ! ${_GIT_R3} ]]; then
 
 if [[ ! ${_INHERITED_BY_GIT_2} ]]; then
-       DEPEND="dev-vcs/git"
+       DEPEND=">=dev-vcs/git-1.8.2.1"
 fi
 
 # @ECLASS-VARIABLE: EGIT_CLONE_TYPE
 # @DESCRIPTION:
 # Type of clone that should be used against the remote repository.
-# This can be either of: 'mirror', 'single'.
+# This can be either of: 'mirror', 'single', 'shallow'.
 #
 # The 'mirror' type clones all remote branches and tags with complete
 # history and all notes. EGIT_COMMIT can specify any commit hash.
@@ -50,6 +50,12 @@ fi
 # in the current branch. No purging of old references is done (if you
 # often switch branches, you may need to remove stale branches
 # yourself). This mode is suitable for general use.
+#
+# The 'shallow' type clones only the newest commit on requested branch
+# or tag. EGIT_COMMIT can only specify tags, and since the history is
+# unavailable calls like 'git describe' will not reference prior tags.
+# No purging of old references is done. This mode is intended mostly for
+# embedded systems with limited disk space.
 : ${EGIT_CLONE_TYPE:=single}
 
 # @ECLASS-VARIABLE: EGIT3_STORE_DIR
@@ -129,7 +135,7 @@ _git-r3_env_setup() {
 
        # check the clone type
        case "${EGIT_CLONE_TYPE}" in
-               mirror|single)
+               mirror|single|shallow)
                        ;;
                *)
                        die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}"
@@ -249,10 +255,6 @@ _git-r3_set_gitdir() {
        fi
 
        addwrite "${EGIT3_STORE_DIR}"
-       if [[ -e ${GIT_DIR}/shallow ]]; then
-               einfo "${GIT_DIR} was a shallow clone, recreating..."
-               rm -r "${GIT_DIR}" || die
-       fi
        if [[ ! -d ${GIT_DIR} ]]; then
                mkdir "${GIT_DIR}" || die
                git init --bare || die
@@ -428,7 +430,7 @@ git-r3_fetch() {
                                # (we keep it in refs/git-r3 since otherwise 
--prune interferes)
                                HEAD:refs/git-r3/HEAD
                        )
-               else # single
+               else # single or shallow
                        local fetch_l fetch_r
 
                        if [[ ${remote_ref} == HEAD ]]; then
@@ -468,6 +470,18 @@ git-r3_fetch() {
                        )
                fi
 
+               if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
+                       # use '--depth 1' when fetching a new branch
+                       if [[ ! $(git rev-parse --quiet --verify "${fetch_r}") 
]]
+                       then
+                               fetch_command+=( --depth 1 )
+                       fi
+               else # non-shallow mode
+                       if [[ -f ${GIT_DIR}/shallow ]]; then
+                               fetch_command+=( --unshallow )
+                       fi
+               fi
+
                set -- "${fetch_command[@]}"
                echo "${@}" >&2
                if "${@}"; then
@@ -477,7 +491,7 @@ git-r3_fetch() {
                                        "$(_git-r3_find_head refs/git-r3/HEAD \
                                                < <(git show-ref --heads || 
die))" \
                                                || die "Unable to update HEAD"
-                       else # single
+                       else # single or shallow
                                if [[ ${fetch_l} == HEAD ]]; then
                                        # find out what branch we fetched as 
HEAD
                                        local head_branch=$(_git-r3_find_head \
@@ -620,6 +634,10 @@ git-r3_checkout() {
 
                # (no need to copy HEAD, we will set it via checkout)
 
+               if [[ -f ${orig_repo}/shallow ]]; then
+                       cp "${orig_repo}"/shallow "${GIT_DIR}"/ || die
+               fi
+
                set -- git checkout --quiet
                if [[ ${remote_ref} ]]; then
                        set -- "${@}" "${remote_ref#refs/heads/}"
-- 
1.8.3.2


Reply via email to