legit-0.1.1/0000755000076500000240000000000011733500663013254 5ustar kreitzstaff00000000000000legit-0.1.1/extra/0000755000076500000240000000000011733500663014377 5ustar kreitzstaff00000000000000legit-0.1.1/extra/bash-completion/0000755000076500000240000000000011733500663017463 5ustar kreitzstaff00000000000000legit-0.1.1/extra/bash-completion/legit0000644000076500000240000000301611733476175020524 0ustar kreitzstaff00000000000000_legit() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="branches graft publish sprout switch sync unpublish" case "${prev}" in sync) local running=$(for x in `git branch`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; switch) local running=$(for x in `git branch`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; sprout) local running=$(for x in `git branch`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; graft) local running=$(for x in `git branch`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; publish) local running=$(for x in `git branch`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; unpublish) local running=$(for x in `git ls-remote 2>/dev/null | grep refs/heads | awk '{ print $2 }' | sed -e 's/refs\/heads\///g'`; do echo ${x} ; done ) COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) return 0 ;; *) ;; esac COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 } complete -F _legit legitlegit-0.1.1/extra/zsh-completion/0000755000076500000240000000000011733500663017352 5ustar kreitzstaff00000000000000legit-0.1.1/extra/zsh-completion/_legit0000644000076500000240000000737111733476175020562 0ustar kreitzstaff00000000000000#compdef legit # ------------------------------------------------------------------------------ # Description # ----------- # # Completion script for legit (https://github.com/kennethreitz/legit). # # ------------------------------------------------------------------------------ # Authors # ------- # # * Ryan James (https://github.com/autoplectic) # # ------------------------------------------------------------------------------ # -*- mode: zsh; -*- # ------------------------------------------------------------------------------ _legit () { local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '1:command:->command' \ '*::options:->options' case $state in (command) local -a subcommands subcommands=( 'settings: Display and edit the current Legit settings.' 'branches: Get a nice pretty list of available branches.' 'sync: Synchronizes the given branch. Defaults to current branch. Stash, Fetch, Auto-Merge/Rebase, Push, and Unstash. You can only sync published branches.' 'switch: Switches to specified branch. Defaults to current branch. Automatically stashes and unstashes any changes.' 'sprout: Creates a new branch off of the specified branch. Switches to it immediately.' 'graft: Merges specified branch into the second branch, and removes it. You can only graft unpublished branches.' 'publish: Publishes specified branch to the remote.' 'unpublish: Removes specified branch from the remote.' 'harvest: Syncs a branch with a given branch. Defaults to current.' ) _describe -t commands 'legit' subcommands ;; (options) case $line[1] in (settings|branches) ;; (sync|switch|publish|unpublish) _arguments \ ':branch:__git_branch_names' ;; (sprout) _arguments \ '1:branch:__git_branch_names' \ '2:new-branch' ;; (graft) _arguments \ '1:branch:__git_branch_names' \ '2:into-branch:__git_branch_names' ;; (harvest) _arguments \ '1:from-branch:__git_branch_names' \ '2:to-branch:__get_branch_names' ;; esac esac } __git_branch_names () { local expl declare -a branch_names branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/}) __git_command_successful || return _wanted branch-names expl branch-name compadd $* - $branch_names } __git_command_successful () { if (( ${#pipestatus:#0} > 0 )); then _message 'not a git repository' return 1 fi return 0 } legit-0.1.1/legit/0000755000076500000240000000000011733500663014360 5ustar kreitzstaff00000000000000legit-0.1.1/legit/__init__.py0000644000076500000240000000005311733473453016475 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- from core import *legit-0.1.1/legit/bootstrap.py0000644000076500000240000000256311733500204016744 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.bootstrap ~~~~~~~~~~~~~~~ This module boostraps the Legit runtime. """ import ConfigParser import clint.textui.colored from clint import resources from clint.textui import colored from .settings import settings resources.init('kennethreitz', 'legit') try: config_file = resources.user.open('config.ini', 'r') except IOError: resources.user.write('config.ini', '') config_file = resources.user.open('config.ini', 'r') # Load existing configuration. config = ConfigParser.ConfigParser() config.readfp(config_file) # Pouplate if needed. if not config.has_section('legit'): config.add_section('legit') modified = False # Set defaults if they are missing. # Add everything to settings object. for (k, v, _) in settings.config_defaults: if not config.has_option('legit', k): modified = True config.set('legit', k, v) setattr(settings, k, v) else: val = config.get('legit', k) # Map boolean strings. if val.lower() in ('true', '1', 'yep', 'sure'): val = True elif val.lower() in ('false', '0', 'nope', 'nadda', 'nah'): val = False setattr(settings, k, val) if modified: config_file = resources.user.open('config.ini', 'w') config.write(config_file) if settings.disable_colors: clint.textui.colored.DISABLE_COLOR = Truelegit-0.1.1/legit/cli.py0000644000076500000240000003254711733476175015526 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.cli ~~~~~~~~~ This module povides the CLI interface to legit. """ import sys from subprocess import call from time import sleep import clint.resources from clint import args from clint.eng import join as eng_join from clint.textui import colored, puts, columns from .core import __version__ from .settings import settings from .helpers import is_lin, is_osx, is_win from .scm import * def black(s): if settings.allow_black_foreground: return colored.black(s) else: return s.encode('utf-8') # -------- # Dispatch # -------- def main(): """Primary Legit command dispatch.""" if (args.get(0) in cmd_map) or (args.get(0) in short_map): arg = args.get(0) args.remove(arg) if arg in short_map: arg = short_map.get(arg) cmd_map.get(arg).__call__(args) sys.exit() elif args.contains(('-h', '--help')): display_help() sys.exit(1) elif args.contains(('-v', '--version')): display_version() sys.exit(1) else: if settings.git_transparency: # Send everything to git git_args = list(sys.argv) if settings.git_transparency is True: settings.git_transparency = 'git' git_args[0] = settings.git_transparency sys.exit(call(' '.join(git_args), shell=True)) else: display_info() sys.exit(1) # ------- # Helpers # ------- def status_log(func, message, *args, **kwargs): """Executes a callable with a header message.""" print message log = func(*args, **kwargs) if log: out = [] for line in log.split('\n'): if not line.startswith('#'): out.append(line) print black('\n'.join(out)) def switch_to(branch): """Runs the cmd_switch command with given branch arg.""" switch_args = args.copy switch_args._args = [branch] return cmd_switch(switch_args) # -------- # Commands # -------- def cmd_switch(args): """Legit Switch command.""" to_branch = args.get(0) if not to_branch: print 'Please specify a branch to switch to:' display_available_branches() sys.exit() if to_branch not in get_branch_names(): print 'Branch not found.' sys.exit(1) else: if repo.is_dirty(): status_log(stash_it, 'Saving local changes.') status_log(checkout_branch, 'Switching to {0}.'.format( colored.yellow(to_branch)), to_branch) if unstash_index(): status_log(unstash_it, 'Restoring local changes.') def cmd_sync(args): """Stashes unstaged changes, Fetches remote data, Performs smart pull+merge, Pushes local commits up, and Unstashes changes. Defaults to current branch. """ if args.get(0): # Optional branch specifier. if args.get(0) in get_branch_names(): branch = args.get(0) is_external = True original_branch = repo.head.ref.name else: print "{0} doesn't exist. Use a branch that does.".format( colored.yellow(args.get(0))) sys.exit(1) else: # Sync current branch. branch = repo.head.ref.name is_external = False if branch in get_branch_names(local=False): if is_external: switch_to(branch) if repo.is_dirty(): status_log(stash_it, 'Saving local changes.', sync=True) status_log(smart_pull, 'Pulling commits from the server.') status_log(push, 'Pushing commits to the server.', branch) if unstash_index(sync=True): status_log(unstash_it, 'Restoring local changes.', sync=True) if is_external: switch_to(original_branch) else: print '{0} has not been published yet.'.format( colored.yellow(branch)) sys.exit(1) def cmd_sprout(args): """Creates a new branch of given name from given branch. Defaults to current branch. """ off_branch = args.get(0) new_branch = args.get(1) if new_branch is None: new_branch = off_branch off_branch = repo.head.ref.name if not off_branch: print 'Please specify branch to sprout:' display_available_branches() sys.exit() branch_names = get_branch_names() if off_branch not in branch_names: print "{0} doesn't exist. Use a branch that does.".format( colored.yellow(off_branch)) sys.exit(1) if new_branch in branch_names: print "{0} already exists. Use a unique name.".format( colored.yellow(new_branch)) sys.exit(1) if repo.is_dirty(): status_log(stash_it, 'Saving local changes.') status_log(sprout_branch, 'Branching {0} to {1}.'.format( colored.yellow(off_branch), colored.yellow(new_branch)), off_branch, new_branch) def cmd_graft(args): """Merges an unpublished branch into the given branch, then deletes it.""" branch = args.get(0) into_branch = args.get(1) if not branch: print 'Please specify a branch to graft:' display_available_branches() sys.exit() if not into_branch: into_branch = repo.head.ref.name branch_names = get_branch_names(local=True, remote=False) remote_branch_names = get_branch_names(local=False, remote=True) if branch not in branch_names: print "{0} doesn't exist. Use a branch that does.".format( colored.yellow(branch)) sys.exit(1) if branch in remote_branch_names: print "{0} is published. To graft it, unpublish it first.".format( colored.yellow(branch)) sys.exit(1) if into_branch not in branch_names: print "{0} doesn't exist. Use a branch that does.".format( colored.yellow(into_branch)) sys.exit(1) # Go to new branch. switch_to(into_branch) status_log(graft_branch, 'Grafting {0} into {1}.'.format( colored.yellow(branch), colored.yellow(into_branch)), branch) def cmd_publish(args): """Pushes an unpublished branch to a remote repository.""" branch = args.get(0) if not branch: display_available_branches() sys.exit() branch_names = get_branch_names(local=False) if branch in branch_names: print "{0} is already published. Use a branch that isn't.".format( colored.yellow(branch)) sys.exit(1) status_log(publish_branch, 'Publishing {0}.'.format( colored.yellow(branch)), branch) def cmd_unpublish(args): """Removes a published branch from the remote repository.""" branch = args.get(0) if not branch: print 'Please specify a branch to unpublish:' display_available_branches() sys.exit() branch_names = get_branch_names(local=False) if branch not in branch_names: print "{0} isn't published. Use a branch that is.".format( colored.yellow(branch)) sys.exit(1) status_log(unpublish_branch, 'Unpublishing {0}.'.format( colored.yellow(branch)), branch) def cmd_harvest(args): """Syncs a branch with given branch. Defaults to current.""" from_branch = args.get(0) to_branch = args.get(1) if not from_branch: print 'Please specify a branch to harvest commits from:' display_available_branches() sys.exit() if to_branch: original_branch = repo.head.ref.name is_external = True else: is_external = False branch_names = get_branch_names(local=True, remote=False) if from_branch not in branch_names: print "{0} isn't an available branch. Use a branch that is.".format( colored.yellow(from_branch)) sys.exit(1) if is_external: switch_to(to_branch) if repo.is_dirty(): status_log(stash_it, 'Saving local changes.') status_log(smart_merge, 'Grafting commits from {0}.'.format( colored.yellow(from_branch)), from_branch, allow_rebase=False) if is_external: switch_to(original_branch) if unstash_index(): status_log(unstash_it, 'Restoring local changes.') # def cmd_branches(args): """Displays available branches.""" display_available_branches() def cmd_settings(args): """Opens legit settings in editor.""" path = clint.resources.user.open('config.ini').name print 'Legit Settings:\n' for (option, _, description) in settings.config_defaults: print columns([colored.yellow(option), 25], [description, None]) print '\nSee {0} for more details.'.format(settings.config_url) sleep(0.35) if is_osx: editor = os.environ.get('EDITOR') or os.environ.get('VISUAL') or 'open' os.system("{0} '{1}'".format(editor, path)) elif is_lin: editor = os.environ.get('EDITOR') or os.environ.get('VISUAL') or 'pico' os.system("{0} '{1}'".format(editor, path)) elif is_win: os.system("'{0}'".format(path)) else: print "Edit '{0}' to manage Legit settings.\n".format(path) sys.exit() def cmd_install(args): """Installs legit git aliases.""" aliases = { 'branches': '\'!legit branches\'', 'graft': '\'!legit graft "$@"\'', 'harvest': '\'!legit harvest "$@"\'', 'publish': '\'!legit publish "$@"\'', 'unpublish': '\'!legit unpublish "$@"\'', 'sprout': '\'!legit sprout "$@"\'', 'sync': '\'!legit sync "$@"\'', 'switch': '\'!legit switch "$@"\'', } print 'The following git aliases have been installed:\n' for (ak, av) in aliases.items(): os.system('git config --global --replace-all alias.{0} {1}'.format(ak, av)) print columns(['', 1], [colored.yellow('git ' + ak), 14], [av, None]) sys.exit() def cmd_help(args): """Display help for individual commands.""" command = args.get(0) help(command) # ----- # Views # ----- def help(command): if command == None: command = 'help' help_info = dict() help_info['branches'] = 'branches\n\nGet a nice pretty list of ' \ 'branches.' help_info['graft'] = 'graft \n\nMerges ' \ 'specified branch into the second branch,' \ ' and removes it. You can only graft unpublished ' \ 'branches.' help_info['harvest'] = None help_info['help'] = 'help \n\n' \ 'Display help for legit command.' help_info['publish'] = 'publish \n\n' \ 'Publishes specified branch to the remote.' help_info['unpublish'] = 'unpublish ' \ 'Removes specified branch from the remote.' help_info['settings'] = None help_info['sprout'] = 'sprout [] \n\n' \ 'Creates a new branch off of the specified branch.' \ 'Defaults to current branch. Swiches to it immediately.' help_info['switch'] = 'switch \n\n' \ 'Switches to specified branch. Automatically stashes and unstashes any changes.' help_info['sync'] = 'sync []\n\n' \ 'Syncronizes the given branch.' \ 'Defaults to current branch.' \ 'Stash, Fetch, Auto-Merge/Rebase, Push, and Unstash.' help_info['unpublish'] = 'unpublish \n\n' \ 'Removes specified branch from the remote.' print help_info[command] def display_available_branches(): """Displays available branches.""" branches = get_branches() branch_col = len(max([b.name for b in branches], key=len)) + 1 for branch in branches: marker = '*' if (branch.name == repo.head.ref.name) else ' ' color = colored.green if (branch.name == repo.head.ref.name) else colored.yellow pub = '(published)' if branch.is_published else '(unpublished)' print columns( [colored.red(marker), 2], [color(branch.name), branch_col], [black(pub), 14] ) def display_info(): """Displays Legit informatics.""" puts('{0}. {1}\n'.format( colored.red('legit'), black(u'A Kenneth Reitz Projectâ„¢') )) puts('Usage: {0}'.format(colored.blue('legit '))) puts('Commands: {0}.\n'.format( eng_join( [str(colored.green(c)) for c in sorted(cmd_map.keys())] ) )) def display_help(): """Displays Legit help.""" display_info() def display_version(): """Displays Legit version/release.""" puts('{0} v{1}'.format( colored.yellow('legit'), __version__ )) def handle_abort(aborted): print colored.red('Error:'), aborted.message print black(aborted.log) print 'Unfortunately, there was a merge conflict. It has to be merged manually.' sys.exit(1) settings.abort_handler = handle_abort cmd_map = dict( switch=cmd_switch, sync=cmd_sync, sprout=cmd_sprout, graft=cmd_graft, harvest=cmd_harvest, publish=cmd_publish, unpublish=cmd_unpublish, branches=cmd_branches, settings=cmd_settings, help=cmd_help, install=cmd_install ) short_map = dict( sw='switch', sy='sync', sp='sprout', gr='graft', pub='publish', unp='unpublish', br='branches', ha='harvest', hv='harvest', har='harvest', h='help' )legit-0.1.1/legit/core.py0000644000076500000240000000033011733476175015670 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.core ~~~~~~~~~~ This module provides the basic functionality of legit. """ import bootstrap del bootstrap __version__ = '0.1.0' __author__ = 'Kenneth Reitz' __license__ = 'BSD' legit-0.1.1/legit/helpers.py0000644000076500000240000000115211733476175016405 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.helpers ~~~~~~~~~~~~~ Various Python helpers. """ import os import platform _platform = platform.system().lower() is_osx = (_platform == 'darwin') is_win = (_platform == 'windows') is_lin = (_platform == 'linux') def find_path_above(*names): """Attempt to locate given path by searching parent dirs.""" path = '.' while os.path.split(os.path.abspath(path))[1]: for name in names: joined = os.path.join(path, name) if os.path.exists(joined): return os.path.abspath(joined) path = os.path.join('..', path) legit-0.1.1/legit/scm.py0000644000076500000240000001260711733476175015534 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.scm ~~~~~~~~~ This module provides the main interface to Git. """ import os import sys from collections import namedtuple from operator import attrgetter from git import Repo, Git from git.exc import GitCommandError from .helpers import find_path_above from .settings import settings LEGIT_TEMPLATE = 'Legit: stashing before {0}.' git = 'git' Branch = namedtuple('Branch', ['name', 'is_published']) class Aborted(object): def __init__(self): self.message = None self.log = None def abort(message, log=None): a = Aborted() a.message = message a.log = log settings.abort_handler(a) def repo_check(require_remote=False): if repo is None: print 'Not a git repository.' sys.exit(128) # TODO: no remote fail if not repo.remotes and require_remote: print 'No git remotes configured. Please add one.' sys.exit(128) # TODO: You're in a merge state. def stash_it(sync=False): repo_check() msg = 'syncing banch' if sync else 'switching branches' return repo.git.execute([git, 'stash', 'save', LEGIT_TEMPLATE.format(msg)]) def unstash_index(sync=False): """Returns an unstash index if one is available.""" repo_check() stash_list = repo.git.execute([git, 'stash', 'list']) for stash in stash_list.splitlines(): verb = 'syncing' if sync else 'switching' branch = repo.head.ref.name if ( (('Legit' in stash) and ('On {0}:'.format(branch) in stash) and (verb in stash)) or (('GitHub' in stash) and ('On {0}:'.format(branch) in stash) and (verb in stash)) ): return stash[7] def unstash_it(sync=False): """Unstashes changes from current branch for branch sync.""" repo_check() stash_index = unstash_index(sync=sync) if stash_index is not None: return repo.git.execute([git, 'stash', 'pop', 'stash@{{0}}'.format(stash_index)]) def fetch(): repo_check() return repo.git.execute([git, 'fetch', repo.remotes[0].name]) def smart_pull(): 'git log --merges origin/master..master' repo_check() remote = repo.remotes[0].name branch = repo.head.ref.name fetch() return smart_merge('{0}/{1}'.format(remote, branch)) def smart_merge(branch, allow_rebase=True): repo_check() from_branch = repo.head.ref.name merges = repo.git.execute([git, 'log', '--merges', '{0}..{1}'.format(branch, from_branch)]) if allow_rebase: verb = 'merge' if len(merges.split('commit')) else 'rebase' else: verb = 'merge' try: return repo.git.execute([git, verb, branch]) except GitCommandError, why: log = repo.git.execute([git,'merge', '--abort']) abort('Merge failed. Reverting.', log=why) def push(branch=None): repo_check() if branch is None: return repo.git.execute([git, 'push']) else: return repo.git.execute([git, 'push', repo.remotes[0].name, branch]) def checkout_branch(branch): """Checks out given branch.""" repo_check() return repo.git.execute([git, 'checkout', branch]) def sprout_branch(off_branch, branch): """Checks out given branch.""" repo_check() return repo.git.execute([git, 'checkout', off_branch, '-b', branch]) def graft_branch(branch): """Merges branch into current branch, and deletes it.""" repo_check() log = [] try: msg = repo.git.execute([git, 'merge', '--no-ff', branch]) log.append(msg) except GitCommandError, why: log = repo.git.execute([git,'merge', '--abort']) abort('Merge failed. Reverting.', log='{0}\n{1}'.format(why, log)) out = repo.git.execute([git, 'branch', '-D', branch]) log.append(out) return '\n'.join(log) def unpublish_branch(branch): """Unpublishes given branch.""" repo_check() return repo.git.execute([git, 'push', repo.remotes[0].name, ':{0}'.format(branch)]) def publish_branch(branch): """Publishes given branch.""" repo_check() return repo.git.execute([git, 'push', repo.remotes[0].name, branch]) def get_repo(): """Returns the current Repo, based on path.""" bare_path = find_path_above('.git') if bare_path: prelapsarian_path = os.path.split(bare_path)[0] return Repo(prelapsarian_path) else: return None def get_branches(local=True, remote=True): """Returns a list of local and remote branches.""" repo_check() # print local branches = [] if remote: # Remote refs. try: for b in repo.remotes[0].refs: name = '/'.join(b.name.split('/')[1:]) if name not in settings.forbidden_branches: branches.append(Branch(name, True)) except IndexError: pass if local: # Local refs. for b in [h.name for h in repo.heads]: if b not in [br.name for br in branches] or not remote: if b not in settings.forbidden_branches: branches.append(Branch(b, False)) return sorted(branches, key=attrgetter('name')) def get_branch_names(local=True, remote=True): repo_check() branches = get_branches(local=local, remote=remote) return [b.name for b in branches] repo = get_repo() legit-0.1.1/legit/settings.py0000644000076500000240000000343511733476175016611 0ustar kreitzstaff00000000000000# -*- coding: utf-8 -*- """ legit.config ~~~~~~~~~~~~~~~~~~ This module provides the Legit settings feature set. """ class Settings(object): _singleton = {} # attributes with defaults __attrs__ = tuple() def __init__(self, **kwargs): super(Settings, self).__init__() self.__dict__ = self._singleton def __call__(self, *args, **kwargs): # new instance of class to call r = self.__class__() # cache previous settings for __exit__ r.__cache = self.__dict__.copy() map(self.__cache.setdefault, self.__attrs__) # set new settings self.__dict__.update(*args, **kwargs) return r def __enter__(self): pass def __exit__(self, *args): # restore cached copy self.__dict__.update(self.__cache.copy()) del self.__cache def __getattribute__(self, key): if key in object.__getattribute__(self, '__attrs__'): try: return object.__getattribute__(self, key) except AttributeError: return None return object.__getattribute__(self, key) settings = Settings() settings.config_defaults = ( ('check_for_updates', True, 'Are update checks allowed? Defaults to True.'), ('allow_black_foreground', True, 'Is the epic black foreground color allowed? Defaults to True.'), ('git_transparency', False, 'Send unknown commands to Git? Defaults to False.'), ('disable_colors', False, 'Y U NO FUN? Defaults to False.'), ('last_update_check', None, 'Date of the last update check.')) settings.config_url = 'http://git-legit.org/config' settings.update_url = 'https://api.github.com/repos/kennethreitz/legit/tags' settings.forbidden_branches = ['HEAD',]legit-0.1.1/legit.egg-info/0000755000076500000240000000000011733500663016052 5ustar kreitzstaff00000000000000legit-0.1.1/legit.egg-info/dependency_links.txt0000644000076500000240000000000111733500663022120 0ustar kreitzstaff00000000000000 legit-0.1.1/legit.egg-info/entry_points.txt0000644000076500000240000000005211733500663021345 0ustar kreitzstaff00000000000000[console_scripts] legit = legit.cli:main legit-0.1.1/legit.egg-info/PKG-INFO0000644000076500000240000000643111733500663017153 0ustar kreitzstaff00000000000000Metadata-Version: 1.0 Name: legit Version: 0.1.1 Summary: Git for Humans. Home-page: https://github.com/kennethreitz/legit Author: Kenneth Reitz Author-email: me@kennethreitz.com License: BSD Description: .. -*-restructuredtext-*- Legit: Git for Humans ===================== Inspired by GitHub for Mac. The Concept ----------- `GitHub for Mac `_ is not just a Git client. This `comment `_ on Hacker News says it best: They haven't re-created the git CLI tool in a GUI, they've created something different. They've created a tool that makes Git more accessible. Little things like auto-stashing when you switch branches will confuse git veterans, but it will make Git much easier to grok for newcomers because of the assumptions it makes about your Git workflow. Why not bring this innovation back to the command line? The Interface ------------- ``branches`` Get a nice pretty list of available branches. ``sync []`` Syncronizes the given branch. Defaults to current branch. Stash, Fetch, Auto-Merge/Rebase, Push, and Unstash. You can only sync published branches. ``switch `` Switches to specified branch. Defaults to current branch. Automatically stashes and unstashes any changes. ``sprout [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``harvest [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``graft `` Auto-Merge/Rebase of specified branch into the second branch. ``publish `` Publishes specified branch to the remote. ``unpublish `` Removes specified branch from the remote. ``install`` Installs legit git aliases. The Installation ---------------- Installing Legit is easy with pip:: $ pip install legit You'll then have the wonderful ``legit`` command available. Run it within a repository. To install the git aliases, run the following command:: $ legit install Caveats ------- - All remote operations are carried out by the first remote found. - If a ``stash pop`` merge fails, Legit stops. I'd like to add checking for a merge failure, and undo the command with friendly error reporting. - Pip install is cumbersome to people unfamiliar with Python. Package. (Py2App + PyInstaller) Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 legit-0.1.1/legit.egg-info/requires.txt0000644000076500000240000000003511733500663020450 0ustar kreitzstaff00000000000000clint>=0.2.4 gitpython>=0.3.0legit-0.1.1/legit.egg-info/SOURCES.txt0000644000076500000240000000061011733500663017733 0ustar kreitzstaff00000000000000LICENSE MANIFEST.in README.rst reqs.txt setup.py extra/bash-completion/legit extra/zsh-completion/_legit legit/__init__.py legit/bootstrap.py legit/cli.py legit/core.py legit/helpers.py legit/scm.py legit/settings.py legit.egg-info/PKG-INFO legit.egg-info/SOURCES.txt legit.egg-info/dependency_links.txt legit.egg-info/entry_points.txt legit.egg-info/requires.txt legit.egg-info/top_level.txtlegit-0.1.1/legit.egg-info/top_level.txt0000644000076500000240000000000611733500663020600 0ustar kreitzstaff00000000000000legit legit-0.1.1/LICENSE0000644000076500000240000000273311733473453014274 0ustar kreitzstaff00000000000000Copyright (c) 2011, Kenneth Reitz All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.legit-0.1.1/MANIFEST.in0000644000076500000240000000007611733500204015004 0ustar kreitzstaff00000000000000include reqs.txt README.rst LICENSE recursive-include extra * legit-0.1.1/PKG-INFO0000644000076500000240000000643111733500663014355 0ustar kreitzstaff00000000000000Metadata-Version: 1.0 Name: legit Version: 0.1.1 Summary: Git for Humans. Home-page: https://github.com/kennethreitz/legit Author: Kenneth Reitz Author-email: me@kennethreitz.com License: BSD Description: .. -*-restructuredtext-*- Legit: Git for Humans ===================== Inspired by GitHub for Mac. The Concept ----------- `GitHub for Mac `_ is not just a Git client. This `comment `_ on Hacker News says it best: They haven't re-created the git CLI tool in a GUI, they've created something different. They've created a tool that makes Git more accessible. Little things like auto-stashing when you switch branches will confuse git veterans, but it will make Git much easier to grok for newcomers because of the assumptions it makes about your Git workflow. Why not bring this innovation back to the command line? The Interface ------------- ``branches`` Get a nice pretty list of available branches. ``sync []`` Syncronizes the given branch. Defaults to current branch. Stash, Fetch, Auto-Merge/Rebase, Push, and Unstash. You can only sync published branches. ``switch `` Switches to specified branch. Defaults to current branch. Automatically stashes and unstashes any changes. ``sprout [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``harvest [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``graft `` Auto-Merge/Rebase of specified branch into the second branch. ``publish `` Publishes specified branch to the remote. ``unpublish `` Removes specified branch from the remote. ``install`` Installs legit git aliases. The Installation ---------------- Installing Legit is easy with pip:: $ pip install legit You'll then have the wonderful ``legit`` command available. Run it within a repository. To install the git aliases, run the following command:: $ legit install Caveats ------- - All remote operations are carried out by the first remote found. - If a ``stash pop`` merge fails, Legit stops. I'd like to add checking for a merge failure, and undo the command with friendly error reporting. - Pip install is cumbersome to people unfamiliar with Python. Package. (Py2App + PyInstaller) Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 legit-0.1.1/README.rst0000644000076500000240000000425311733500034014737 0ustar kreitzstaff00000000000000.. -*-restructuredtext-*- Legit: Git for Humans ===================== Inspired by GitHub for Mac. The Concept ----------- `GitHub for Mac `_ is not just a Git client. This `comment `_ on Hacker News says it best: They haven't re-created the git CLI tool in a GUI, they've created something different. They've created a tool that makes Git more accessible. Little things like auto-stashing when you switch branches will confuse git veterans, but it will make Git much easier to grok for newcomers because of the assumptions it makes about your Git workflow. Why not bring this innovation back to the command line? The Interface ------------- ``branches`` Get a nice pretty list of available branches. ``sync []`` Syncronizes the given branch. Defaults to current branch. Stash, Fetch, Auto-Merge/Rebase, Push, and Unstash. You can only sync published branches. ``switch `` Switches to specified branch. Defaults to current branch. Automatically stashes and unstashes any changes. ``sprout [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``harvest [] `` Creates a new branch off of the specified branch. Swiches to it immediately. ``graft `` Auto-Merge/Rebase of specified branch into the second branch. ``publish `` Publishes specified branch to the remote. ``unpublish `` Removes specified branch from the remote. ``install`` Installs legit git aliases. The Installation ---------------- Installing Legit is easy with pip:: $ pip install legit You'll then have the wonderful ``legit`` command available. Run it within a repository. To install the git aliases, run the following command:: $ legit install Caveats ------- - All remote operations are carried out by the first remote found. - If a ``stash pop`` merge fails, Legit stops. I'd like to add checking for a merge failure, and undo the command with friendly error reporting. - Pip install is cumbersome to people unfamiliar with Python. Package. (Py2App + PyInstaller) legit-0.1.1/reqs.txt0000644000076500000240000000003611733500204014755 0ustar kreitzstaff00000000000000clint>=0.2.4 gitpython>=0.3.0 legit-0.1.1/setup.cfg0000644000076500000240000000007311733500663015075 0ustar kreitzstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 legit-0.1.1/setup.py0000644000076500000240000000331011733500627014763 0ustar kreitzstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys try: from setuptools import setup except ImportError: from distutils.core import setup APP_NAME = 'legit' APP_SCRIPT = './legit_r' VERSION = '0.1.1' # Grab requirments. with open('reqs.txt') as f: required = f.readlines() settings = dict() # Publish Helper. if sys.argv[-1] == 'publish': os.system('python setup.py sdist upload') sys.exit() # Build Helper. if sys.argv[-1] == 'build': try: import py2exe except ImportError: print 'py2exe is required to continue.' sys.exit(1) sys.argv.append('py2exe') settings.update( console=[{'script': APP_SCRIPT}], zipfile = None, options = { 'py2exe': { 'compressed': 1, 'optimize': 0, 'bundle_files': 1}}) settings.update( name=APP_NAME, version=VERSION, description='Git for Humans.', long_description=open('README.rst').read(), author='Kenneth Reitz', author_email='me@kennethreitz.com', url='https://github.com/kennethreitz/legit', packages= ['legit',], install_requires=required, license='BSD', classifiers=( # 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Natural Language :: English', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', # 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', ), entry_points={ 'console_scripts': [ 'legit = legit.cli:main', ], } ) setup(**settings)