8000 Sparse Checkout support for a submodule · Issue #503 · VisionSystemsInc/vsi_common · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Sparse Checkout support for a submodule #503
Open
@andyneff

Description

@andyneff

Plugin idea for supporting sparse checkout

Here are some Just targets to consider:

In just sync

    if [ "$(git config submodule.external/data.update)" = "none" ]; then
      echo 'Initializing data'
      justify data init
    fi

Init

Note: Docs say sparse-checkout init is deprecated, so probably should be matching that behavior instead.

    data_init) # git sparse-checkout init for external/data
      local git_version=${git_version-$(git_version)}
      local sm_name=external/data
      local sm_path="$(git config -f .gitmodules "submodule.${sm_name}.path")"

      ### 1. First clone --no-checkout ###
      if version_lt "${git_version}" 1.8.4; then
        # Port of git's submodule update's clone.
        local git_dir="$("${GIT}" rev-parse --git-dir)/modules/${sm_path}"

        "${GIT}" submodule init "${sm_path}"
        mkdir -p "$(dirname "${git_dir}")"
        "${GIT}" clone --no-checkout \
          --separate-git-dir "${git_dir}" \
          "$("${GIT}" config "submodule.${sm_name}.url")" \
          "${sm_path}"
      else
        # A close equivalent of clone no checkout
        "${GIT}" -c "submodule.${sm_name}.update="'!true' submodule update --init external/data
      fi

      ### 2. git sparse-checkout init ###
      pushd "${sm_path}" &> /dev/null
        if version_lt "${git_version}" 2.25.0; then
          "${GIT}" config core.sparseCheckout true
        else # 2.25.0
          "${GIT}" sparse-checkout init --cone
        fi
        justify data set prod .gitlab
      popd &> /dev/null

      ### 3. Now, return normal control over to git submodule
      "${GIT}" config "submodule.${sm_name}.update" checkout
      "${GIT}" submodule update "${sm_path}"
      pushd "${sm_path}" &> /dev/null
        # I'm ok with always doing read-tree here, as I am init-ing and this
        # directory should would have not existed before "data init" started

        # This is needed for corner cases even in git 2.25 like when someone deinit's a sparse submodule
        # which results in a no-checkout scenario where every file is stages as deleted, and we need to
        # read-tree, and not prompt the user, so don't call "just data read-tree"
        "${GIT}" read-tree -mu HEAD
      popd &> /dev/null
      ;;

Add

    data_add) # git sparse-checkout add for external/data
      local git_version=${git_version-$(git_version)}
      pushd "${DATA_DIR}" &> /dev/null
        if version_lt "${git_version}" 2.26.0; then
          echo "Approximation of 'git sparse-checkout add', update to git 2.26.0 or newer for more reliable results" >&2
          local add_dir
          local sparse_file="$("${GIT}" rev-parse --git-dir)/info/sparse-checkout"
          for add_dir in ${@+"${@}"}; do
            # The entry should look like /foo/bar/, starting and ending with a /
            if [ "${add_dir:0:1}" != "/" ]; then
              add_dir="/${add_dir}"
            fi
            if [ "${add_dir:${#add_dir}-1:1}" != "/" ]; then
              add_dir="${add_dir}/"
            fi
            # Just blindly add it, no cone check. TODO: Cone?
            echo "${add_dir}" >> "${sparse_file}"
          done
          justify data read-tree
        else
          "${GIT}" sparse-checkout add ${@+"${@}"}
        fi
      popd &> /dev/null
      extra_args=${#}
      ;;

List

    data_list) # git sparse-checkout list for external/data
      local git_version=${git_version-$(git_version)}
      pushd "${DATA_DIR}" &> /dev/null
        if version_lt "${git_version}" 2.25.0; then
          echo "Approximation of 'git sparse-checkout list', update to git 2.25.0 or newer for more reliable results" >&2
          sed -En 's|^/(.*)/|\1|p'  ../../.git/modules/external/data/info/sparse-checkout
        else
          "${GIT}" sparse-checkout list
        fi
      popd &> /dev/null
      ;;

Disable

    data_disable) # git sparse-checkout disable for external/data
      local git_version=${git_version-$(git_version)}
      pushd "$DATA_DIR}" &> /dev/null
        if version_lt "${git_version}" 2.25.0; then
          echo "Approximation of 'git sparse-checkout disable', update to git 2.25.0 or newer for more reliable results" >&2
          "${GIT}" config core.sparseCheckout false
          "${GIT}" read-tree -mu HEAD
        else
          "${GIT}" sparse-checkout disable
        fi
      popd &> /dev/null
      ;;

Set

    data_set) # git sparse-checkout set for external/data
      local git_version=${git_version-$(git_version)}
      pushd "${DATA_DIR}" &> /dev/null
        if version_lt "${git_version}" 2.25.0; then
          echo '/*
!/*/' > "$("${GIT}" rev-parse --git-dir)/info/sparse-checkout"
          justify data add ${@+"${@}"}
        else
          "${GIT}" sparse-checkout set  ${@+"${@}"}
        fi
      popd &> /dev/null
      extra_args=${#}
      ;;

Other

    data_read-tree) # git read-tree -mu HEAD for external/data
      # Several references refer to read-tree being the way to update the workspace
      # https://vmiklos.hu/blog/sparse-checkout-example-in-git-1-7
      # https://web.archive.org/web/20130121010056/https://blog.quilitz.de/2010/03/checkout-sub-directories-in-git-sparse-checkouts/comment-page-1/
      # https://stackoverflow.com/a/2340860/4166604
      # https://stackoverflow.com/a/50818880/4166604

      # This is more destructive of a command then I thought it was.
      # This will remove any STAGED changes, which is not what I think is the point? I just
      # wanted something like "git checkout" that will update the workspace after the sparse-checkout
      # is updated. I originally thought this was less intrusive.

      # This behavior is also what we want on initial clone. A clone --no-checkout looks like all files
      # are staged as deleted. So reverting that is exactly what we need on data init
      pushd "${DATA_DIR}" &> /dev/null
        if [ -z "$(${GIT} status --untracked-files=no --porcelain 2>/dev/null)" ]; then
          "${GIT}" read-tree -mu HEAD
        else
          echo "external/data is in a dirty state. This command will revert the ${RED}staged changes in external/data!${NC}."
          git status --untracked-files=no
          local ans
          ask_question "Are you sure you want to execute 'git read-tree -mu HEAD' on external/data?" ans y
          if [ "${ans}" = "1" ]; then
            "${GIT}" read-tree -mu HEAD
          else
            echo "To complete sparse checkout, run: ${YELLOW}git read-tree -mu HEAD${NC}"
          fi
        fi
      popd &> /dev/null
      ;;

    data_ls-files) # git ls-files for external/data
      pushd "${DATA_DIR}" &> /dev/null
        "${GIT}" ls-files
      popd &> /dev/null
      ;;

    data_ls-dirs) # Print directory tree for external/data
      pushd "${DATA_DIR}" &> /dev/null
        "${GIT}" ls-files -z | xargs -0 dirname | sort -u
      popd &> /dev/null
      ;;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0