0

I am trying to get all merged branches as well as stale branches (not being used for 3 months) I have the command written for linux shell. However, I need to write an alternative command in Gitpyhon. Could anybody help me with this?

self.cmd("git branch --merged master") # <-- Display, merged branches
self.cmd(                              # <-- Display stale branches
    "for branch in `git branch -r | grep -v HEAD`;"
    "do echo -e `git log --before=\"3 months\" --no-merges"
    " -n 1 --format=\"%cr | %an | %ae | \""
    " $branch | head -n 1` \\t$branch; done | sort -M"
)

1 Answer 1

4

Here are tips on how to translate git commands straightforwardly in GitPython.

  1. Always use import git.
  2. Use g = git.Git() to create a git handler.
  3. Use env = {'GIT_DIR': '/path/to/repo/.git', 'GIT_WORK_TREE': '/path/to/repo'} to pass these two variables so that we can call git commands anywhere. If the script involves multiple repositories, remember to switch variable values.
  4. For commands, turn git foo to g.foo(), and git foo-bar to g.foo_bar(). For example, git commit is equal to g.commit() and git cherry-pick is equal to g.cherry_pick().
  5. For options, turn -f to f=True, -f b to f=b, --foo to foo=True, --foo-bar to foo_bar=True and --foo-bar=baz to foo_bar=baz.
  6. Pass with_extended_output=True to commands so that we can catch status, stdout, and stderr.
  7. Use try...catch... to catch command errors. Note that when stderr is not empty, there might be no problem at all. Some commands print results to stderr even if the commands are successful.
  8. If you don't want to do translation, call g.execute() instead.

Now try your commands. Suppose the non-bare repository is /path/to/repo.

import git
import logging

g = git.Git()
env = {'GIT_DIR': '/path/to/repo.git', 'GIT_WORK_TREE': '/path/to/repo'}
# git branch --merged master
try:
    status, stdout, stderr = g.branch(
        merged='master',
        env=env,
        with_extended_output=True)
    print(stdout.split('\n'))
except Exception as e:
    logging.exception(e)
    # more stuff

# git branch -r
stale_branches = []
try:
    status, stdout, stderr = g.branch(
        r=True,
        env=env
        with_extended_output=True)
    stale_branches += [l.strip() for l in stdout.split('\n')]
except Exception as e:
    logging.exception(e)
    # more stuff

for branch in stale_branches:
    if 'HEAD' in branch:
        continue
    # git log
    logs = []
    try:
        status, stdout, stderr = g.log(
            branch,
            before='3 months',
            no_merges=True,
            n=1,
            format='"%cr | %an | %ae | "',
            env=env,
            with_extended_output=True)
        logs += stdout.split('\n')
    except Exception as e:
        logging.exception(e)
        # more stuff

# leave the rest to you
        

For some commands like git worktree add --no-checkout foo HEAD, g.worktree('add', 'foo', 'HEAD', no_checkout=True) always fails because it calls an invalid command git worktree --no-checkout add foo HEAD. In such case, we can use g.execute(). Convert the whole command to a list of parameters, ['git', 'worktree', 'add', '--no-checkout', 'foo', 'HEAD'], and pass it to g.execute().

try:
    status, stdout, stderr = g.execute(
        ['git', 'worktree', 'add', '--no-checkout', 'foo', 'HEAD'],
        env=env,
        with_extended_output=True)
    print(stdout)
except Exception as e:
    logging.exception(e)
    # more stuff
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.