diff --git a/README.md b/README.md
index 72a2c402..0a1f50fe 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ Package build scripts live in the [`pmaports`](https://gitlab.com/postmarketOS/p
* [Linux kernel 3.17 or higher](https://postmarketos.org/oldkernel)
* Python 3.4+
* OpenSSL
+* git
## Usage Examples
Please refer to the [postmarketOS wiki](https://wiki.postmarketos.org) for in-depth coverage of topics such as [porting to a new device](https://wiki.postmarketos.org/wiki/Porting_to_a_new_device) or [installation](https://wiki.postmarketos.org/wiki/Installation_guide). The help output (`pmbootstrap -h`) has detailed usage instructions for every command. Read on for some generic examples of what can be done with `pmbootstrap`.
diff --git a/pmb/aportgen/core.py b/pmb/aportgen/core.py
index d8d60816..ce689f7c 100644
--- a/pmb/aportgen/core.py
+++ b/pmb/aportgen/core.py
@@ -206,9 +206,8 @@ def get_upstream_aport(args, pkgname):
# APKBUILD < binary
if compare == -1:
- raise RuntimeError("You can update your local checkout with:"
- " 'pmbootstrap chroot --add=git --user -- git -C"
- " /mnt/pmbootstrap-git/aports_upstream pull'")
+ raise RuntimeError("You can update your local checkout with: 'git -C"
+ "\"{}\" pull'".format(aports_upstream_path))
# APKBUILD > binary
raise RuntimeError("You can force an update of your binary package"
" APKINDEX files with: 'pmbootstrap update'")
diff --git a/pmb/config/__init__.py b/pmb/config/__init__.py
index b60c386d..619cb093 100644
--- a/pmb/config/__init__.py
+++ b/pmb/config/__init__.py
@@ -45,12 +45,12 @@ pmaports_min_version = "4"
# Version of the work folder (as asked during 'pmbootstrap init'). Increase
# this number, whenever migration is required and provide the migration code,
# see migrate_work_folder()).
-work_version = 3
+work_version = 4
# Programs that pmbootstrap expects to be available from the host system. Keep
# in sync with README.md, and try to keep the list as small as possible. The
# idea is to run almost everything in Alpine chroots.
-required_programs = ["openssl", "ps"]
+required_programs = ["git", "openssl", "ps"]
# Keys saved in the config file (mostly what we ask in 'pmbootstrap init')
config_keys = ["ccache_size", "device", "extra_packages", "hostname", "jobs",
diff --git a/pmb/config/init.py b/pmb/config/init.py
index 68a10955..7a480ef8 100644
--- a/pmb/config/init.py
+++ b/pmb/config/init.py
@@ -78,8 +78,9 @@ def ask_for_work_path(args):
with open(work + "/version", "w") as handle:
handle.write(str(pmb.config.work_version) + "\n")
- # Make sure, that we can write into it
- os.makedirs(work + "/cache_http", 0o700, True)
+ # Create cache_git dir, so it is owned by the host system's user
+ # (otherwise pmb.helpers.mount.bind would create it as root)
+ os.makedirs(work + "/cache_git", 0o700, True)
return (work, exists)
except OSError:
logging.fatal("ERROR: Could not create this folder, or write"
diff --git a/pmb/config/pmaports.py b/pmb/config/pmaports.py
index 49ec4e07..d9259af3 100644
--- a/pmb/config/pmaports.py
+++ b/pmb/config/pmaports.py
@@ -49,7 +49,7 @@ def clone(args):
" recipes (pmaports)...")
# Set up the native chroot and clone pmaports
- pmb.helpers.git.clone(args, "pmaports", False, True)
+ pmb.helpers.git.clone(args, "pmaports", False)
def symlink(args):
diff --git a/pmb/helpers/git.py b/pmb/helpers/git.py
index eccc3322..a71bd8db 100644
--- a/pmb/helpers/git.py
+++ b/pmb/helpers/git.py
@@ -18,7 +18,6 @@ along with pmbootstrap. If not, see .
"""
import logging
import os
-import shutil
import pmb.build
import pmb.chroot.apk
@@ -26,55 +25,37 @@ import pmb.config
import pmb.helpers.run
-def clone(args, name_repo, shallow=True, chown_to_user=False):
+def clone(args, name_repo, shallow=True):
+ """ Clone a git repository to $WORK/cache_git/$name_repo.
+
+ :param name_repo: short alias used for the repository name, from
+ pmb.config.git_repos (e.g. "aports_upstream",
+ "pmaports")
+ :param shallow: only clone the last revision of the repository, instead
+ of the entire repository (faster, saves bandwith) """
# Check for repo name in the config
if name_repo not in pmb.config.git_repos:
raise ValueError("No git repository configured for " + name_repo)
# Skip if already checked out
- if os.path.exists(args.work + "/cache_git/" + name_repo):
+ path = args.work + "/cache_git/" + name_repo
+ if os.path.exists(path):
return
- # Check out to temp folder
- name_temp = name_repo + ".temp"
- if not os.path.exists(args.work + "/cache_git/" + name_temp):
- # Set up chroot and install git
- pmb.chroot.apk.install(args, ["git"])
- logging.info("(native) git clone " + pmb.config.git_repos[name_repo])
+ # Build git command
+ url = pmb.config.git_repos[name_repo]
+ command = ["git", "clone"]
+ if shallow:
+ command += ["--depth=1"]
+ command += [url, path]
- # git options
- options = []
- if shallow:
- options += ["--depth=1"]
-
- # Run the command
- pmb.chroot.user(args, ["git", "clone"] + options +
- [pmb.config.git_repos[name_repo], name_temp],
- working_dir="/home/pmos/git/", check=False,
- output="stdout")
- if not os.path.exists(args.work + "/cache_git/" + name_temp):
- logging.info("NOTE: cloning from git is known to fail when the"
- " host linux kernel is older than 3.17:"
- " ")
- raise RuntimeError("git clone failed!")
-
- # Chown to user's UID and GID
- if chown_to_user:
- uid_gid = "{}:{}".format(os.getuid(), os.getgid())
- pmb.helpers.run.root(args, ["chown", "-R", uid_gid, args.work +
- "/cache_git/" + name_temp])
-
- # Rename the temp folder
- pmb.helpers.run.root(args, ["mv", name_temp, name_repo],
- args.work + "/cache_git")
+ # Create parent dir and clone
+ logging.info("Clone git repository: " + url)
+ os.makedirs(args.work + "/cache_git", exist_ok=True)
+ pmb.helpers.run.user(args, command, output="stdout")
def rev_parse(args, revision="HEAD"):
- if shutil.which("git") is None:
- logging.warning("WARNING: Cannot determine revision of git " +
- "repository at " + args.aports + ". Command 'git' " +
- "not found.")
- return ""
rev = pmb.helpers.run.user(args, ["git", "rev-parse", revision],
args.aports, output_return=True, check=False)
if rev is None:
diff --git a/pmb/helpers/other.py b/pmb/helpers/other.py
index 64c922e3..342f5854 100644
--- a/pmb/helpers/other.py
+++ b/pmb/helpers/other.py
@@ -21,6 +21,7 @@ import os
import re
import pmb.chroot
import pmb.config
+import pmb.config.init
import pmb.helpers.pmaports
import pmb.helpers.run
@@ -154,6 +155,30 @@ def migrate_work_folder(args):
migrate_success(args, 3)
current = 3
+ if current == 3:
+ # Ask for confirmation
+ path = args.work + "/cache_git"
+ logging.info("Changelog:")
+ logging.info("* pmbootstrap clones repositories with host system's")
+ logging.info(" 'git' instead of using it from an Alpine chroot")
+ logging.info("Migration will do the following:")
+ logging.info("* Check if 'git' is installed")
+ logging.info("* Change ownership to your user: " + path)
+ if not pmb.helpers.cli.confirm(args):
+ raise RuntimeError("Aborted.")
+
+ # Require git, set cache_git ownership
+ pmb.config.init.require_programs()
+ if os.path.exists(path):
+ uid_gid = "{}:{}".format(os.getuid(), os.getgid())
+ pmb.helpers.run.root(args, ["chown", "-R", uid_gid, path])
+ else:
+ os.makedirs(path, 0o700, True)
+
+ # Update version file
+ migrate_success(args, 4)
+ current = 4
+
# Can't migrate, user must delete it
if current != required:
raise RuntimeError("Sorry, we can't migrate that automatically. Please"