summaryrefslogtreecommitdiff
path: root/morphlib/gitdir.py
Commit message (Collapse)AuthorAgeFilesLines
* Use the modern way of the GPL copyright header: URL instead real addressJavier Jardón2015-03-161-2/+1
| | | | Change-Id: I992dc0c1d40f563ade56a833162d409b02be90a0
* Fix copyright yearsSam Thursfield2015-01-121-1/+1
|
* Merge branch 'sam/cached-repo-cleanup'Sam Thursfield2015-01-121-13/+31
|\ | | | | | | | | Reviewed-By: Adam Coldrick <adam.coldrick@codethink.co.uk> Reviewed-By: Richard Maw <richard.maw@codethink.co.uk>
| * Rework CachedRepo to use the GitDirectory class where possibleSam Thursfield2014-12-031-13/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | This consolidates a bunch of code paths that were previously duplicated. This also changes the API for local cached repos to match the function names GitDirectory uses. Note that the remote repo cache still uses the old names, and should be fixed when time permits. Some unit tests that use the CachedRepo module required a bit of inelegant monkey-patching in order that they continue to work. A better way to do this would be with the 'mock' library (which would need to be added to Baserock 'build' and 'devel' systems before we could use it).
* | Document that GitDirectory.get_config() can raise an exceptionSam Thursfield2014-12-041-3/+7
|/ | | | Also fix wrong indent.
* Check that directory passed to GitDirectory is a git repoSam Thursfield2014-11-171-1/+16
| | | | | | | | | | | | | | Previously, creating a GitDirectory object for something that wasn't a Git repository would succeed, but most operations would raise a cliapp.AppException with the following error message: ERROR: Command failed: git config -z core.bare Now, the constructor will raise a NoGitRepoError if the directory isn't a Git repo, which (unless handled) gives the user the following sort of message: ERROR: Directory /src/ws/definitions is not a Git repository
* Merge branch 'sam/gitdir-fixes-v2'Sam Thursfield2014-11-061-11/+26
|\ | | | | | | | | Reviewed-By: Pedro Alvarez <pedro.alvarez@codethink.co.uk> Reviewed-By: Adam Coldrick <adam.coldrick@codethink.co.uk>
| * Improve documentation of GitDirectory classSam Thursfield2014-11-051-5/+13
| | | | | | | | Clarify that bare repositories are supported, and other fixes.
| * Only search for repository root in GitDirectory constructor if told toSam Thursfield2014-11-051-6/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The GitDirectory() constructor, if passed a 'dirname' that doesn't contain a '.git' subdirectory, can search upwards to find the real root of the repository. This is used by the `add-binary`, `push`, and `pull` commands. This causes very confusing behaviour in the case that 'dirname' points to a directory that should be a Git repository, but isn't, and that directory is a path inside the working tree of another Git repository. Rather than raising an error, in this case the GitDirectory class would perform operations on a different repository to the one the caller expected. This 'search_for_root' behaviour is now opt-in, to avoid confusion.
* | Add GitDirectory.ref_exists() methodSam Thursfield2014-11-051-0/+7
|/ | | | | This allows checking if a ref exists without requiring the caller to use a try:, except: block.
* Use git's remotes to determine unpushed branchesbaserock/richardmaw/less-ls-remoteRichard Maw2014-09-021-0/+16
| | | | | | | | | | | | | | | | | | | | | | Rather than using `git ls-remote` every time to see if there are changes at the remote end, use a local cache. Git already solves this problem with its refs/remotes/$foo branch namespace, so we can just use that instead. In addition, the detection of which upstream branch to use has been improved; it now uses git's notion of which the upstream branch of your current branch is, which saves effort in the implementation, and allows the name of the local branch to differ from that of the remote branch. This now won't notice if the branch you currently have checked out had commits pushed from another source, but for some use-cases this is preferable, as the result equivalent to if you had built before the other push. It may make sense to further extend this logic to check that the local branch is not ahead of the remote branch, instead of requiring them to be equal.
* Prevent git-replace refs affecting git operationsRichard Maw2014-08-211-43/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We assumed that the sha1 of the tree of the commit of the ref we care about was sufficient to cache, but `git replace` means that you need to know the state of other branches too, since anything in refs/replace can completely change what the tree you check-out is. This behaviour can be disabled globally by setting GIT_NO_REPLACE_OBJECTS, so we're going to do that. If we need to integrate a project that uses git-replace to change the contents of their git trees then we could support that by: if any(refs/replace/*): potentially_replacable_objects = [ `git rev-parse HEAD`, `git rev-parse HEAD^{commit}`, `git rev-parse HEAD^{tree}`] potentially_replacable_objects.extend( `git ls-tree -r HEAD | awk '{print $3}'`) # NOTE: doesn't handle submodules, and you'd need to expand this # set whenever you process a replacement for object in refs/replace/*: if basename(object) not in potentially_replacable_objects: continue cache_key['replacements'][basename(object)] = `git rev-parse $object` If we were to support this would need to traverse the tree anyway, doing replacements, so we may as well use libgit to do the checkout anyway, and list which replacements were used. However, since the expected use-case of `git replace` is as a better way to do history grafting, we're unlikely to need it, as it would only have any effect if it replaced the commit we were using with a different one. Rubber-stamped-by: Daniel Silverstone
* Cache configuration values in GitDirectory.Daniel Silverstone2014-08-191-2/+6
| | | | | | | | This reduces the vast number of 'git config -z core.bare' which we used to get a lot of, to one or two per run. It doesn't save much time, but it does make logs less full of confusion. Reviewed-By: Richard maw <richard.maw@codethink.co.uk> +2
* Fix `morph edit` when repo has the same ref as system branchRichard Maw2014-08-121-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | There was a check in it to see whether it needed to do the git branch and git checkout based on whether the name of the branch matched that in the morphology. This had a couple of problems: 1. Now that we aren't always building from HEAD, we need to be able to roll its commit back, so using the existing branch isn't always the best idea. 2. It only checks the "ref" field, not "unpetrify-ref", so even though we clone the right ref in there, it's checking the commit id against the system branch name, so would always try to re-create the branch, and fail when it already exists. So now, we remove the original ref and re-create it with our preferred HEAD. A better solution might be to change the clone logic to not automatically checkout HEAD, and instead require an explicit branch then checkout, but the initial clone logic is shared with build, and I didn't feel like tracking down all the different places that it was used.
* Avoid creating and pushing temporary build branches when they aren't necessary.Richard Maw2014-08-121-0/+14
| | | | | | | | | | | | | | | | | | | | | Sorry about the big lump, I can split it into a nicer set of changes, but they didn't naturally emerge in a nice series. This creates a pushed_build_branch context manager, to eliminate code duplication between build and deploy. Rather than the build branch being constructed knowing whether it needs to push the branch, it infers that from the state of the repositories, and whether a local build would be possible. If there are no uncommitted changes and all local branches are pushed, then it doesn't create temporary branches or push them, and instead uses what it already has. It will currently create and use temporary build branches even for chunks that have no local changes, but it's pretty cheap, and doesn't require re-working the build-ref injection code to check whether there are local changes.
* Don't attempt to load symlinks as morphologiesRichard Maw2014-07-071-0/+10
| | | | | | | | | | | This was noticed because our definitions.git had a dangling symlink, so it failed to construct the temporary build branch. We shouldn't process symlinks as morphologies either, since either we make symlinked morphologies a first-class behaviour, and validate that the link points inside the repository, which is a lot of work for something we don't and probably won't need; or we can just assume that we deal with the morphology this is linked to correctly anyway.
* Tweak some user-facing error messages in 'gitdir'Sam Thursfield2014-04-081-6/+8
| | | | | | | | | | | | | | | The default Python __repr__() is useless for both developers and users, so avoid using it in error messages. The following message: ERROR: Push to remote <morphlib.gitdir.Remote object at 0x905096c>, push url None with refspecs (<morphlib.gitdir.RefSpec object at 0xf72fec2c>,) failed with exit code 128 Becomes: ERROR: Push to remote "origin", push url None failed with exit code 128
* Stop using GitDirectory().list_files() to check for .gitfatAdam Coldrick2014-03-251-1/+1
| | | | | This function causes a UnicodeDecodeError for some repositories when building. Use os.path.isfile() when looking for .gitfat instead.
* Make existing morph commands use git-fatAdam Coldrick2014-03-201-0/+3
| | | | | | When cloning a repository, the files stored using git-fat need to be pulled. This situation occurs in `morph branch`, `morph edit`, and `morph checkout`.
* Add functionality for doing git commands in a directoryAdam Coldrick2014-03-201-2/+32
| | | | | | | | | | | | These commands are: * git fat <init|push|pull> * git pull They are required for the morph add-binary and push/pull plugins. Also make sure that GitDirectory is working in the root directory of the specified git repository, and add some helper functions for handling paths of files in the working tree.
* Fix `morph petrify` in cases where root repo URL has a trailing /Sam Thursfield2014-03-071-1/+2
| | | | | | | | | gitdir._list_work_tree_files() needs to use os.relpath() instead of direct string manipulation to avoid chopping off the first line of every filename in cases where the base gitdir path string includes the trailing /. Unit test updated to catch this.
* deploy: Record deployment information in deployed systemSam Thursfield2014-03-041-1/+6
| | | | | | | | | | | | | | | | | | This commit introduces a new requirement: USERS MUST NOT HAVE SENSITIVE DATA IN THEIR ENVIRONMENT. Otherwise it will be leaked into the system. Note that configuration fields with 'PASSWORD' in their name are stripped before writing the /baserock/deployment.meta file, so the OpenStack OS_PASSWORD field is not leaked. We want this so that we can run hooks at upgrade-time in the future. These hooks might need to know how the system was configured and what releaseuu it was. I'm not quite sure how we will define 'release' yet, but by using `git tag` and `git describe` we are able to textually label a time period in the history of the system's source code. We already have the specific SHA1 of definitions.git stored in the system metadata, so this should give us enough to be able to implement specific hooks that work around any awkward upgrade complications we encounter in the future.
* GitDir: Add remote.push(RefSpec...)Richard Maw2013-11-221-0/+169
| | | | | | | | Remotes have a push method, which takes multiple RefSpecs, runs git push using arguments derived from the set of refspecs, then returns the push's result. If it fails the push, it will return the result in the exception.
* GitDir: Add support for push urls in RemoteRichard Maw2013-11-221-7/+36
|
* GitDir: Split out Remote objectRichard Maw2013-11-221-14/+41
| | | | Operations on remotes are now accessed through this proxy object.
* GitDir: Add methods for ref managementRichard Maw2013-11-221-0/+123
|
* GitDir: Add GitDirectory.commit_tree() methodRichard Maw2013-11-221-0/+20
| | | | | This is used to create commit objects. This is used by build without commit to provide the behind-the-scenes history.
* GitDir: Add GitIndex classRichard Maw2013-11-221-32/+2
| | | | | | | | | | | | | | | This represents the state of the index of a GitDirectory. Methods that use the index are now used via the GitIndex class, rather than using the default index, as previously used when the methods were in GitDirectory. GitIndex may be constructed with an alternative path, which can be used to manipulate a git checkout without altering a developer's view of the repository i.e. The working tree and default index. This is needed for `morph build` and `morph deploy` to handle the build without commit logic.
* GitDir: add store_blob methodRichard Maw2013-11-221-0/+15
| | | | This is needed for making commits without touching the workspace.
* GitDir: Add resolve_ref_to_{commit,tree} methodsRichard Maw2013-11-221-5/+10
| | | | | | | | | | | | Some APIs should take SHA1 object IDs, there needs to be a way to get one from a ref. To handle this, we add APIs for getting either the commit or the tree pointed to by the ref. Commits are provided because we need to create commits from existing commits and update refs from existing values. Trees are provided because we need trees to create commits, and we can read trees into the index to eventually create another tree.
* GitDir: Provide more specific object access than cat-fileRichard Maw2013-11-221-3/+27
| | | | | | | We need to use cat-file for files by SHA1, commits by SHA1 and files by ref and path, so provide access in separate methods, since while it's all the same thing "under the hood", it avoids the user needing to know the command-line syntax.
* GitDir: Allow config values ending in whitespaceRichard Maw2013-11-221-2/+2
|
* GitDir: remove duplicate definition of update_remotesRichard Maw2013-11-221-4/+0
|
* gitdir: Add method for getting uncommitted changesRichard Maw2013-09-171-0/+32
| | | | | | | | | | get_uncommitted_changes() is needed for morph status to tell if git repositories have changes in them. _get_status() is private, since it does not currently have a user, the small amount of code in get_uncommitted_changes() wrapping _get_status() is in the GitDirectory class instead of the branch and merge plugin, since `morph build` will also need to know about uncommitted changes.
* gitdir: add HEAD property to find the current branchRichard Maw2013-09-171-0/+5
| | | | | This is needed for status to tell if a repo is checked out in an unexpected branch.
* gitdir: Add methods to inspect contentsRichard Maw2013-09-051-0/+69
| | | | | | This adds methods to list and read files. The difference between doing this to a commit and the currrent working tree is abstracted over by whether the passed ref is None or omitted.
* Add GitDir.is_currently_checked_outLars Wirzenius2013-08-151-0/+17
| | | | | | | | | | | | | | | This is needed when we load morphologies in "morph edit": it needs to load things differently depending on whether we're loading from the currently checked out ref or not. The new method does not have a unit test, because I'm betting that the test would not find a real bug. The test would just set up a git repo and check whether the right ref is checked out in a couple of ways (it is, and it isn't), and the code is simple enough that it's unlikely to break the test. Creating the test, however, is a fair bit of work. What the test would not catch is when we need the method to do something quite different, but then we'll want a new method anyway.
* Add GitDirectory classLars Wirzenius2013-08-061-0/+131