At work, we have a workflow where each branch is "named" by date. During the week, at least once, the latest branch gets pushed to production. What we require now is the summary/commit messages of the changes between the latest branch in production vs the new branch via gitpython.
What I have tried to do:
import git
g = git.Git("pathToRepo")
r = git.Repo("pathToRepo")
g.pull() # get latest
b1commits = r.git.log("branch1")
b2commits = r.git.log("branch2")
This give me all of the commit history from both branches but I can't figure out how to compare them to just get the newest commit messages.
Is this possible to do in gitPython? Or is there a better solution?
I figured it out:
import git
g = git.Git(repoPath+repoName)
g.pull()
commitMessages = g.log('%s..%s' % (oldBranch, newBranch), '--pretty=format:%ad %an - %s', '--abbrev-commit')
Reading through the Git documentation I found that I can compare two branches with this syntax B1..B2. I tried the same with gitpython and it worked, the other parameters are there for a custom format.
This solution uses GitPython
import git
def get_commit_from_range(start_commit, end_commit):
repo = git.Repo('path')
commit_range = f"{start_commit}...{end_commit}"
result = repo.iter_commits(commit_range)
for commit in result:
print(commit.message)
Related
We've been using pipenv for dependency management for a while, and using micropipenv's protected functionality to check lock freshness - the idea here being that micropipenv is lightweight, so this is a cheap and cheerful way of ensuring that our dependencies haven't drifted during CI or during a docker build.
Alas, micropipenv has no such feature for poetry (it skips the hash check completely), and I am therefore left to "reverse-engineer" the feature on my own. Ostensibly this should be super easy - I've assembled the code posted later from what I traced through the poetry and poetry-core repos (Locker, Factory, core.Factory, and PyProjectTOML, primarily). This absolutely does not do the trick, and I'm at a loss as to why.
_relevant_keys = ["dependencies", "group", "source", "extras"]
def _get_content_hash(pyproject):
content = pyproject["tool"]["poetry"]
print(content)
relevant_content = {}
for key in _relevant_keys:
relevant_content[key] = content.get(key)
print(json.dumps(relevant_content, sort_keys=True).encode())
content_hash = sha256(
json.dumps(relevant_content, sort_keys=True).encode()
).hexdigest()
print(f"Calculated: {content_hash}")
return content_hash
def is_fresh(lockfile, pyproject):
metadata = lockfile.get("metadata", {})
print(f"From file: {lockfile['metadata']['content-hash']}")
if "content-hash" in metadata:
return _get_content_hash(pyproject) == lockfile["metadata"]["content-hash"]
return False
Would love to figure out what exactly the heck I'm missing here - i'm guessing that the poetry locker _local_config gets changed at some point and I've failed to notice it.
References:
Locker: https://github.com/python-poetry/poetry/blob/a1a5bce96d85bdc0fdc60b8abf644615647f969e/poetry/packages/locker.py#L454
core.Factory: https://github.com/python-poetry/poetry-core/blob/afaa6903f654b695d9411fb548ad10630287c19f/poetry/core/factory.py#L24
Naturally, this ended up being a PEBKAC error. I was using the hash generation function from the master branch but using an earlier version of poetry on the command line. Once I used the function from the correct code version, everything was hunky dory.
I think this functionality actually exists in micropipenv now anyways lol
Edit: So apparantly my install wasn't working. This pointed me to a mailing list Here where I figured out which commands I was missing. I have the answer for the update below. Now that I think about it, it does make sense. I just wish they'd put this somewhere simple on the dev pages.
yb = yum.YumBase()
yb.conf.assumeyes = True
yb.update(name='aws-cli')
yb.buildTransaction()
yb.processTransaction()
I'm trying to perform an update using yumbase when a server first boots with my kickstart script. At the moment I have a rather crude python subprocess to do "yum update" and would like to make this better.
I'm trying to hook into Yumbase, but the documentation is quite scarce. I have had a look at both the source code and documentation on this page: http://yum.baseurl.org/wiki/5MinuteExamples
I've figured out how to list all packages but not the ones that need updating using an SO answer from 2008: Given an rpm package name, query the yum database for updates
I've also figured out it's a very simple 3-line process to install a new package:
yb = yum.YumBase()
yb.conf.assumeyes = True
yb.install(name='aws-cli')
However the following doesn't work to "update" the package:
yb = yum.YumBase()
yb.conf.assumeyes = True
yb.update(name='aws-cli')
So what I need is:
1: A way to list the packages that need updating, much like "yum check-update"
2: Install the packages above using "yum update"
From what I can see in the yum code, it doesn't seem to be written to be used as a library. The code you gave is not the right way to do it, there's much else happening behind the scenes.
Basically, as of yum-3.4.3, the process looks like this:
->yummain.__main__
<trap KeyboardInterrupt>
->yummain.user_main(sys.argv[1:], exit_code=True)
<check YUM_PROF,YUM_PDB envvars, wrap the following into debugger/profiler if set>
->yummain.main(args)
<set up locale, set up logging>
-><create a YumBaseCli (child of YumBase & YumOutput)>
<incl. fill a list field with YumCommand instances of known commands>
->cli.YumBaseCli.getOptionsConfig()
<parse args into the YumBaseCli instance, includes initializing plugins>
<obtain global yum lock>
<check write permissions for current dir>
->cli.YumBaseCli.doCommands()
<select a YumCommand from the list>
->YumCommand.needTs/needTsRemove if needed
->YumCommand.doCommand(self, self.basecmd, self.extcmds)
<handle errors & set error code if any>
'Resolving Dependencies'
->cli.YumBaseCli.buildTransaction()
<check for an unfinished transaction>
<resolve deps using the info written by the YumCommand into the object>
<honor clean_requirements_on_remove, protected_packages,
protected_multilib, perform some checks>
<handle errors & set error code if any>
'Dependencies Resolved'
->cli.YumBaseCli.doTransaction()
<download, transaction check, transaction test, transaction
using the info in the object>
<handle errors & set error code if any>
'Complete!'
<release global yum lock>
sys.exit(error_code)
As you can see, the main working sequence is embedded directly into main so you can only replicate this logic in-process by running it directly:
yummain.main(<sequence of cmdline arguments>)
Which is just the same as running a separate process minus process isolation.
With git status I can get information about count of unpublished commits:
» git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
# (use "git push" to publish your local commits)
#
nothing to commit, working directory clean
I want to get unpublished commits (or count) with GitPython. I docs I found repo.git.status(), but this is not what I want.
The command you are looking for is:
repo.iter_commits('BRANCH#{u}..BRANCH')
or if you want this as a list:
list(repo.iter_commits('BRANCH#{u}..BRANCH'))
The BRANCH#{u} syntax refers to the upstream branch of BRANCH.
Thanks to #Chronial and #Clare-Macrae for your feedback
Using gitPython ==3.1.11, I did it like that:
branch = self.repo.active_branch
unpushed_symbol = '⇡' if list(self.repo.iter_commits(f'{branch}#{{u}}..{branch}')) else constants.NOTHING
unpulled_symbol = '⇣' if list(self.repo.iter_commits(f'{branch}..{branch}#{{u}}')) else constants.NOTHING
Well the title is self explanatory. What will be the python code equivalent to running git reset --hard (on terminal) using GitPython module?
You can use:
repo = git.Repo('c:/SomeRepo')
repo.git.reset('--hard')
Or if you need to reset to a specific branch:
repo.git.reset('--hard','origin/master')
Or in my case, if you want to just hard update a repo to origin/master (warning, this will nuke your current changes):
# blast any current changes
repo.git.reset('--hard')
# ensure master is checked out
repo.heads.master.checkout()
# blast any changes there (only if it wasn't checked out)
repo.git.reset('--hard')
# remove any extra non-tracked files (.pyc, etc)
repo.git.clean('-xdf')
# pull in the changes from from the remote
repo.remotes.origin.pull()
I searched for reset in the documentation and found this:
class git.refs.head.HEAD(repo, path='HEAD')
reset(commit='HEAD', index=True, working_tree=False, paths=None, **kwargs)
Reset our HEAD to the given commit optionally synchronizing the index and working tree. The reference we refer to will be set to commit as well.
You can use:
repo = git.Repo('repo')
# ...
# Remove last commit
repo.head.reset('HEAD~1', index=True, working_tree=True)
I have a django (Python) project that needs to know what version its code is on in Bazaar for deployment purposes. This is a web application, so I don't want to do this because it fires off a new subprocess and that's not going to scale.
import subprocess
subprocess.Popen(["bzr", "revno"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
Is there a way to parse Bazaar repositories to calculate the version number? Bazaar itself is written in Python and contains this code for calculating the revno, which makes me think it isn't exactly trivial.
rh = self.revision_history()
revno = len(rh)
Edit: Final fix
from bzrlib.branch import BzrBranch
branch = BzrBranch.open_containing('.')[0]
revno = len(branch.revision_history())
Edit: Final fix but for real this time
from bzrlib.branch import BzrBranch
branch = BzrBranch.open_containing('.')[0]
revno = branch.last_revision_info()[0]
You can use Bazaar's bzrlib API to get information about any given Bazaar repository.
>>> from bzrlib.branch import BzrBranch
>>> branch = BzrBranch.open('.')
>>> branch.last_revision_info()
More examples are available here.
Do it once and cache the result (in a DB/file, if need be)? I doubt the version is going to change that much.